spring boot基本的http身份验证与多个角色抛出403禁止错误

时间:2015-06-19 19:23:13

标签: spring-security spring-boot http-basic-authentication spring-4 embedded-tomcat-7

我正在尝试配置具有多个角色的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://localhost:8080/app/index.html的浏览器中的HTTP用户名/密码弹出窗口,请使用 appadminname / appadminpwd 表示正常。但是对于相同的网址,如果我输入 appusername / appuserpwd ,则会抛出 HTTP 403禁止访问错误 。这里为什么APPUSER配置的第二个角色是抛出这个错误,我不确定。如果有办法解决这个问题,请告诉我们。

由于

1 个答案:

答案 0 :(得分:0)

我很欣赏这个问题现在有点老了,但这可能对某人有用。

首先,我不确定为什么你对antMatchers()的调用提供null作为第一个参数; antMatchers()需要一个字符串列表来定义此规则所涵盖的URL,因此我不确定在这种情况下预期匹配的是什么。

其次,anyRequest()意味着无论使用何种URL,此规则都将应用于对应用程序发出的任何请求,Spring将按照定义的顺序应用安全规则。您通常首先定义URL及其关联角色,然后默认为必须通过anyRequest()等身份验证(但不一定需要任何特定角色)的任何其他请求的规则.certatedated()

您的第一条规则是,对应用程序发出的任何请求必须由具有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