我已经开发了一个Spring Boot Web服务,并使用Keycloak进行访问管理。
该网站将一些用户数据存储在数据库中。我尝试将这些数据与登录的用户连接。

目前,我将用户名和数据一起存储。但是我喜欢存储用户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())可以工作。

10-04 19:27