And*_*niy 2 java spring spring-mvc spring-security
这是关于第Spring4版(MVC +安全性).我已实现UserDetailsServiceImpl,其中内部loadUserByUsername方法用户被授予其权限.说它很简单:
public UserDetails loadUserByUsername(String username) {
...
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ADMIN"));
return new org.springframework.security.core.userdetails.User(username, password, enabled, true, true, true, authorities);
...
}
Run Code Online (Sandbox Code Playgroud)
我有安全控制器,我在其中注释带有@Secured注释的方法:
@Secured("ADMIN")
@RequestMapping(value = "/users", method = RequestMethod.GET)
public String users(Model model ...) { ... }
Run Code Online (Sandbox Code Playgroud)
正如您在内部所见,loadUserByUsername我明确地ADMIN向用户授予角色.但是当我尝试访问时,/users我得到了Access is denied异常:
2016-04-19 10:25:16,899 DEBUG(http-nio-8080-exec-9)[org.springframework.security.web.access.ExceptionTranslationFilter] - 访问被拒绝(用户不是匿名的); 委托给AccessDeniedHandler org.springframework.security.access.AccessDeniedException:在org.springframework.security.access.vote.AffirmativeBased的org.springframework.security.access.vote.AbstractAccessDecisionManager.checkAllowIfAllAbstainDecisions(AbstractAccessDecisionManager.java:70)中拒绝访问.在org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)在org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java决定(AffirmativeBased.java:88): 64)在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)...
(没有@Secured注释一切正常).
那么,我在这里错过了什么?
cas*_*lin 10
我也遇到过这个问题。Spring Security 4 自动为任何角色添加前缀ROLE_。有关更多详细信息,请参阅Spring Security 3.x 到 4.x 迁移指南。
ROLE_前缀正如迁移指南中所建议的,以下内容BeanPostProcessor可用于禁用自动ROLE_前缀:
public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor,
PriorityOrdered {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// Remove this if you are not using JSR-250
if (bean instanceof Jsr250MethodSecurityMetadataSource) {
((Jsr250MethodSecurityMetadataSource) bean).setDefaultRolePrefix(null);
}
if (bean instanceof DefaultMethodSecurityExpressionHandler) {
((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
}
if (bean instanceof DefaultWebSecurityExpressionHandler) {
((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
}
if (bean instanceof SecurityContextHolderAwareRequestFilter) {
((SecurityContextHolderAwareRequestFilter)bean).setRolePrefix("");
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
@Override
public int getOrder() {
return PriorityOrdered.HIGHEST_PRECEDENCE;
}
}
Run Code Online (Sandbox Code Playgroud)
然后将其定义为一个 bean:
@Bean
public static DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
return new DefaultRolesPrefixPostProcessor();
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用@PreAuthorize注释检查权限:
@PreAuthorize("hasAuthority('ADMIN')")
Run Code Online (Sandbox Code Playgroud)
确保prePostEnabled已启用:
@EnableGlobalMethodSecurity(prePostEnabled = true)
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,问题在于角色名称.由于defaultRolePrefix设置为ROLE_(请参阅org.springframework.security.access.vote.RoleVoter类),所有角色的名称都应以ROLE_prefix 开头.换句话说,当我改变了
authorities.add(new SimpleGrantedAuthority("ADMIN"));
至
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
并@Secured("ADMIN")以@Secured("ROLE_ADMIN")-一切都变得很好.
| 归档时间: |
|
| 查看次数: |
9205 次 |
| 最近记录: |