具有角色的经过身份验证的用户的 Spring Security Java 配置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33673300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Security Java configuration for authenticated users with a role
提问by gingerkid
I am trying to configure Spring Security using Java configuration with Spring Boot.
我正在尝试使用带有 Spring Boot 的 Java 配置来配置 Spring Security。
My WebSecurityConfig class has a configure method like this
我的 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);
}
I get the login page fine for unauthenticated users, and the user authenticates. However, when trying to access the url /individual I get a 403 error and this in the log
对于未经身份验证的用户,我的登录页面很好,并且用户进行了身份验证。但是,当尝试访问 url /individual 时,我收到 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: [email protected]; 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
if I replace .hasRole("USER")
with .authenticated()
it works and the user gets the page desired, but no role is being checked.
如果我更换.hasRole("USER")
与.authenticated()
它的工作原理和用户获取所需的页面,但没有一个角色被检查。
I cannot figure out how to specify that the user must be authenticated and have the role USER. I have looked at many examples and tried many combinations but I cannot get it to work as desired. Most of the examples refer to older XML based configuration as well, which I want to avoid.
我无法弄清楚如何指定用户必须经过身份验证并拥有角色 USER。我看过很多例子并尝试了很多组合,但我无法让它按预期工作。大多数示例也参考了旧的基于 XML 的配置,我想避免这种情况。
What do I need to do to specify that certain URL patterns can be accessed with authenticated users with certain roles?
我需要做什么来指定某些 URL 模式可以由具有某些角色的经过身份验证的用户访问?
As requested, the success handler method looks like this
根据要求,成功处理程序方法如下所示
@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("[email protected]"))
{
redirectStrategy.sendRedirect(request, response, "/individual");
return;
}
redirectStrategy.sendRedirect(request, response, "/application");
}
Note that this is early stage WIP, per the comments in the code. I know this works as the log message appears and without the role check in the WebSecurity class the desired page is served.
请注意,根据代码中的注释,这是早期的 WIP。我知道这会在出现日志消息时起作用,并且如果没有 WebSecurity 类中的角色检查,则会提供所需的页面。
EDIT : noticed a typo in the question referring to roleService.getDefaultRole(). This was a mistake and has been corrected.
编辑:注意到问题中提到 roleService.getDefaultRole() 的错字。这是一个错误并已得到纠正。
回答by FrontierPsychiatrist
I think your logged in user [email protected] has the wrong authorities set. In the log you can see the authorities are ['USER'], but since you are working with roles it should be ['ROLE_USER']. Where do you define the authorities for [email protected]?
我认为您登录的用户 [email protected] 设置了错误的权限。在日志中,您可以看到权限是 ['USER'],但由于您正在处理角色,所以它应该是 ['ROLE_USER']。你在哪里定义 [email protected] 的权限?
Otherwise try switching
否则尝试切换
.antMatchers("/individual", "/application", "/upload").hasRole("USER")
to
到
.antMatchers("/individual", "/application", "/upload").hasAuthority("USER")
回答by gingerkid
I have solved my own question, thanks in part to the various suggestions here making me research it differently. Also noted that FrontierPsychiatrist provided the answer as well, but I did not spot the response while I was working on it.
我已经解决了我自己的问题,部分原因是这里的各种建议让我对它进行了不同的研究。还注意到 FrontierPsychiatrist 也提供了答案,但我在处理它时没有发现响应。
The problem is that Spring interchangably refers to ROLES and AUTHORITIES.
问题是 Spring 可以互换地指代 ROLES 和 AUTHORITIES。
Having implemented the UserDetailsService
interface to allow Spring to load user records from the application database, I was creating an instance of org.springframework.security.core.userdetails.User
and setting the granted authorities. It can be seen in the log statements that the User object had that - Granted Authorities: USER
, but then my security config was checking for a role, and failing. The solution, simply, was to check for an authority instead. I have also cleaned up the config to separate the URL patterns to be ignored from security from the authentication & authorisation. Complete code snippet below
实现了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();
}
I really hope this helps others when using Java based configuration with Spring 4 MVC.
我真的希望这可以帮助其他人在 Spring 4 MVC 中使用基于 Java 的配置。
回答by Imrank
Modify your configuration something like this.
像这样修改您的配置。
http.authorizeRequests().antMatchers("/individual","/application", "/upload")
.hasRole("USER").and().authorizeRequests().anyRequest()
.authenticated().and()
.formLogin()
.loginPage("/login")
.successHandler(successHandler);
and if you don't want all the request to be authenticated you can replace anyRequest()
method with antMatchers("/urls-goes-here")
如果您不希望对所有请求进行身份验证,您可以将anyRequest()
方法替换为antMatchers("/urls-goes-here")
回答by Lukehey
Here's a tutorial that does what you're trying to implement:
这是一个教程,可以完成您要实施的操作:
http://www.jcombat.com/spring/custom-authentication-success-handler-with-spring-security
http://www.jcombat.com/spring/custom-authentication-success-handler-with-spring-security
I'm guessing you forgot to set the session attributes in your handler:
我猜你忘了在处理程序中设置会话属性:
HttpSession session = request.getSession();
session.setAttribute("uname", authUser.getUsername());
session.setAttribute("authorities", authentication.getAuthorities());