如何在 Spring 中获取 Keycloak 令牌

How to get Keycloak token in Spring

我有 Spring 应用程序和 Angular 前端,我用 Keycloak 11.0.2 保护两侧,当从前端发送请求时,我如何获取令牌信息,因为示例 我想访问 Spring 端的经过身份验证的用户信息和属性,因为我返回的请求取决于用户属性。

下面是我在 spring 中的配置:

keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=myapp
keycloak.resource=myapp-api
keycloak.ssl-required=external
keycloak.bearer-only=true
keycloak.principal-attribute=preferred_username


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests().anyRequest().permitAll();
        http.csrf().disable();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new NullAuthenticatedSessionStrategy();
    }

    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
}

根据您的问题,我认为您指的是 ID 令牌,您可以(例如)从请求中获取它。检查以下示例:

@GetMapping(path = "/student")
public String teen(HttpServletRequest request) throws ServletException {
       KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) request.getUserPrincipal();
       System.out.println("---- ROLES ----");
       token.getAccount().getRoles().forEach(System.out::println);
       Map<String, Object> otherClaims = token.getAccount().getKeycloakSecurityContext().getIdToken().getOtherClaims();

       Enumeration<String> attributeNames = request.getAttributeNames();
       while (attributeNames.hasMoreElements())
            System.out.println(attributeNames.nextElement());

       for(String s : otherClaims.keySet()){
            System.out.println(s);
            System.out.println(otherClaims.get(s).toString());
       }

       System.out.println("------------");
       return "student";
    }

上面的代码只是一个示例,但展示了一些 API 功能。