4 Stimmen

Acegi Sicherheit: Wie füge ich einer Authentifizierung für anonyme Benutzer eine weitere GrantedAuthority hinzu?

Ich gebe Benutzern eine spezielle URL mit einem Zugriffsschlüssel darin. Benutzer, die die öffentliche Seite über diese spezielle URL aufrufen, sollten im Vergleich zu einfachen anonymen Benutzern einige zusätzliche Daten sehen können.

Ich möchte anonymen Benutzern basierend auf den im Request übergebenen Parametern eine zusätzliche Rolle geben, damit ich in meiner Vorlage etwas Ähnliches tun kann:

<@sec.authorize ifAnyGranted="ROLE_ADMIN, ROLE_USER, ROLE_INVITED_VISITOR">
...einige zusätzliche Inhalte, die der eingeladene Benutzer sehen kann

Aktuell implementiere ich Springs OncePerRequestfilter:

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();
            //Wie füge ich zusätzliche Rollen für den authentifizierten (potenziell anonymen) Benutzer hinzu?
        }
    }
}

7voto

alasdairg Punkte 2078

Warum erstellen Sie nicht einfach eine Wrapper-Klasse, die an das Original delegiert, aber ein paar zusätzliche GrantedAuthorities hinzufügt:

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

und dann das in Ihrem Filter tun:

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

Die Authentifizierung wird nun durch Ihre Version mit den zusätzlichen Rollen ersetzt. Beachten Sie, dass Sie möglicherweise den Fall behandeln müssen, in dem die Authentifizierung noch nicht durchgeführt wurde und daher ihr getAuthorities() null zurückgibt. (Die Wrapper-Implementierung geht derzeit davon aus, dass sie immer ein nicht-nulles Array von der umschlossenen Authentifizierung erhält)

0 Stimmen

Schön gemacht! Ich habe es selbst gelöst, indem ich ein neues AnonymousAuthenticationToken mit zusätzlichen Rollen erstellt habe, aber das hier ist viel eleganter. Danke

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X