midi
midi

Reputation: 4078

How to get Access Token from Keycloak over SpringBoot?

I'm trying to get an Access Token from Keycloak over SpringBoot and did try the following example. But the KeycloakAuthenticationToken token is null.

Does someone know another approach to get an Access 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;
}

Seems like I can get a token like this with ('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();

If someone knows a more elegant way, I would appreciate if you let me know :)

Thanks in advance!

Upvotes: 1

Views: 8189

Answers (2)

Terrence Munyunguma
Terrence Munyunguma

Reputation: 156

Try this:

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

Upvotes: 0

dreamcrash
dreamcrash

Reputation: 51543

Try the following:

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();

and the helper class:

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(){
    }
}

Upvotes: 5

Related Questions