#java #spring #spring-security #authorization
#java #spring #spring-безопасность #авторизация
Вопрос:
Я работаю с политикой безопасности Spring и нуждаюсь в помощи с глобальной ролью SUPER, которая должна обходить все @PreAuthorize
конечные точки, когда она есть у токена. Это пример конечной точки:
@GetMapping
@PreAuthorize("(hasAuthority('DOMAIN_FIND_ALL'))")
public ResponseEntity<ResponseDTO<List<DomainDTO>>> findAll() {
return ResponseEntity.ok().body(domainService.findAll());
}
Способ, который я нашел для своей глобальной роли, выглядит следующим образом
@GetMapping
@PreAuthorize("(hasAuthority('DOMAIN_FIND_ALL') or (hasAuthority('SUPER'))")
public ResponseEntity<ResponseDTO<List<DomainDTO>>> findAll() {
return ResponseEntity.ok().body(domainService.findAll());
}
Но слишком длинный, чтобы реализовать каждую отдельную конечную точку приложения (hasAuthority('SUPER')
, поэтому я ищу способ настроить его глобальным образом, чтобы, если токен имеет эту роль, разрешались все конечные точки.
Что я пробовал:
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.otherStuffs..
.antMatchers("/**").authenticated()
.antMatchers("/**").hasRole("SUPER");
}
Но это не работает. У кого-нибудь есть идеи по этому поводу?
Ответ №1:
Для более подробного объяснения посмотрите следующую ссылку (в основном раздел 6). Код, используемый в качестве основы моего ответа, был:
customMethod Security expressionhandler
Следующий код работает для меня:
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.otherStuffs..
.antMatchers("/**").authenticated(); // hasRole("SUPER") isn't require
}
Переопределить MethodSecurityExpressionOperations
интерфейс по умолчанию:
public class MySecurityExpressionRoot implements MethodSecurityExpressionOperations {
// Same properties than provided
// link for MySecurityExpressionRoot
...
public MySecurityExpressionRoot(Authentication authentication) {
if (authentication == null) {
throw new IllegalArgumentException("Authentication object cannot be null");
}
this.authentication = authentication;
}
// This is the ONLY change, as you can see the "SUPER" was added as allowed
@Override
public final boolean hasAuthority(String authority) {
return this.hasAnyAuthority(authority, "SUPER");
}
// Rest of the code is the same than provided
// link for MySecurityExpressionRoot
...
}
Теперь нам нужно добавить вышеуказанный класс в конфигурацию Spring:
@Configuration // Required although not include in "source CustomMethodSecurityExpressionHandler" class
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@Override
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
final MySecurityExpressionRoot root = new MySecurityExpressionRoot(authentication);
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(this.trustResolver);
root.setRoleHierarchy(getRoleHierarchy());
return root;
}
}
Теперь вы можете проверить это, используя следующую фиктивную GET
конечную точку:
@GetMapping("/add-new-user")
@PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<String> addNewUser() {
return new ResponseEntity("[add-new-user] Testing purpose", OK);
}
Любой пользователь с ADMIN
SUPER
ролями: или сможет получить к нему доступ.