Acegi Security: come posso aggiungere un altro GrantedAuthority all'autenticazione a un utente anonimo

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

Domanda

Offro agli utenti un URL speciale con la chiave di accesso al suo interno. gli utenti che accedono alla pagina pubblica tramite questo URL speciale dovrebbero essere in grado di visualizzare alcuni dati aggiuntivi rispetto al semplice utente anonimo.

Voglio assegnare un ruolo aggiuntivo all'utente anonimo in base ai parametri forniti nella richiesta in modo da poter fare qualcosa del genere nel mio modello:

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

Al momento sto implementando il OncePerRequestfilter di 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?
        }
    }
}
È stato utile?

Soluzione

Perché non solo creare una classe wrapper che deleghi all'originale, ma aggiunge un paio di extra 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 );
   }  
}

e quindi fai questo nel tuo filtro:

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 );

L'autenticazione è ora sostituita dalla versione con i ruoli aggiuntivi. NB Potrebbe essere necessario gestire il caso in cui l'autenticazione non è ancora stata autenticata e quindi getAuthorities () restituisce null. (L'implementazione del wrapper attualmente presuppone che otterrà sempre un array non nullo dalla sua autenticazione incorporata)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top