2008-11-12 14 views
4

사용자에게 액세스 키가있는 특수 URL을 제공합니다. 이 특수 URL을 통해 공용 페이지에 액세스하는 사용자는 간단한 익명 사용자와 비교하여 일부 추가 데이터를 볼 수 있어야합니다.Acegi Security : 익명 사용자에게 인증에 다른 GrantedAuthority를 ​​추가하는 방법

는 나는 내 템플릿에이 같은 작업을 수행 할 수 있도록 요청에 제공된 매개 변수를 기반으로 익명 사용자에게 몇 가지 추가 역할을 부여 할 : 현재

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

내가 구현하고있어 봄의 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? 
     } 
    } 
} 

답변

6

원본에 위임 한 래퍼 클래스를 만들지 말고 두 가지 추가 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); 
    } 
} 

한 다음 필터에서이 작업을 수행 :

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

Authentication (인증) 이제 여분의 역할과 버전으로 대체됩니다. 주의 인증이 아직 인증되지 않은 getAuthorities()가 null을 돌려주는 경우를 처리해야 할 수도 있습니다. (래퍼 구현에서는, 현재, 랩 된 인증으로부터 항상 null 이외의 배열을 취득하는 것을 전제로하고있다)

+0

멋지다! 나는 자신을 추가 역할을 가진 새로운 AnonymousAuthenticationToken을 작성하여 해결했지만 훨씬 더 우아합니다. 감사 – miceuz