Spring Security:公开页面如何识别已通过Keycloak认证的用户
问题根因
你当前的Spring Security配置仅为/secure/**路径声明了访问控制规则,未显式配置的路径不会触发Spring Security过滤器链的身份解析逻辑:Keycloak的相关过滤器只有在命中访问控制规则时才会解析当前会话中已存在的认证信息,因此直接访问首页时不会读取已登录的用户信息,Principal为null。访问安全页时触发了身份解析,认证信息被存入SecurityContext和会话中,因此返回首页时可以正常读取。
解决方案
调整authorizeRequests部分的规则顺序,先声明安全路径的认证要求,再配置所有路径允许匿名访问即可。permitAll规则不会强制要求用户登录,但会触发完整的身份上下文解析逻辑,已登录用户的信息会被正常填充到Principal中:
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // 安全页仍要求必须认证 .antMatchers("/secure/**").authenticated() // 其余所有路径允许匿名访问,同时自动解析已存在的登录状态 .anyRequest().permitAll() .and() // 后续原有配置保持不变即可 .csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher()) .and() .sessionManagement() .sessionAuthenticationStrategy(sessionAuthenticationStrategy()) .and() .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class) .addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class) .addFilterBefore(keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class) .addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class) .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint()) .and() .logout() .addLogoutHandler(keycloakLogoutHandler()) .logoutUrl("/sso/logout").permitAll() .logoutSuccessUrl("/"); }
调整配置后,无论用户先访问首页还是安全页,只要已完成Keycloak认证,首页都可以正常读取到Principal信息。
内容的提问来源于stack exchange,提问作者baronKarza
相关产品推荐
相关产品推荐

