Acegi segurança: Como faço para adicionar outro GrantedAuthority de autenticação para usuário anônimo

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

Pergunta

i dar aos usuários URL especial com chave de acesso na mesma. usuários que acessam a página pública através deste url especial deve ser capaz de ver alguns dados adicionais em relação ao usuário anônimo simples.

Eu quero dar algum papel adicional para usuário anônimo com base nos parâmetros fornecidos no pedido para que eu possa fazer algo assim no meu modelo:

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

Atualmente estou implementando OncePerRequestfilter da Primavera:

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?
        }
    }
}
Foi útil?

Solução

Porque não basta criar uma classe wrapper que delega para o original, mas acrescenta em um par de GrantedAuthorities extras:

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, em seguida, fazer isso no seu 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 );

A autenticação é agora substituído por sua versão com as funções extras. NB Você pode ter que lidar com o caso em que a autenticação ainda não foi autenticado e por isso seus getAuthorities () retorna null. (A implementação invólucro assume actualmente que ele sempre terá uma matriz não-nula de sua autenticação envolto)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top