java - Spring Security - 角色在 HttpServletRequest 中不可访问,除非通过 mappableAuthorities 指定

标签 java spring spring-security

我有一个在 Tomcat 应用程序服务器上运行并针对第三方 IdP 进行身份验证的 Spring Boot Web 应用程序。

我们目前在我们的许多应用程序中使用 <security-role> 进行基于角色的身份验证和 <security-constraint>web.xml , 它工作正常。

现在,尝试使用 Spring Security,我添加了以下配置类:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        String[] publicPaths = /*get public paths from properties*/
        String[] authorizedPaths = /*get authorized paths from properties*/
        String[] authorizedRoles = /*get authorized roles from properties*/

        http.csrf().disable()
                .jee()
                .mappableAuthorities(authorizedRoles)
                .and()
                .authorizeRequests()
                .antMatchers(publicPaths).permitAll()
                .antMatchers(authorizedPaths).hasAnyRole(authorizedRoles)
                .and()
                .logout().disable()
        ;
    }

}

authorizedRoles上面的配置中是有权访问此应用程序的角色。但是,应用程序中还有其他手动检查,只需调用 HttpServletRequest.isUserInRole()确定用户是否具有特定角色。在使用 Spring Security 之前,该调用将返回 true如果该用户在原始请求中具有该角色。添加 Spring Boot 后,该调用仅返回 true如果角色是传递给 .mappableAuthorities() 的角色之一在上面的例子中。通过 HttpServletRequest.isUserInRole() 检查的角色存储在数据库中并且可以经常更新,因此将它们传递给 .mappableAuthorities()当应用程序加载不可行时。

所以,为了切入我的问题,似乎 Spring Security 正在修改原始的 HttpServletRequest并删除所有未包含在 authorizedRoles 中的角色传递给 .mappableAuthorities() .

有没有办法避免这种行为,或者可能将某种通配符传递给 .mappableAuthorities() ,这样您就不必知道应用程序启动时的所有角色,就可以通过调用 HttpServletRequest.isUserInRole() 来访问它们。 ?我一直在查看 Spring Security 文档几个小时,但没有找到任何东西。

最佳答案

您只能看到映射的角色,因为 SecurityContextHolderAwareRequestFilter包装 HttpServletRequest:

A Filter which populates the ServletRequest with a request wrapper which implements the servlet API security methods.

它使用 SecurityContextHolderAwareRequestWrapper实现 servlet API 安全方法:

A Spring Security-aware HttpServletRequestWrapper, which uses the SecurityContext-defined Authentication object to implement the servlet API security methods:

  • getUserPrincipal()
  • isUserInRole(String)
  • HttpServletRequestWrapper.getRemoteUser().

要自定义角色映射,请参阅 J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource :

Implementation of AuthenticationDetailsSource which converts the user's J2EE roles (as obtained by calling HttpServletRequest.isUserInRole(String)) into GrantedAuthoritys and stores these in the authentication details object.

它使用 MappableAttributesRetriever获取可映射角色:

Interface to be implemented by classes that can retrieve a list of mappable security attribute strings (for example the list of all available J2EE roles in a web or EJB application).

你可以自己写MappableAttributesRetriever它从您的数据库加载可映射角色。

或者您可以使用 WebXmlMappableAttributesRetriever ,它从 web.xml 中检索角色:

This MappableAttributesRetriever implementation reads the list of defined J2EE roles from a web.xml file and returns these from getMappableAttributes().

关于java - Spring Security - 角色在 HttpServletRequest 中不可访问,除非通过 mappableAuthorities 指定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40028122/

相关文章:

java - 如何将纽约时区转换为亚洲时区

java - 从 bash 脚本中将 Spring Boot 作为前台进程启动

spring-security - 使spring security在登录页面的查询字符串中添加return to url

java - 引用另一个类中的方法

java - Opa:它如何识别服务器端或客户端脚本

java - XPath 使用空节点

java - Tomcat 和 JDBC 驱动程序(可能存在内存泄漏)。应用启动失败

java - 添加 JPA 后 Spring Boot 关闭

grails - Grails resources.groovy bean

spring-boot - 如何保护 websocket 应用程序 [Spring boot + STOMP]