spring 启动具有多个角色的基本 http 身份验证抛出 403 禁止错误

spring boot basic http authentication with multiple roles throws 403 forbidden error

我正在尝试配置 spring boot-Embedded Tomcat 具有多个角色的基本 HTTP 身份验证,大多数 url 相似但很少有特定于每个角色.这里的第一个角色是弹出基本的 HTTP 身份验证并且工作正常。使用以下代码,

    @Configuration
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)

public class TestSecurityAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests().antMatchers(null, getAppAdminRolePaths()).authenticated()
                .anyRequest().hasAnyRole("APPADMIN")
                .and()
                .httpBasic();

        http.csrf().disable()
                .authorizeRequests().antMatchers(null, getAppUserRolePaths()).authenticated()
                .anyRequest().hasAnyRole("APPUSER")
                .and()
                .httpBasic();

        http.authorizeRequests().antMatchers(null, new String[]{"/app/appOwnerView.html"}).authenticated()
                .anyRequest().hasAnyRole("APPOWNER")
                .and()
                .httpBasic();
    }

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("appadminname").password("appadminpwd").roles("APPADMIN").and()
        .withUser("appusername").password("appuserpwd").roles("APPUSER").and()
        .withUser("appownername").password("appoownerpwd").roles("APPOWNER");
    }

    private static String[] getAppAdminRolePaths(){
        return new String[]{"/appweb/*",
                "/app/checkService.html",               
                "/app/index.html",                
                "/app/testData.html",    
                "/app/adminView.html", 
                "/app/demo.html"};
    }

    private static String[] getAppUserRolePaths(){
        return new String[]{"/appweb/*",
                "/app/checkService.html",               
                "/app/index.html",                
                "/app/testData.html",    
                "/app/userView.html", 
                "/app/demo.html"};
    }
}

对于浏览器中的 HTTP username/password 弹出 url http://localhost:8080/app/index.htmlappadminname/appadminpwd 它工作正常。但是对于相同的 url 如果我输入 appusername/appuserpwd 它会抛出 HTTP 403 禁止访问错误。我不确定为什么配置的第二个角色 APPUSER 会抛出此错误。如果有解决此问题的方法,请告知。

谢谢

我很感激这个问题现在有点老了,但这可能对某些人仍然有用。

首先,我不确定为什么您对 antMatchers() 的调用提供 null 作为第一个参数; antMatchers() 期望定义 URL 的字符串列表被该规则覆盖,所以我不确定在这种情况下期望匹配什么 null 。

其次,anyRequest() 意味着此规则将应用于对应用程序发出的任何请求,而不管使用的 URL,并且 Spring 将按照安全规则的顺序应用它们定义。您通常会首先定义 URLs 及其关联的角色,然后默认为任何其他必须经过身份验证的请求(但不一定需要任何特定角色)使用类似 anyRequest().authenticated() 的规则

你的第一条规则说 任何 对应用程序的请求必须由具有 APPADMIN 角色的用户发出,当你尝试以 appusername 登录时拒绝你访问,所以允许 APPUSER 的第二条规则甚至没有被处理。

第三,您多次调用 http.authorizeRequests() 而实际上您可能应该将它们链接在一起,例如:

http.csrf().disable().authorizeRequests()
    .antMatchers( getAppAdminRolePaths() ).hasRole("APPADMIN")
    .antMatchers( getAppUserRolePaths() ).hasRole("APPUSER")
    .anyRequest().authenticated();


最后,当您只有一个角色要检查时,您可以使用 hasRole() 而不是 hasAnyRole()。

您也不需要在同一规则中提供 authenticated() 和 hasRole(),因为 hasRole() 意味着用户已经通过身份验证。

您可以在 Spring 文档中找到更多解释和示例:http://docs.spring.io/spring-security/site/docs/4.0.3.RELEASE/reference/htmlsingle/#authorize-requests