2016-07-30 657 views
0

Ich mag würde gründen SwitchUserFilter in meinem Feder-Boot-App, die noch federsicherheits oauth2 implementiert. Ich habe bereits diese Filter in meinem WebSecurityConfiguration einrichten, die WebSecurityConfigurerAdapter erstreckt.Federsicherheits oauth2 + Schalter Benutzerfilter

Nach dem Login erhalte ich mein Token, ein Bearer-Token, und ich benutze einen konfigurierten Endpunkt, um den Benutzer zu wechseln.

Ich befolge den Code mit Debug in meiner IDE und anscheinend SecurityContextHolder wird aktualisiert und ein neuer Zielbenutzer wird injiziert.

Wenn die Anforderung jedoch an die Ziel-URL umgeleitet wird (eine Eigenschaft dieses Filters), gibt SecurityContextHolder mir den alten Benutzer zurück und nicht das, was ich angefordert habe.

Ich habe OAuth2AuthenticationProcessingFilter inspiziert und das Token aus Anfrage extrahiert einen gleichen Träger Token zurückgeben und damit es baut Detail Benutzer und injizieren sie in SecurityContextHolder.

Gibt es eine Möglichkeit, diese Art von Filter mit oauth2 Ansatz zu verwenden?

Antwort

1

Das Problem besteht darin, dass Sie ein neues Token erstellen müssen, das die neuen Zielbenutzerinformationen enthält. Dieses neue Token muss zurück an den Client gesendet werden, so dass bei künftigen Anfragen das neue Zielbenutzertoken verwendet wird. In unserem Fall wird das Token auf der Serverseite beibehalten (unter Verwendung des JDBCTokenStore), aber es würde auch in vollständig serverseitigen zustandslosen Umgebungen (JWT-Token) funktionieren.

Unsere Umgebung ist eine Spring-Boot/Jhipster-Anwendung mit einem eckigen 1.2-Client.

Erstellen ein neues Token:

@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; 
    } 

Diese neuen Token an den Client (in unserem Fall eine Winkel 1.2-Anwendung) zurückgeführt werden, die das Token in seinem lokalen Speicher speichert (bis auf nächste Anfragen verwendet werden). Dann muss die Anwendung neu geladen werden (einfachste Möglichkeit, den Zielbenutzer zu aktualisieren):

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