Acegi Security: Как добавить еще один GrantedAuthority для аутентификации анонимному пользователю

StackOverflow https://stackoverflow.com/questions/283870

Вопрос

Я даю пользователям специальный URL с ключом доступа. пользователи, получающие доступ к общедоступной странице через этот специальный URL-адрес, должны видеть некоторые дополнительные данные по сравнению с простым анонимным пользователем.

Я хочу дать некоторую дополнительную роль анонимному пользователю на основе параметров, указанных в запросе, чтобы я мог сделать что-то подобное в моем шаблоне:

<@sec.authorize ifAnyGranted="ROLE_ADMIN, ROLE_USER, ROLE_INVITED_VISITOR">
...some additional stuff for invited user to see
</@sec.authorize>

В настоящее время я реализую OncePerRequestfilter Spring :

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
    if (null != request.getParameter("accessKey")) {
        if(isValid(request.getParameter("accessKey"))) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            //how do i add additional roles to authenticated (potentially anonymous) user?
        }
    }
}
Это было полезно?

Решение

Почему бы просто не создать класс-оболочку, который делегирует оригинал, но добавляет несколько дополнительных GrantedAuthorities:

public class AuthenticationWrapper implements Authentication
{
   private Authentication original;
   private GrantedAuthority[] extraRoles;

   public AuthenticationWrapper( Authentication original, GrantedAuthority[] extraRoles )
   {
      this.original = original;
      this.extraRoles = extraRoles;
   }

   public GrantedAuthority[] getAuthorities()
   {
      GrantedAuthority[] originalRoles = original.getAuthorities();
      GrantedAuthority[]  roles = new GrantedAuthority[originalRoles.length + extraRoles.length];
      System.arraycopy( originalRoles, 0, roles, 0, originalRoles.length );
      System.arraycopy( extraRoles, 0, roles, originalRoles.length, extraRoles.length );
      return roles;
   }

   public String getName() { return original.getName(); }
   public Object getCredentials() { return original.getCredentials(); }
   public Object getDetails() { return original.getDetails(); }   
   public Object getPrincipal() { return original.getPrincipal(); }
   public boolean isAuthenticated() { return original.isAuthenticated(); }
   public void setAuthenticated( boolean isAuthenticated ) throws IllegalArgumentException
   {
      original.setAuthenticated( isAuthenticated );
   }  
}

, а затем сделайте это в своем фильтре:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
GrantedAuthority extraRoles = new GrantedAuthority[2];
extraRoles[0] = new GrantedAuthorityImpl( "Role X" );
extraRoles[1] = new GrantedAuthorityImpl( "Role Y" );
AuthenticationWrapper wrapper = new AuthenticationWrapper( auth, extraRoles );
SecurityContextHolder.getContext().setAuthentication( wrapper );

Аутентификация теперь заменяется вашей версией с дополнительными ролями. NB. Возможно, вам придется обработать случай, когда аутентификация еще не была аутентифицирована, и поэтому ее getAuthorities () возвращает ноль. (Реализация оболочки в настоящее время предполагает, что он всегда получит ненулевой массив из своей завернутой аутентификации)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top