【问题标题】:How to get Access Token from Keycloak over SpringBoot?如何通过 SpringBoot 从 Keycloak 获取访问令牌?
【发布时间】:2021-08-13 17:28:57
【问题描述】:

我正在尝试通过 SpringBoot 从 Keycloak 获取访问令牌,并尝试了以下示例。但KeycloakAuthenticationToken token 为空。

有人知道获取访问令牌的另一种方法吗?

@GetMapping("/token")
public String getToken(HttpServletRequest request) throws IOException {

    KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) request.getUserPrincipal();
    RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) token.getAccount().getKeycloakSecurityContext();
    KeycloakSecurityContext context = token.getAccount().getKeycloakSecurityContext();


    String accessTokenPretty = JsonSerialization.writeValueAsPrettyString(session.getToken());
    String idTokenPretty = JsonSerialization.writeValueAsPrettyString(session.getIdToken());

    RefreshToken refreshToken;
    try {
        refreshToken = new JWSInput(session.getRefreshToken()).readJsonContent(RefreshToken.class);
    } catch (JWSInputException e) {
        throw new IOException(e);
    }
    String refreshTokenPretty = JsonSerialization.writeValueAsPrettyString(refreshToken);

    return refreshTokenPretty;
}

似乎我可以使用 ('org.keycloak:keycloak-admin-client') 获得这样的令牌:

Keycloak keycloak = KeycloakBuilder.builder() //
            .serverUrl(serverUrl) //
            .realm(realm) //
            .grantType(OAuth2Constants.PASSWORD) //
            .clientId(clientId) //
            .clientSecret(clientSecret) //
            .username(userName) //
            .password(password) //
            .build();
AccessTokenResponse tok = keycloak.tokenManager().getAccessToken();

如果有人知道更优雅的方式,如果你让我知道,我将不胜感激:)

提前致谢!

【问题讨论】:

    标签: java spring-boot keycloak access-token


    【解决方案1】:

    尝试以下方法:

    HttpEntity<MultiValueMap<String, String>> request =
            new TokenRequest.Builder(clientID, OAuth2Constants.PASSWORD)
                    .add("username", userName)
                    .add("password", password)
                    .build();
    ResponseEntity<String> response = restTemplate.postForEntity( postUrl, request , String.class );
    return response.getBody();
    

    和辅助类:

    public class TokenRequest {
        public static class Builder{
            MultiValueMap<String, String> data;
            public Builder(String clientID, String grant_type){
                data = new LinkedMultiValueMap<>();
                data.put("client_id", Collections.singletonList(clientID));
                data.put("grant_type", Collections.singletonList(grant_type));
            }
            public Builder add(String key, String value){
                data.put(key, Collections.singletonList(value));
                return this;
            }
            public HttpEntity<MultiValueMap<String, String>>  build(){
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
                return new HttpEntity<>(data, headers);
            }
        }
        private TokenRequest(){
        }
    }
    

    【讨论】:

      【解决方案2】:

      试试这个:

      HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
          KeycloakAuthenticationToken keycloakAuthenticationToken = (KeycloakAuthenticationToken) request.getUserPrincipal();
          KeycloakPrincipal<KeycloakSecurityContext> principal = (KeycloakPrincipal) keycloakAuthenticationToken.getPrincipal();
          String token = principal.getKeycloakSecurityContext().getIdTokenString();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-13
        • 2022-10-13
        • 2018-07-09
        • 2020-10-02
        • 2017-06-23
        • 1970-01-01
        • 1970-01-01
        • 2021-03-21
        相关资源
        最近更新 更多