2015-10-19 109 views
14

我有这样的代码在我的Web安全配置:Spring安全性为所有角色名称添加前缀“ROLE_”?

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .authorizeRequests() 
      .antMatchers("/api/**") 
      .hasRole("ADMIN") 
      .and() 
      .httpBasic().and().csrf().disable(); 

} 

所以我增加了一个用户在我的数据库“ADMIN”的角色,我总是得到403错误,当我tryed洛这个用户,然后我启用日志春天,我发现这条线:

2015-10-18 23:13:24.112 DEBUG 4899 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/user/login; Attributes: [hasRole('ROLE_ADMIN')] 

为什么春季安全正在寻找“ROLE_ADMIN”,而不是“管理”?

+0

[春季安全角色前缀和自定义用户信息服务(可能的重复http://stackoverflow.com/questions/4951832/spring-security-role-prefix-and-custom -user-details-service) – Bruno

回答

8

默认情况下,Spring安全性添加前缀“ROLE_”。

如果你想要这个删除或更改,看看

http://forum.spring.io/forum/spring-projects/security/51066-how-to-change-role-from-interceptor-url

编辑:发现这个问题,以及: Spring Security remove RoleVoter prefix

+0

只是一个问题,如果我在@Secured注解中添加一个角色,Spring是否默认添加ROLE_?如果我添加@Secured(“abc”),Spring会检查ROLE_abc还是abc? –

+0

@SajibAcharya你可以改变默认的'ROLE_'。请参阅http://stackoverflow.com/questions/38134121/how-do-i-remove-the-role-prefix-from-spring-security-with-javaconfig/38970309#38970309 – walsh

9

在Spring 4,有两种方法hasAuthority()hasAnyAuthority()定义在org.springframework.security.access.expression.SecurityExpressionRoot类。这两种方法只检查您的自定义角色名称而不加前缀添加ROLE_。定义如下:

public final boolean hasAuthority(String authority) { 
    return hasAnyAuthority(authority); 
} 
public final boolean hasAnyAuthority(String... authorities) { 
    return hasAnyAuthorityName(null, authorities); 
} 
private boolean hasAnyAuthorityName(String prefix, String... roles) { 
    Set<String> roleSet = getAuthoritySet(); 

    for (String role : roles) { 
     String defaultedRole = getRoleWithDefaultPrefix(prefix, role); 
     if (roleSet.contains(defaultedRole)) { 
      return true; 
     } 
    } 

    return false; 
} 
private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) { 
    if (role == null) { 
     return role; 
    } 
    if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) { 
     return role; 
    } 
    if (role.startsWith(defaultRolePrefix)) { 
     return role; 
    } 
    return defaultRolePrefix + role; 
} 

实例:

<http auto-config="false" use-expressions="true" pattern="/user/**" 
     entry-point-ref="loginUrlAuthenticationEntryPoint"> 
    <!--If we use hasAnyAuthority, we can remove ROLE_ prefix--> 
    <intercept-url pattern="/user/home/yoneticiler" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/> 
    <intercept-url pattern="/user/home/addUser" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/> 
    <intercept-url pattern="/user/home/addUserGroup" access="hasAuthority('FULL_ADMIN')"/> 
    <intercept-url pattern="/user/home/deleteUserGroup" access="hasAuthority('FULL_ADMIN')"/> 
    <intercept-url pattern="/user/home/**" access="hasAnyAuthority('FULL_ADMIN','ADMIN','EDITOR','NORMAL')"/> 
    <access-denied-handler error-page="/403"/> 
    <custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/> 
    <logout logout-url="/user/logout" 
      invalidate-session="true" 
      logout-success-url="/user/index?logout"/> 
    <!-- enable csrf protection --> 
    <csrf/> 
</http> <beans:bean id="loginUrlAuthenticationEntryPoint" 
      class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> 
    <beans:constructor-arg value="/user"/> 
</beans:bean> 
1

作为@olyanren悲伤,可以使用hasAuthority()方法在弹簧4而不是hasRole()。我加入JavaConfig例如:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    .authorizeRequests() 
    .antMatchers("/api/**") 
    .access("hasAuthority('ADMIN')") 
    .and() 
    .httpBasic().and().csrf().disable(); 
} 
相关问题