2016-07-30 3 views
0

아직 봄 보안 OAuth2를 구현 나의 봄 부팅 응용 프로그램에서 SwitchUserFilter를 설정합니다. 난 이미 내 WebSecurityConfiguration WebSecurityConfigurerAdapter를 확장이 필터를 설정했습니다.봄 보안 OAuth2를 + 스위치 사용자 필터

로그인 후에 토큰 및 베어러 토큰을 얻었으며 사용자를 전환하기 위해 구성된 끝점을 사용합니다.

내 IDE에서 디버그 코드를 따르고 분명히 SecurityContextHolder이 업데이트되고 새로운 대상 사용자가 삽입됩니다.

그러나 요청이 대상 URL (이 필터의 속성)으로 리디렉션 될 때 SecurityContextHolder은 내가 이전에 요청한 사용자가 아니라 이전 사용자를 돌려줍니다.

I은 ​​OAuth2AuthenticationProcessingFilter를 검사 한 결과 요구로부터 추출 된 토큰이 토큰을 반환 동일한 베어러이 그것을 사용자의 세부 사항을 구축하고에 SecurityContextHolder에 주입.

oauth2 방식으로 이러한 종류의 필터를 사용할 수 있습니까?

답변

1

문제는 새 대상 사용자 정보가 들어있는 새 토큰을 만들어야한다는 것입니다. 이 새 토큰은 클라이언트에 다시 보내 져야하므로 이후 요청시 새 대상 사용자 토큰이 사용됩니다. 이 경우 토큰은 (JDBCTokenStore를 사용하여) 서버 측에서 유지되지만 서버 측의 완전 무 상태 환경 (JWT-Token)에서도 작동합니다.

우리의 환경은 1.2 버전의 클라이언트가있는 spring-boot/jhipster 응용 프로그램입니다. 이 새로운 토큰은 로컬 스토리지에있는 토큰을 저장 (우리의 경우 각도 1.2 응용 프로그램에서) 클라이언트에 반환됩니다

@Inject 
private UserDetailsService userDetailsService; 

@Inject 
private AuthorizationServerTokenServices tokenService; 

@Inject 
private ClientDetailsService clientDetailsService; 


    public OAuth2AccessToken createImpersonationAccessToken(String login) { 
     UserDetails userDetails = userDetailsService.loadUserByUsername(login); 
     log.info("Switching current user to {}", login); 

     Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities(); 
     List<GrantedAuthority> impersonationAuthorities = new ArrayList<>(authorities); 
     Authentication source = SecurityContextHolder.getContext().getAuthentication(); 
     // add current user authentication (to switch back from impersonation): 
     SwitchUserGrantedAuthority switchUserAuthority = 
       new SwitchUserGrantedAuthority(AuthoritiesConstants.IMPERSONATION, source); 
     impersonationAuthorities.add(switchUserAuthority); 
        UserDetails newUserDetails = 
       org.springframework.security.core.userdetails.User 
       .withUsername(login) 
       .authorities(impersonationAuthorities) 
       .password("justinventedhere") 
       .build(); 
          Authentication userPasswordAuthentiation = 
       new UsernamePasswordAuthenticationToken(newUserDetails, null, impersonationAuthorities); 

     Map<String, String> parameters = new HashMap<>();   
     ClientDetails client = clientDetailsService.loadClientByClientId(clientId); 
        OAuth2Request oauthRequest = new OAuth2Request(parameters, client.getClientId(), client.getAuthorities(), true, 
       client.getScope(), client.getResourceIds(), null, null, null); 
     OAuth2Authentication authentication = new OAuth2Authentication(oauthRequest, userPasswordAuthentiation); 
     OAuth2AccessToken createAccessToken = tokenService.createAccessToken(authentication); 
        return createAccessToken; 
    } 

(다음 요청에 사용되는) :

새로운 토큰을 생성. 그런 다음 응용 프로그램을 다시로드해야합니다 (대상 사용자를 업데이트하는 가장 간단한 방법).

vm.switchToClient = function (client) { 
    vm.switchingUser = true; 
    UserService.switchToClient(client, function(response) { 
       var expiredAt = new Date(); 
       $localStorage.authenticationToken = response; 
       window.location.href='#/'; 
       window.location.reload() 
      }); 
}