java - hasrole - spring security role access
La seguridad de primavera agregó el prefijo "ROLE_" al nombre de todos los roles. (3)
En Spring 4, hay dos métodos hasAuthority()
y hasAnyAuthority()
definidos en la clase org.springframework.security.access.expression.SecurityExpressionRoot
. Estos dos métodos solo verifican su nombre de rol personalizado sin agregar el prefijo ROLE_
. Definición de la siguiente manera:
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;
}
Ejemplo de uso:
<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>
Tengo este código en mi configuración de seguridad web:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**")
.hasRole("ADMIN")
.and()
.httpBasic().and().csrf().disable();
}
Así que agregué un usuario con el rol "ADMIN" en mi base de datos y siempre obtengo el error 403 cuando probaba el inicio de sesión con este usuario, luego habilité el registro para la primavera y encontré esta línea:
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'')]
¿Por qué Spring Security está buscando "ROLE_ADMIN" en lugar de "ADMIN"?
La seguridad de Spring agrega el prefijo " ROLE_ " de manera predeterminada.
Si desea eliminar o cambiar esto, eche un vistazo a
http://forum.spring.io/forum/spring-projects/security/51066-how-to-change-role-from-interceptor-url
EDIT: encontré esto también: Spring Security elimina el prefijo RoleVoter
Como @olyanren sad, puede usar el método hasAuthority () en Spring 4 en lugar de hasRole (). Estoy agregando el ejemplo de JavaConfig:
@Override
protected void configure(HttpSecurity http) throws Exception {
.authorizeRequests()
.antMatchers("/api/**")
.access("hasAuthority(''ADMIN'')")
.and()
.httpBasic().and().csrf().disable();
}