可信空间问题具有与匿名用户标识类似的解决方案(在研究时,我已经得出了这个结论。)
简短答案
受信任的空间并不需要授权,但没有 一个UserDetailsService
会被调用,因为只使用的,
AnonymousAuthenticationProvider并且
AnonymousAuthenticationFilter在默认情况下。足以实现基于
AnonymousAuthenticationFilter覆盖的自定义过滤器,
createAuthentication并
AnonymousAuthenticationFilter用自定义一个(
CustomAnonymousAuthenticationFilter)替换默认值():
@组态 公共静态类NoAuthConfigurationAdapter扩展了WebSecurityConfigurerAdapter { @Autowired 私人UserDetailsService userDetailsService; @Autowired 私有IdentifiableAnonymousAuthenticationFilter identifiableAnonymousAuthenticationFilter; @Override 受保护的void configure(HttpSecurity http)抛出异常{ http.anonymous()。authenticationFilter(identifiableAnonymousAuthenticationFilter); http.antMatcher(“ / **”)。authorizeRequests() .anyRequest()。permitAll(); } }完整答案
我发现,如果未授权用户,则永远不会调用 CustomUserDetailsService* 。继续进行的研究集中在负责创建匿名用户信息的
AnonymousAuthenticationFilter 上。因此,最主要的目的是用我的
IdentifiableAnonymousAuthenticationFilter 替换
AnonymousAuthenticationFilter ,其中应重写某些方法: *
@零件公共类IdentifiableAnonymousAuthenticationFilter扩展了AnonymousAuthenticationFilter { 公共静态最终字符串KEY_IDENTIFIABLE_ANONYMOUS_AUTHENTICATION_FILTER =“ Key.IdentifiableAnonymousAuthenticationFilter”; @Autowired 私人CustomUserDetailsService userDetailsService; @Autowired 私有GrantedAuthorityService grantAuthorityService; 私有AuthenticationDetailsSource身份验证DetailsSource = new WebAuthenticationDetailsSource(); public IdentifiableAnonymousAuthenticationFilter(){ 这个(KEY_IDENTIFIABLE_ANONYMOUS_AUTHENTICATION_FILTER); } public IdentifiableAnonymousAuthenticationFilter(String key){ 超级(密钥); } @Override 受保护的身份验证createAuthentication(HttpServletRequest请求){ AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken( KEY_IDENTIFIABLE_ANONYMOUS_AUTHENTICATION_FILTER, userDetailsService.loadCurrentUser(request), grantAuthorityService.getGrantedAuthoritiesForCurrentUser()); auth.setDetails(authenticationDetailsSource.buildDetails(request)); 返回认证; }}将其注入配置
@Configurationpublic class IdentifyAnonymousConfigurationAdapter extends WebSecurityConfigurerAdapter { @Autowired private IdentifiableAnonymousAuthenticationFilter identifiableAnonymousAuthenticationFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.anonymous().authenticationFilter(identifiableAnonymousAuthenticationFilter); // ... some other configurations }}现在看起来好多了,因为 identifiableAnonymousAuthenticationFilter 已注入
AnonymousConfigurer中
。请注意基于的配置
WebSecurityConfigurerAdapter。如果您只有几个,并且其中一个不会设置
customAnonymousAuthenticationFilter, 而是配置为早于 custom .., 您将获得
AnonymousAuthenticationFilter的 默认实例(默认情况下配置
WebSecurityConfigurerAdapter):
受保护的最终HttpSecurity getHttp()引发异常{ // ... http .csrf()。and() .addFilter(新的WebAsyncManagerIntegrationFilter()) .exceptionHandling()。and() .headers()。and() .sessionManagement()。和() .securityContext()。and() .requestCache()。and() .anonymous()。和() // ...如果应用程序已修复,我不会在乎,但是 AnonymousAuthenticationFilter 早于
IdentifiableAnonymousAuthenticationFilter 调用。然后 doFilter 放入
SecurityContextHolder
incorrect身份验证。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { if(SecurityContextHolder.getContext().getAuthentication() == null) { SecurityContextHolder.getContext().setAuthentication(this.createAuthentication((HttpServletRequest)req)); if(this.logger.isDebugEnabled()) { this.logger.debug("Populated SecurityContextHolder with anonymous token: '" + SecurityContextHolder.getContext().getAuthentication() + "'"); } } else if(this.logger.isDebugEnabled()) { this.logger.debug("SecurityContextHolder not populated with anonymous token, as it already contained: '" + SecurityContextHolder.getContext().getAuthentication() + "'"); } chain.doFilter(req, res);}因此,下一次为 IdentifiableAnonymousAuthenticationFilter* 调用 doFilter
时,它不会因为条件而替换(请参见之前的方法)。
*
Authentication``if(SecurityContextHolder.getContext().getAuthentication()== null)
结果,提供配置非常有用,其中
WebSecurityConfigurerAdapter使用魔术批注 @Order 修复配置以管理配置加载顺序。
警告
或者有人会想-
doFilter在 IdentifiableAnonymousAuthenticationFilter中 添加无条件覆盖(这是
hack ):
@Override 公共无效doFilter(ServletRequest请求,ServletResponse资源,FilterChain链) 引发IOException,ServletException { SecurityContextHolder.getContext()。setAuthentication(createAuthentication((HttpServletRequest)req)); 如果(logger.isDebugEnabled()){ logger.debug(“带有匿名令牌的已填充SecurityContextHolder:” + SecurityContextHolder.getContext()。getAuthentication()+“'”); } chain.doFilter(req,res); }如果您需要通过处理授权的/已认证的用户来确保spring安全性,这是不可接受的,但是在某些情况下,这就足够了。
ps
解决方案的某些部分可以改进,但我希望这个想法总体上是明确的。



