Spring Security - 除非通过mappableAuthorities指定,否则HttpServletRequest中无法访问角色

时间:2016-10-13 18:12:25

标签: java spring spring-security

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

我们目前在<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文档,但没有发现任何东西。

1 个答案:

答案 0 :(得分:3)

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

  

一个Filter,它使用一个实现servlet API安全方法的请求包装器填充ServletRequest。

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

  

Spring Security-aware HttpServletRequestWrapper,它使用SecurityContext定义的Authentication对象来实现servlet API安全方法:

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

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

  

AuthenticationDetailsS​​ource的实现,它将用户的J2EE角色(通过调用HttpServletRequest.isUserInRole(String)获得)转换为GrantedAuthority并将其存储在身份验证详细信息对象中。

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

  

由可以检索可映射安全属性字符串列表的类实现的接口(例如,Web或EJB应用程序中所有可用J2EE角色的列表)。

您可以编写自己的MappableAttributesRetriever,从数据库中加载可映射的角色。

或者您可以使用WebXmlMappableAttributesRetrievernum::Float::integer_decode()web.xml检索角色:

  

MappableAttributesRetriever实现从web.xml文件中读取已定义的J2EE角色列表,并从getMappableAttributes()返回这些角色。