UserDetails.getAuthorities()
содержит все роли текущего пользователя. Поскольку у вас уже есть пользовательский UserDetails
. Вам нужно только добавить дополнительную роль к значениям, возвращаемым getAuthorities()
в начале середины сеанса, а затем удалить ее в конце сеанса. ( см. edit ниже)
е
public class MyUserDetails implements UserDetails {
// holds the authorities granted to the user in DB
private List<GrantedAuthority> authorities;
// holds the temporarily added authorities for the mid-session
private List<GrantedAuthority> extraAuthorities;
public GrantedAuthority[] getAuthorities() {
List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
auths.addAll(this.authorities);
auths.addAll(this.extraAuthorities);
return auths;
}
public void addExtraAuthorities(GrantedAuthority...auths) {
for (GrantedAuthority a : auths) {
this.extraAuthorities.add(a);
}
}
public void clearExtraAuthorities() {
this.extraAuthorities.clear();
}
}
Или Вы можете создать обертку вокруг исходных UserDetails, которая будет содержать дополнительные права доступа и обернуть их и установить для текущего объекта аутентификации в начале сеанса и развернуть в конце сеанса.
Редактировать:
Как отметил Бен в комментарии, UserDetails.getAuthorities()
вызывается только один раз, при входе в систему, когда создается объект Authentication
- я забыл об этом. Но это приводит нас к правильному ответу, и на этот раз я уверен, что это сработает, потому что я сам так сделал. Authentication.getAuthorities()
- это метод, который нужно использовать, а не UserDetails.getAuthorities()
. И я действительно рекомендую для этого оболочку, а не пользовательскую реализацию Authentication
, так как она будет более гибкой и позволит прозрачно поддерживать различные механизмы аутентификации под ней.
е
public class MidSessionAuthenticationWrapper implements Authentication {
private Authentication wrapped;
private List<GrantedAuthority> authorities;
public MidSessionAuthenticationWrapper(
Authentication wrapped, Collection<GrantedAuthority> extraAuths) {
this.wrapped = wrapped;
this.authorities = new ArrayList<GrantedAuthority>(wrapped.getAuthorities());
this.authorities.addAll(extraAuths);
}
public Authentication getWrapped() {
return this.wrapped;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return this.authorities;
}
// delegate all the other methods of Authentication interace to this.wrapped
}
Тогда все, что вам нужно сделать, это в начале сеанса:
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
Collection<GrantedAuthority> extraAuths =
null; // calculate the extra authorities
MidSessionAuthenticationWrapper midSessionAuthentication =
new MidSessionAuthenticationWrapper(authentication, extraAuths);
SecurityContextHolder.getContext().setAuthentication(midSessionAuthentication);
И в конце сеанса:
MidSessionAuthenticationWrapper midSessionAuthentication =
(MidSessionAuthenticationWrapper) SecurityContextHolder.getContext().getAuthentication();
Authentication authentication = midSessionAuthentication.getWrapped();
SecurityContextHolder.getContext().setAuthentication(authentication);