Pertanyaan Keamanan Acegi: Bagaimana saya menambahkan GrantedAuthority lain ke Authentication ke pengguna anonim


saya memberi pengguna URL khusus dengan kunci akses di dalamnya. pengguna yang mengakses halaman publik melalui url khusus ini harus dapat melihat beberapa data tambahan dibandingkan dengan pengguna anonim sederhana.

Saya ingin memberikan beberapa peran tambahan kepada pengguna anonim berdasarkan parameter yang disediakan dalam permintaan sehingga saya dapat melakukan sesuatu seperti ini di template saya:

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

Saat ini saya sedang menerapkan 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?
        }
    }
}

4
2017-11-12 13:04


asal


Jawaban:


Mengapa tidak membuat kelas pembungkus yang didelegasikan ke asli, tetapi menambahkan beberapa tambahan 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 );
   }  
}

lalu lakukan ini di filter Anda:

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

Otentikasi sekarang digantikan oleh versi Anda dengan peran tambahan. NB Anda mungkin harus menangani kasus di mana Otentikasi belum dikonfirmasi dan sehingga getAuthorities () mengembalikan nol. (Implementasi wrapper saat ini mengasumsikan bahwa ia akan selalu mendapatkan array non-null dari Otentikasi terbungkusnya)


6
2017-11-12 14:02