問題是您需要創建一個包含新目標用戶信息的新令牌。這個新的令牌必須被髮送回客戶端,所以爲了將來的請求使用新的目標用戶令牌。在我們的例子中,令牌在服務器端持久存在(使用JDBCTokenStore),但它也可以在完全服務器端的無狀態環境(JWT-Token)中運行。
我們的環境是一個帶角度爲1.2的客戶端的spring-boot/jhipster應用程序。
創建一個新的令牌:
@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;
}
這個新的令牌返回給客戶端(在本例中的角1.2應用程序)存儲在其本地存儲的令牌(在下次請求中使用)。然後,應用程序需要重新加載(更新目標用戶的最簡單方式):
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()
});
}