// 参数object就是FilterSecurityInterceptor过滤时构造的new FilterInvocation(request, response, chain); protected InterceptorStatusToken beforeInvocation(Object object) { Assert.notNull(object, "Object was null"); finalbooleandebug= logger.isDebugEnabled(); // 调用子类实现的getSecureObjectClass方法判断安全对象类型和参数类型是否一致 // 从FilterSecurityInterceptor中我们可以发现它的安全对象类型就是FilterInvocation.class if (!getSecureObjectClass().isAssignableFrom(object.getClass())) { thrownewIllegalArgumentException( "Security invocation attempted for object " + object.getClass().getName() + " but AbstractSecurityInterceptor only configured to support secure objects of type: " + getSecureObjectClass()); } // 从当前的安全对象(这里可以当做是http请求)获取与当前安全对象相关的配置属性 // 例如permitAll,denyAll,anonymous,authenticated,fullyAuthenticated,rememberMe Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource() .getAttributes(object); // 如果当前安全对象没有配置属性就返回null if (attributes == null || attributes.isEmpty()) { // 如果当前是拒绝公共调用的(可以理解为没有配置任何属性的请求不允许直接调用)直接抛出异常 if (rejectPublicInvocations) { thrownewIllegalArgumentException( "Secure object invocation " + object + " was denied as public invocations are not allowed via this interceptor. " + "This indicates a configuration error because the " + "rejectPublicInvocations property is set to 'true'"); }
if (debug) { logger.debug("Public object - authentication not attempted"); } // 发布事件 publishEvent(newPublicInvocationEvent(object));
returnnull; // no further work post-invocation }
if (debug) { logger.debug("Secure object: " + object + "; Attributes: " + attributes); } // 如果当前没有认证信息,在前面的匿名认证过滤器分析中我们知道,无论如何SecurityContext // 中都会填充认证信息的,至少也是匿名认证信息,所以此处会抛出一个 // AuthenticationCredentialsNotFoundException异常 if (SecurityContextHolder.getContext().getAuthentication() == null) { credentialsNotFound(messages.getMessage( "AbstractSecurityInterceptor.authenticationNotFound", "An Authentication object was not found in the SecurityContext"), object, attributes); } // 根据alwaysReauthenticate判断是否需要重新认证,如果需要重新认证则调用AuthenticationManager // 重新认证然后返回认证信息,否则直接返回之前的认证信息,默认是不需要重新认证的 Authenticationauthenticated= authenticateIfRequired();
publicvoidafterPropertiesSet()throws Exception { Assert.notNull( key, "A Key is required and should match that configured for the RunAsImplAuthenticationProvider"); } // 构造新的Authentication public Authentication buildRunAs(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { // new一个空的集合 List<GrantedAuthority> newAuthorities = newArrayList<>(); // 将安全对象上配置的属性拼接角色前缀添加到newAuthorities中 for (ConfigAttribute attribute : attributes) { if (this.supports(attribute)) { GrantedAuthorityextraAuthority=newSimpleGrantedAuthority( getRolePrefix() + attribute.getAttribute()); newAuthorities.add(extraAuthority); } }