Seguridad de Acegi: ¿Cómo agrego otra GrantedAuthority a la autenticación a un usuario anónimo?

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

Pregunta

les doy a los usuarios una URL especial con clave de acceso. Los usuarios que accedan a la página pública a través de esta URL especial deberían poder ver algunos datos adicionales en comparación con un usuario anónimo simple.

Quiero asignar un rol adicional al usuario anónimo en función de los parámetros proporcionados en la solicitud para poder hacer algo como esto en mi plantilla:

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

actualmente estoy implementando Spring's 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();
            //how do i add additional roles to authenticated (potentially anonymous) user?
        }
    }
}
¿Fue útil?

Solución

¿Por qué no simplemente crear una clase de contenedor que delega al original, sino que agrega un par de GrantedAuthorities adicionales:

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

y luego haz esto en tu 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 );

La autenticación ahora se reemplaza por su versión con los roles adicionales. Nota: es posible que deba manejar el caso en el que la autenticación aún no se haya autenticado y, por lo tanto, getAuthorities () devuelve nulo. (La implementación del contenedor actualmente supone que siempre obtendrá una matriz no nula de su autenticación envuelta)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top