2014-10-15 6 views
0

DaoAuthenticationProvider와 함께 스프링 보안을 사용하는 스프링 기반 웹 응용 프로그램을 구현 중입니다. 그러므로 나는 boolean isEnabled()를 가진 User 클래스를 생성했다. 메서드를 사용하기 때문에 Spring UserDetails 인터페이스를 구현합니다. 따라서 사용자가 "사용하도록 설정되지 않은 경우"이 사용자는 더 이상 로그인 할 수 없습니다. 여태까지는 그런대로 잘됐다. 런타임에 사용자가 계속 로그인되어있는 동안 사용자를 비활성화하면 http 세션이 끝날 때까지이 사용자가 로그인 상태를 유지하지만 비활성화 된 즉시 사용자 로그 아웃을 원합니다. 어떻게해야합니까?스프링 보안 사용자가 런타임 중에 로그 오프

감사합니다.

+0

이것 좀 봐 : http://stackoverflow.com/questions/14297577/get-all-logged-users-in-spring-security, 당신은 어떻게 든 SessionRegistry를 사용해야합니다 – gerrytan

답변

1

사용자를 실행 중지 할 수있는 실행중인 웹 응용 프로그램이 있다고 가정하면 런타임에 해당 사용자를 잠그는 방법을 보여줍니다.

기본적인 아이디어는 새로 고친 사용자 세부 정보로 각 요청을 다시 인증하는 것입니다. 이 목적을 위해 SecurityContextRepository 사용자 정의가 필요합니다. 은 http 세션에 저장된 사용자 세부 정보를 삭제합니다.

public class RefreshingUserDetailsSecurityContextRepository implements SecurityContextRepository { 

    private final SecurityContextRepository delegate; 
    private final UserDetailsService userDetailsService; 

    public RefreshingUserDetailsSecurityContextRepository(final SecurityContextRepository delegate, final UserDetailsService userDetailsService) { 
     Assert.notNull(delegate); 
     Assert.notNull(userDetailsService); 
     this.delegate = delegate; 
     this.userDetailsService = userDetailsService; 
    } 

    @Override 
    public SecurityContext loadContext(final HttpRequestResponseHolder requestResponseHolder) { 
     SecurityContext securityContext = delegate.loadContext(requestResponseHolder); 

     if(securityContext.getAuthentication() == null) { 
      return securityContext; 
     } 

     Authentication principal = securityContext.getAuthentication(); 
     UserDetails userDetails = userDetailsService.loadUserByUsername(principal.getName()); 

     //this code has to be modified when using remember me service, jaas or a custom authentication token 
     UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword()); 

     securityContext.setAuthentication(token); 
     saveContext(securityContext, requestResponseHolder.getRequest(), requestResponseHolder.getResponse()); 
     return securityContext; 
    } 

    @Override 
    public void saveContext(final SecurityContext context, final HttpServletRequest request, final HttpServletResponse response) { 
     delegate.saveContext(context, request, response); 
    } 

    @Override 
    public boolean containsContext(final HttpServletRequest request) { 
     return delegate.containsContext(request); 
    } 
} 

RefreshingUserDetailsSecurityContextRepository 단순히 기본 SecurityContextRepository 랩, 그 HttpSessionSecurityContextRepository입니다. 따라서 세션 시간 초과 또는 걱정없이 SecurityContext을 저장할 필요가 없습니다. loadContext 메서드에서 사용자 세부 정보는 userDetailsService으로 새로 고쳐지고 호출자에게 넘겨 받기 전에 SecurityContext에 다시 기록됩니다.

사용자에게 authoritiesUsernamePasswordAuthenticationToken 생성자로 전달하지 마십시오. 그렇지 않으면 토큰이 인증 된 것으로 표시되고 재 인증이 실행되지 않습니다!

RefreshingUserDetailsSecurityContextRepositoryUsernamePasswordAuthenticationToken으로 제한됩니다. 예를 들어, Jaas를 사용하고자한다면, Spring Security는 UsernamePasswordAuthenticationToken에서 파생되지 않은 커스텀 인증 토큰이나 나를 기억합니다. 사용자의 필요에 따라 RefreshingUserDetailsSecurityContextRepository을 적용해야합니다.

보안 구성에 RefreshingUserDetailsSecurityContextRepository을 추가하십시오.

<security:http use-expressions="true" security-context-repository-ref="refreshingUserDetailsSecurityContextRepository"> 
    <security:intercept-url ... /> 
    <security:form-login ... /> 
    <security:logout /> 
</security:http> 

<bean id="refreshingUserDetailsSecurityContextRepository" class="security.RefreshingUserDetailsSecurityContextRepository"> 
    <constructor-arg index="0"> 
     <bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" /> 
    </constructor-arg> 
    <constructor-arg index="1" ref="userDetailsService" /> 
</bean> 

그게 전부입니다. 로그인했지만 비활성화 된 사용자는 다음 페이지 요청시 로그인 페이지로 다시 연결됩니다.

완전한 기능을 갖춘 example입니다.

+0

어떻게 자바 구성 ? 내가 구성 (HttpSecurity http) { http.securityContext(). securityContextRepository (새로운 RefreshingUserDetailsSecurityContextRepository()) 하지만이 클래스는 생성자 매개 변수가 필요합니까? – matthewrk

관련 문제