로그인 다시 안하고 사용자 권한 업데이트 & 변경하기
Problem
회원가입, 멤버십 구매등의 로직을 개발하면서 구매 완료시점에서 사용자의 권한을 변경 또는 추가를 해줘야했다. 단순한 방법으로는 가입 및 구매 완료 후 다시 로그인 화면으로 옮기는 방법이 있다.
하지만 이 방법은 사용자로 하여금 불편한? 과정일 것이다. 그래서 찾아보니 로그아웃 - 로그인 없이 Spring 의 Security 에 있는 SecurityContext 의 값을 변경해주면 되는 방법이 있었다.
다음은 간단한 사용방법의 예이다.
How to solve?
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities());
updatedAuthorities.add(...); //add your role here [e.g., new SimpleGrantedAuthority("ROLE_NEW_ROLE")]
Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities);
SecurityContextHolder.getContext().setAuthentication(newAuth);
나는 Keycloak 을 사용하고 있어서 Keycloak 버전도 올려본다.
List<GrantedAuthority> newRoles = new ArrayList<>();
if (result.getStatusCode().is2xxSuccessful()) {
newRoles = result.getBody().stream().map(
res -> {
// {keycloak auth url}/auth/admin/realms/{realm name}/users/{user id(uuid)}/role-mappings/clients/{clientid{uuid}, containerid};
// 요청 후 받아온 값에서 Security 의 기본 접두사인 ROLE_ 이 생략되어 있으므로 추가해주어야 한다.
// 추가하지 않으면 Security 에서 원할한 검사가 되지 않는다.
String role = "ROLE_" + ((String) res.get("name"));
return new KeycloakRole(role);
}
)
.collect(Collectors.toList());
}
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
KeycloakAuthenticationToken existToken = (KeycloakAuthenticationToken) auth;
List<GrantedAuthority> oldRoles = auth.getAuthorities().stream().map(authority -> new KeycloakRole(authority.getAuthority())).collect(Collectors.toList());
newRoles.addAll(oldRoles);
Authentication newAuth = new KeycloakAuthenticationToken(existToken.getAccount(), existToken.isInteractive(), newRoles);
SecurityContextHolder.getContext().setAuthentication(newAuth);
참고
How to reload authorities on user update with Spring Security
댓글남기기