具有角色

时间:2015-11-12 14:05:10

标签: java spring spring-mvc spring-security

我正在尝试使用Spring Boot使用Java配置来配置Spring Security。

我的WebSecurityConfig类有一个像这样的配置方法

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/", "/login", "/css/**", "/js/**", "/img/**", "/bootstrap/**" ).permitAll()
            .antMatchers("/individual", "/application", "/upload").hasRole("USER")
        .and()
            .formLogin()
                .loginPage("/login")
                .successHandler(successHandler);

}

我为未经身份验证的用户提供了良好的登录页面,并且用户进行了身份验证。但是,当尝试访问url /个人时,我收到403错误,这在日志中

2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/'
2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/login'
2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/css/**'
2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/js/**'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/img/**'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/bootstrap/**'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/individual'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /individual; Attributes: [hasRole('ROLE_USER')]
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4c2eda81: Principal: org.springframework.security.core.userdetails.User@4c0ab982: Username: foo@bar.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 6E0BF830C070912EAC0050D1285D5CF9; Granted Authorities: USER
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6f192fd7, returned: -1
2015-11-12 13:59:46.386 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is not anonymous); delegating to AccessDeniedHandler

如果我将.hasRole("USER")替换为.authenticated()它可以正常工作并且用户获得所需的页面,但不会检查任何角色。

我无法弄清楚如何指定必须对用户进行身份验证并具有USER角色。我看了很多例子并尝试了很多组合,但是我无法按照需要使用它。大多数示例也引用了较旧的基于XML的配置,我想避免这种配置。

我需要做些什么来指定可以使用具有特定角色的经过身份验证的用户访问某些网址格式?

根据要求,成功处理程序方法如下所示

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth)
        throws IOException, ServletException {

    // Here we want to check whether the user has already started the process and redirect to the appropriate stage

    log.info("User {} has been authenticated", auth.getName());

    if(auth.getName().equals("foo@bar.com"))
    {
        redirectStrategy.sendRedirect(request, response, "/individual");
        return;
    }


    redirectStrategy.sendRedirect(request, response, "/application");

}

请注意,根据代码中的注释,这是早期的WIP。我知道这有效,因为日志消息出现,并且在WebSecurity类中没有角色检查,就会提供所需的页面。

编辑:在注意到roleService.getDefaultRole()的问题中注意到一个拼写错误。这是一个错误,并已得到纠正。

4 个答案:

答案 0 :(得分:8)

我认为您登录的用户foo@bar.com设置了错误的权限。在日志中,您可以看到权限是[' USER'],但由于您正在使用角色,因此应该是[' ROLE_USER']。你在哪里定义foo@bar.com的权限?

否则尝试切换

.antMatchers("/individual", "/application", "/upload").hasRole("USER")

.antMatchers("/individual", "/application", "/upload").hasAuthority("USER")

答案 1 :(得分:1)

我已经解决了我自己的问题,部分归功于这里的各种建议让我以不同的方式进行研究。还注意到FrontierPsychiatrist也提供了答案,但在我工作时我没有发现响应。

问题是春天可以互换地提到了角色和权威。

实现UserDetailsService接口以允许Spring从应用程序数据库加载用户记录后,我创建了org.springframework.security.core.userdetails.User的实例并设置了授权权限。在日志语句中可以看到User对象具有 - Granted Authorities: USER,但是我的安全配置正在检查角色,并且失败。简单来说,解决方案是检查权限。我还清理了配置,将要忽略的URL模式从身份验证和安全性中分离出来。授权。

下面的完整代码段
@Override
public void configure(WebSecurity web) throws Exception {
    web
        .ignoring()
            .antMatchers( "/css/**", "/js/**", "/img/**", "/bootstrap/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .authorizeRequests()
            .antMatchers("/individual","/application", "/upload").hasAuthority("USER")
            .and()
        .formLogin()
            .loginPage("/login")
            .successHandler(successHandler)
            .permitAll()
            .and()
        .logout()
            .deleteCookies("remove")
            .logoutSuccessUrl("/login?logout")
            .permitAll();   
}

我真的希望在Spring 4 MVC中使用基于Java的配置时,这有助于其他人。

答案 2 :(得分:0)

修改您的配置。

http.authorizeRequests().antMatchers("/individual","/application", "/upload")
                .hasRole("USER").and().authorizeRequests().anyRequest()
                .authenticated().and()
        .formLogin()
            .loginPage("/login")
            .successHandler(successHandler);

如果您不希望对所有请求进行身份验证,则可以将anyRequest()方法替换为antMatchers("/urls-goes-here")

答案 3 :(得分:-1)

这是一个教程,可以帮助您实现以下目标:

http://www.jcombat.com/spring/custom-authentication-success-handler-with-spring-security

我猜你忘了在你的处理程序中设置会话属性:

    HttpSession session = request.getSession();
    session.setAttribute("uname", authUser.getUsername());  
    session.setAttribute("authorities", authentication.getAuthorities());