Acegi Security: Comment puis-je ajouter un autre GrantedAuthority à l'authentification à un utilisateur anonyme

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

Question

Je donne aux utilisateurs une URL spéciale avec une clé d'accès. Les utilisateurs accédant à la page publique via cette URL spéciale devraient pouvoir voir des données supplémentaires par rapport à un simple utilisateur anonyme.

Je souhaite donner un rôle supplémentaire à un utilisateur anonyme en fonction des paramètres fournis dans la demande afin que je puisse faire quelque chose comme ceci dans mon modèle:

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

j'implémente actuellement le OncePerRequestfilter de 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?
        }
    }
}
Était-ce utile?

La solution

Pourquoi ne pas créer simplement une classe wrapper qui délègue à l'original, mais ajoute quelques octrois supplémentaires?

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

puis faites ceci dans votre filtre:

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'authentification est maintenant remplacée par votre version avec les rôles supplémentaires. NB: vous devrez peut-être gérer le cas où l'authentification n'a pas encore été authentifiée et que son getAuthorities () renvoie null. (L’implémentation du wrapper suppose actuellement qu’elle obtiendra toujours un tableau non nul de son authentification encapsulée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top