스프링 키클로크:사용자 ID 가져오기
저는 Spring Boot Web 서비스를 개발했고, 접근 관리를 위해 Keycloock을 사용합니다.웹 사이트는 일부 사용자 데이터를 데이터베이스에 저장합니다.로그인한 사용자와 이 데이터를 연결하려고 합니다.
데이터와 함께 사용자 이름을 저장하는 순간.하지만 저는 사용자 이름 대신 사용자 ID를 저장하고 싶습니다.내가 어떻게 그럴 수 있을까?
이를 통해 SecurityContext를 가져오려고 합니다.
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public KeycloakSecurityContext getKeycloakSecurityContext() {
return ((KeycloakPrincipal<KeycloakSecurityContext>) getRequest().getUserPrincipal()).getKeycloakSecurityContext();
}
하지만 오류가 발생합니다.
There was an unexpected error (type=Internal Server Error, status=500).
Error creating bean with name 'scopedTarget.getKeycloakSecurityContext'
defined in com.SiteApplication: Bean instantiation via factory method
failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.keycloak.KeycloakSecurityContext]: Factory method
'getKeycloakSecurityContext' threw exception; nested exception is
java.lang.ClassCastException:
org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken
cannot be cast to org.keycloak.KeycloakPrincipal
이게 바른 길이야?무엇이 부족합니까?
감사해요!
위의 것보다 훨씬 간단한 해결책을 찾았습니다.
@GetMapping
public ResponseEntity getEndpoint(String someParam, HttpServletRequest request) {
KeycloakAuthenticationToken principal = (KeycloakAuthenticationToken) request.getUserPrincipal();
String userId = principal.getAccount().getKeycloakSecurityContext().getIdToken().getSubject();
//....do something
return new ResponseEntity(HttpStatus.OK);
}
내 생각에 당신이 위에 있는 예외는 당신이 캐스팅하려고 하기 때문인 것 같습니다.getRequest().getUserPrincipal()
로.KeycloakPrincipal<KeycloakSecurityContext>
그것이 활자인 동안에는KeycloakAuthenticationToken
,그렇게((KeycloakAuthenticationToken) getRequest().getUserPrincipal())
효과가 있을 겁니다.
저도 우리 코드에 비슷한 걸 해봤어요.
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new RuntimeException("Expecting a HTTP request");
}
RefreshableKeycloakSecurityContext context = (RefreshableKeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
if (context == null) {
handleNoSecurityContext(request, response, chain);
return;
}
AccessToken accessToken = context.getToken();
Integer userId = Integer.parseInt(accessToken.getOtherClaims().get("user_id").toString());
chain.doFilter(request, response);
}
}
이 작업을 수행하기 전에 먼저 다음을 추가해야 합니다.user_id
키클록에 의해 발행되는 액세스 토큰.아래 스크린샷과 같이 맵퍼를 통해 할 수 있습니다.
또한 위의 프로세싱 필터를 응용프로그램 라이프사이클에 추가하는 것을 잊지 마십시오.@Bean
응용 프로그램 클래스에 메서드를 지정합니다.
@Configuration
@EnableAutoConfiguration(exclude = {FallbackWebSecurityAutoConfiguration.class, SpringBootWebSecurityConfiguration.class, DataSourceAutoConfiguration.class})
@ComponentScan
@EnableAsync
public class MyServiceClass {
public static void main(String[] args) {
Properties properties = new Properties();
new SpringApplicationBuilder(MyServiceClass.class)
.properties(properties)
.bannerMode(Banner.Mode.OFF)
.run(args);
}
@Bean
public AuthenticationTokenProcessingFilter authFilter() {
return new AuthenticationTokenProcessingFilter();
}
}
위의 모든 솔루션들은 2년 전에는 사용하지 않던 (매우) Keycloak Spring 어댑터를 사용하고 있습니다.
2 키클로크 스프링 어댑터의 대안으로, 두 어댑터 모두 토큰 클레임에 매우 쉽게 접근할 수 있습니다.Authentication
스프링이 주입한 "자동으로"@Controller
메서드 매개 변수입니다.
spring-addons-webmvc-jwt-resource-server
여기 샘플: 속성에서 구성할 수 있는 거의 모든 것
@GetMapping
@PreAuthorize("isAuthenticated()")
public ResponseEntity getEndpoint(OAuthentication<OpenidClaimSet> auth) {
final var preferredUsername = auth.getClaims().getPreferredUsername();
final var subject = auth.getClaims().getSubject();
//....do something
return new ResponseEntity(HttpStatus.OK);
}
spring-boot-starter-oauth2-resource-server
샘플: 훨씬 더 많은 Java 구성이 필요합니다.
@GetMapping
@PreAuthorize("isAuthenticated()")
public ResponseEntity getEndpoint(JwtAuthenticationToken auth) {
final var preferredUsername = auth.getToken().getClaimAsString(StandardClaimNames.SUB);
final var subject = auth.getToken().getClaimAsString(StandardClaimNames.PREFERRED_USERNAME);
//....do something
return new ResponseEntity(HttpStatus.OK);
}
언급URL : https://stackoverflow.com/questions/45802797/spring-keycloak-get-user-id
'source' 카테고리의 다른 글
mysql 숫자가 쉼표로 구분된 목록에 있는지 확인합니다. (0) | 2023.10.09 |
---|---|
Linux의 C 프로그램에서 FS가 없는 하드 디스크에 직접 액세스 (0) | 2023.10.09 |
기존 표에서 각 단어의 첫 글자를 대문자로 바꿉니다. (0) | 2023.10.09 |
Linux에서 Ctrl + C 인터럽트 이벤트 처리 (0) | 2023.10.09 |
제출후 각도 - 클리어 폼 입력 (0) | 2023.10.09 |