Java Spring security 为所有角色名称添加了前缀“ROLE_”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33205236/
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 added prefix "ROLE_" to all roles name?
提问by Gustavo Rozolin
I have this code in my Web Security Config:
我的网络安全配置中有此代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**")
.hasRole("ADMIN")
.and()
.httpBasic().and().csrf().disable();
}
So I added an user with "ADMIN" role in my database and I always get 403 error when I tryed loggin with this user, then I enabled log for spring and I found this line:
所以我在我的数据库中添加了一个具有“ADMIN”角色的用户,当我尝试用这个用户登录时总是出现 403 错误,然后我为 spring 启用了日志,我发现了这一行:
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')]
Why Spring Security is looking for "ROLE_ADMIN" instead "ADMIN"?
为什么 Spring Security 正在寻找“ROLE_ADMIN”而不是“ADMIN”?
采纳答案by jmcg
Spring security adds the prefix "ROLE_" by default.
Spring security默认添加前缀“ ROLE_”。
If you want this removed or changed, take a look at
如果您想删除或更改此内容,请查看
How to change role from interceptor-url?
EDIT: found this as well: Spring Security remove RoleVoter prefix
编辑:也发现了这一点: Spring Security remove RoleVoter prefix
回答by olyanren
In Spring 4, there are two methods hasAuthority()
and hasAnyAuthority()
defined in org.springframework.security.access.expression.SecurityExpressionRoot
class. These two methods checks only your custom role name withoutadding ROLE_
prefix. Definition as follows:
在 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;
}
Example usage:
用法示例:
<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>
<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>
回答by Svitlana Onish
As @olyanren sad, you can use hasAuthority() method in Spring 4 instead of hasRole(). I am adding JavaConfig example:
正如@olyanren 难过的那样,您可以在 Spring 4 中使用 hasAuthority() 方法而不是 hasRole()。我正在添加 JavaConfig 示例:
@Override
protected void configure(HttpSecurity http) throws Exception {
.authorizeRequests()
.antMatchers("/api/**")
.access("hasAuthority('ADMIN')")
.and()
.httpBasic().and().csrf().disable();
}
回答by Hamid Mohayeji
You can create a mapper to add _ROLE
at the beginning of all of your roles:
您可以创建一个映射器以添加_ROLE
到所有角色的开头:
@Bean
public GrantedAuthoritiesMapper authoritiesMapper() {
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setPrefix("ROLE_"); // this line is not required
mapper.setConvertToUpperCase(true); // convert your roles to uppercase
mapper.setDefaultAuthority("USER"); // set a default role
return mapper;
}
The you should add the mapper to your provider:
您应该将映射器添加到您的提供者:
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// your config ...
provider.setAuthoritiesMapper(authoritiesMapper());
return provider;
}
回答by Hashan Mahesh
_ROLE prefix is used by spring security, to identify that it is as a role. A role has a set of privileges a.k.a Authorities, these authorities define varies permissions for a role. ex:- EDIT_PROFILE, DELETE_PROFILE
_ROLE 前缀由 spring security 使用,以标识它是一个角色。角色具有一组权限,即权限,这些权限为角色定义了不同的权限。例如:- EDIT_PROFILE, DELETE_PROFILE
You can define both the roles and authorities, if you are defining a role then it must be prefixed with "ROLE_"
您可以定义角色和权限,如果要定义角色,则必须以“ROLE_”为前缀
In your case you are looking for a role, so by default spring security looks for a string that is prefixed with "ROLE_".
在您的情况下,您正在寻找一个角色,因此默认情况下,spring security 会查找以“ROLE_”为前缀的字符串。