Как предоставить пользователям доступ к адресам, начинающимся с определённого сочетания, в соответствии с их ролями?
Как настроить Spring Security так, чтобы у пользователя с определённой ролью был доступ только к URL, начинающихся с определённого значения? В данном случае задача такая:
USER → все URL, начинающиеся с /user (например, /user, /user/, /user/update-info)
ADMIN → все URL, начинающиеся с /admin (например, /admin, /admin/, /admin/update-user)
Пробовал так (должно работать, я считаю!)
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin", "/admin/**").hasRole("ADMIN")
.antMatchers("/user", "/user/**").hasRole("USER")
.anyRequest().authenticated()
.and().formLogin().successHandler(successUserHandler)
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/login");
}
и так
// ...
.antMatchers("/admin/", "/admin/**").hasRole("ADMIN")
.antMatchers("/user/", "/user/**").hasRole("USER")
// ...
и ещё несколько вариаций. Всё одно – ошибка 403 ("forbidden", то есть нет прав)
Мэтчеры могут работать шиворот-навыворот
Но одновременно и нет
Все скриншоты сделаны после входа в пользователя mickey_m, который имеет роль USER. Джоинтейбл:
Как мне реализовать свою задачу и почему Spring Security так себя ведёт (на мой взгляд, странно)?
Версия Boot 2.6.2, а Security – 5.6.1. Гуглил по такому запросу. Репо здесь (Security конфиг может отличаться от того, что на скриншотах)
Я знаю, что скриншоты здесь не любят, но я действительно не знаю, как передать эту информацию столь же полно и достоверно с помощью текста
UPD: Запустил с дебаг-логом и увидел это. Возможно, это связано с проблемой. Но почему он проверяет с префиксом? Я префиксы нигде не ставил. Зашёл в класс FilterSecurityInterceptor, но ничего там не увидел
DEBUG 3888 --- [nio-8080-exec-6] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /user] with attributes [hasRole('ROLE_USER')]
UPD2: Кажется, я нашёл бандита, который мне всё портит (SecurityExpressionRoot). Но как его обезвредить? Как сделать так, чтобы роли проверялись без этого дефолтного суффикса?
public abstract class SecurityExpressionRoot implements SecurityExpressionOperations {
// ...
private String defaultRolePrefix = "ROLE_";
// ...
public final boolean hasRole(String role) {
return this.hasAnyRole(role);
}
public final boolean hasAnyRole(String... roles) {
return this.hasAnyAuthorityName(this.defaultRolePrefix, roles);
}
private boolean hasAnyAuthorityName(String prefix, String... roles) {
Set<String> roleSet = this.getAuthoritySet();
String[] var4 = roles;
int var5 = roles.length;
for(int var6 = 0; var6 < var5; ++var6) {
String role = var4[var6];
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
if (roleSet.contains(defaultedRole)) {
return true;
}
}
return false;
}
UPD3: Слава чатботам (мне помог Sage)! ? Когда роботы восстанут против людей, я займу нейтралитет ?
@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults(""); // удаление дефолтного префикса "ROLE_"
}





