我对springboot很新,我在使用基于角色的基本身份验证方面遇到了一些问题。我编写了一个自定义的UserDetailsService,它在没有角色的情况下工作正常。
@Override
public UserDetails loadUserByUsername(String arg0)
throws UsernameNotFoundException {
Developer d = DeveloperFactory.loadDeveloperByQuery(" Email = '" + arg0 + "'", null);
if (d == null) throw new UsernameNotFoundException ("User with email " + arg0 + " doesn't exist in our database");
String username = d.getEmail();
String password = d.getPassword();
boolean enabled = d.getActive ();
boolean accountNonExpired = enabled;
boolean credentialsNonExpired = enabled;
boolean accountNonLocked = enabled;
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for(Role role : d.roles.toArray()) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
UserDetails u = new User (username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
return u;
}
Once I add a role with the @Secured annotation to my controller methods like
@Secured({"USER"})
@RequestMapping(value = "/admin", method = RequestMethod.GET)
public Developer[] getByQuery (@RequestParam(value="email", required=false) String email) {
if (email == null) {
Developer[] admins = DeveloperFactory.listDeveloperByQuery(" IsAdmin = TRUE", null);
return admins;
} else {
Developer admin = DeveloperFactory.loadDeveloperByQuery("Email = '" + email + "'", null);
if (admin == null) throw new AdminNotFound ();
return new Developer[]{admin};
}
}
我开始得到禁止的错误。我确认用户拥有数据库中请求的角色,但仍然无法正常工作。我的SecurityConfigurer看起来像这样。
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailsServiceImpl());
}
@Override
public UserDetailsService userDetailsServiceBean() {
return new UserDetailsServiceImpl();
}
}
和我的应用程序类一样。
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class Application extends SpringBootServletInitializer {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
有人可以告诉我为什么我的用户角色没有应用于/ admin GET端点吗?
这是我的日志。
2014-06-06 03:16:04.453 DEBUG 9364 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2014-06-06 03:16:04.454 DEBUG 9364 --- [nio-8080-exec-1] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2014-06-06 03:16:04.454 DEBUG 9364 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2014-06-06 03:23:04.886 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 1 of 9 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2014-06-06 03:23:04.886 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 2 of 9 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2014-06-06 03:23:04.886 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 3 of 9 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2014-06-06 03:23:04.887 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@68fe414e
2014-06-06 03:23:04.887 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 4 of 9 in additional filter chain; firing Filter: 'LogoutFilter'
2014-06-06 03:23:04.887 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/admin'; against '/logout'
2014-06-06 03:23:04.887 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 5 of 9 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2014-06-06 03:23:04.887 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 6 of 9 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2014-06-06 03:23:04.888 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 7 of 9 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2014-06-06 03:23:04.888 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2014-06-06 03:23:04.889 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 8 of 9 in additional filter chain; firing Filter: 'SessionManagementFilter'
2014-06-06 03:23:04.889 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin at position 9 of 9 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2014-06-06 03:23:04.889 DEBUG 9364 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /admin reached end of additional filter chain; proceeding with original chain
2014-06-06 03:23:04.894 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.a.i.a.MethodSecurityInterceptor : Secure object: ReflectiveMethodInvocation: public com.withinet.cloud.domain.Developer[] com.withinet.cloud.service.AdminController.getByQuery(java.lang.String); target is of class [com.withinet.cloud.service.AdminController]; Attributes: [ROLE_WEB]
2014-06-06 03:23:04.894 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.a.i.a.MethodSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2014-06-06 03:23:04.894 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.access.vote.RoleVoter@7bcf60f2, returned: -1
2014-06-06 03:23:04.894 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.access.vote.AuthenticatedVoter@6be5ef5e, returned: 0
2014-06-06 03:23:04.896 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at com.withinet.cloud.service.AdminController$$EnhancerBySpringCGLIB$$7633a4cc.getByQuery(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
2014-06-06 03:23:04.897 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2014-06-06 03:23:04.897 DEBUG 9364 --- [nio-8080-exec-3] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2014-06-06 03:23:04.897 DEBUG 9364 --- [nio-8080-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
答案 0 :(得分:3)
您通常需要@Secured
中的“ROLE_”前缀(如果您想使用角色选民),即@Secured("ROLE_USER")
。