Search in sources :

Example 71 with AccessToken

use of org.keycloak.representations.AccessToken in project keycloak by keycloak.

the class TestingOIDCEndpointsApplicationResource method requestAuthenticationChannel.

@POST
@Path("/request-authentication-channel")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public Response requestAuthenticationChannel(@Context HttpHeaders headers, AuthenticationChannelRequest request) {
    String rawBearerToken = AppAuthManager.extractAuthorizationHeaderToken(headers);
    AccessToken bearerToken;
    try {
        bearerToken = new JWSInput(rawBearerToken).readJsonContent(AccessToken.class);
    } catch (JWSInputException e) {
        throw new RuntimeException("Failed to parse bearer token", e);
    }
    // required
    String authenticationChannelId = bearerToken.getId();
    if (authenticationChannelId == null)
        throw new BadRequestException("missing parameter : " + HttpAuthenticationChannelProvider.AUTHENTICATION_CHANNEL_ID);
    String loginHint = request.getLoginHint();
    if (loginHint == null)
        throw new BadRequestException("missing parameter : " + CibaGrantType.LOGIN_HINT);
    if (request.getConsentRequired() == null)
        throw new BadRequestException("missing parameter : " + CibaGrantType.IS_CONSENT_REQUIRED);
    String scope = request.getScope();
    if (scope == null)
        throw new BadRequestException("missing parameter : " + OAuth2Constants.SCOPE);
    // optional
    // for testing purpose
    String bindingMessage = request.getBindingMessage();
    if (bindingMessage != null && bindingMessage.equals("GODOWN"))
        throw new BadRequestException("intentional error : GODOWN");
    // only one CIBA flow without binding_message can be accepted per test method by this test mechanism.
    if (bindingMessage == null)
        bindingMessage = ChannelRequestDummyKey;
    authenticationChannelRequests.put(bindingMessage, new TestAuthenticationChannelRequest(request, rawBearerToken));
    return Response.status(Status.CREATED).build();
}
Also used : AccessToken(org.keycloak.representations.AccessToken) JWSInputException(org.keycloak.jose.jws.JWSInputException) BadRequestException(javax.ws.rs.BadRequestException) JWSInput(org.keycloak.jose.jws.JWSInput) TestAuthenticationChannelRequest(org.keycloak.testsuite.rest.representation.TestAuthenticationChannelRequest) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) NoCache(org.jboss.resteasy.annotations.cache.NoCache)

Example 72 with AccessToken

use of org.keycloak.representations.AccessToken in project keycloak by keycloak.

the class AbstractMigrationTest method testCredentialsMigratedToNewFormat.

protected void testCredentialsMigratedToNewFormat() {
    log.info("testing user's credentials migrated to new format with secretData and credentialData");
    // Try to login with password+otp after the migration
    try {
        oauth.realm(MIGRATION);
        oauth.clientId("migration-test-client");
        TimeBasedOTP otpGenerator = new TimeBasedOTP("HmacSHA1", 8, 40, 1);
        String otp = otpGenerator.generateTOTP("dSdmuHLQhkm54oIm0A0S");
        // Try invalid password first
        OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", "migration-test-user", "password", otp);
        Assert.assertNull(response.getAccessToken());
        Assert.assertNotNull(response.getError());
        // Try invalid OTP then
        response = oauth.doGrantAccessTokenRequest("secret", "migration-test-user", "password2", "invalid");
        Assert.assertNull(response.getAccessToken());
        Assert.assertNotNull(response.getError());
        // Try successful login now
        response = oauth.doGrantAccessTokenRequest("secret", "migration-test-user", "password2", otp);
        Assert.assertNull(response.getError());
        AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
        assertEquals("migration-test-user", accessToken.getPreferredUsername());
    } catch (Exception e) {
        throw new AssertionError("Failed to login with user 'migration-test-user' after migration", e);
    }
}
Also used : TimeBasedOTP(org.keycloak.models.utils.TimeBasedOTP) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) IOException(java.io.IOException)

Example 73 with AccessToken

use of org.keycloak.representations.AccessToken in project keycloak by keycloak.

the class TransientSessionTest method loginSuccess.

@Test
public void loginSuccess() throws Exception {
    setUpDirectGrantFlowWithSetClientNoteAuthenticator();
    oauth.clientId("direct-grant");
    // Signal that we want userSession to be transient
    oauth.addCustomParameter(SetClientNoteAuthenticator.PREFIX + AuthenticationManager.USER_SESSION_PERSISTENT_STATE, UserSessionModel.SessionPersistenceState.TRANSIENT.toString());
    OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
    assertEquals(200, response.getStatusCode());
    AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
    RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
    // sessionState is available, but the session was transient and hence not really persisted on the server
    assertNotNull(accessToken.getSessionState());
    assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
    // Refresh will fail. There is no userSession on the server
    OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
    Assert.assertNull(refreshedResponse.getAccessToken());
    assertNotNull(refreshedResponse.getError());
    Assert.assertEquals("Session not active", refreshedResponse.getErrorDescription());
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 74 with AccessToken

use of org.keycloak.representations.AccessToken in project keycloak by keycloak.

the class HoKTest method refreshTokenRequestByHoKRefreshTokenWithClientCertificate.

@Test
public void refreshTokenRequestByHoKRefreshTokenWithClientCertificate() throws Exception {
    oauth.doLogin("test-user@localhost", "password");
    EventRepresentation loginEvent = events.expectLogin().assertEvent();
    String sessionId = loginEvent.getSessionId();
    String codeId = loginEvent.getDetails().get(Details.CODE_ID);
    String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
    AccessTokenResponse tokenResponse = null;
    try (CloseableHttpClient client = MutualTLSUtils.newCloseableHttpClientWithDefaultKeyStoreAndTrustStore()) {
        tokenResponse = oauth.doAccessTokenRequest(code, "password", client);
    } catch (IOException ioe) {
        throw new RuntimeException(ioe);
    }
    verifyHoKTokenDefaultCertThumbPrint(tokenResponse);
    AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
    String refreshTokenString = tokenResponse.getRefreshToken();
    RefreshToken refreshToken = oauth.parseRefreshToken(refreshTokenString);
    EventRepresentation tokenEvent = events.expectCodeToToken(codeId, sessionId).assertEvent();
    Assert.assertNotNull(refreshTokenString);
    assertEquals("Bearer", tokenResponse.getTokenType());
    Assert.assertThat(token.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(200), lessThanOrEqualTo(350)));
    int actual = refreshToken.getExpiration() - getCurrentTime();
    Assert.assertThat(actual, allOf(greaterThanOrEqualTo(1799 - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800 + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
    assertEquals(sessionId, refreshToken.getSessionState());
    setTimeOffset(2);
    AccessTokenResponse response = null;
    try (CloseableHttpClient client = MutualTLSUtils.newCloseableHttpClientWithDefaultKeyStoreAndTrustStore()) {
        response = oauth.doRefreshTokenRequest(refreshTokenString, "password", client);
    } catch (IOException ioe) {
        throw new RuntimeException(ioe);
    }
    // Success Pattern
    expectSuccessfulResponseFromTokenEndpoint(response, sessionId, token, refreshToken, tokenEvent);
    verifyHoKTokenDefaultCertThumbPrint(response);
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) RefreshToken(org.keycloak.representations.RefreshToken) AccessToken(org.keycloak.representations.AccessToken) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) IOException(java.io.IOException) AccessTokenResponse(org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse) RefreshTokenTest(org.keycloak.testsuite.oauth.RefreshTokenTest) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 75 with AccessToken

use of org.keycloak.representations.AccessToken in project keycloak by keycloak.

the class TokenEndpoint method permissionGrant.

public Response permissionGrant() {
    event.detail(Details.AUTH_METHOD, "oauth_credentials");
    String accessTokenString = null;
    String authorizationHeader = headers.getRequestHeaders().getFirst(HttpHeaders.AUTHORIZATION);
    if (authorizationHeader != null && authorizationHeader.toLowerCase().startsWith("bearer")) {
        accessTokenString = new AppAuthManager().extractAuthorizationHeaderToken(headers);
    }
    // public clients don't have secret and should be able to obtain a RPT by providing an access token previously issued by the server
    if (accessTokenString != null) {
        AccessToken accessToken = Tokens.getAccessToken(session);
        if (accessToken == null) {
            try {
                // In case the access token is invalid because it's expired or the user is disabled, identify the client
                // from the access token anyway in order to set correct CORS headers.
                AccessToken invalidToken = new JWSInput(accessTokenString).readJsonContent(AccessToken.class);
                ClientModel client = realm.getClientByClientId(invalidToken.getIssuedFor());
                cors.allowedOrigins(session, client);
                event.client(client);
            } catch (JWSInputException ignore) {
            }
            event.error(Errors.INVALID_TOKEN);
            throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Invalid bearer token", Status.UNAUTHORIZED);
        }
        ClientModel client = realm.getClientByClientId(accessToken.getIssuedFor());
        session.getContext().setClient(client);
        cors.allowedOrigins(session, client);
        event.client(client);
    }
    String claimToken = null;
    // claim_token is optional, if provided we just grab it from the request
    if (formParams.containsKey("claim_token")) {
        claimToken = formParams.get("claim_token").get(0);
    }
    String claimTokenFormat = formParams.getFirst("claim_token_format");
    if (claimToken != null && claimTokenFormat == null) {
        claimTokenFormat = AuthorizationTokenService.CLAIM_TOKEN_FORMAT_ID_TOKEN;
    }
    String subjectToken = formParams.getFirst("subject_token");
    if (accessTokenString == null) {
        // in case no bearer token is provided, we force client authentication
        checkClient();
        // if a claim token is provided, we check if the format is a OpenID Connect IDToken and assume the token represents the identity asking for permissions
        if (AuthorizationTokenService.CLAIM_TOKEN_FORMAT_ID_TOKEN.equalsIgnoreCase(claimTokenFormat)) {
            accessTokenString = claimToken;
        } else if (subjectToken != null) {
            accessTokenString = subjectToken;
        } else {
            // Clients need to authenticate in order to obtain a RPT from the server.
            // In order to support cases where the client is obtaining permissions on its on behalf, we issue a temporary access token
            accessTokenString = AccessTokenResponse.class.cast(clientCredentialsGrant().getEntity()).getToken();
        }
    }
    AuthorizationTokenService.KeycloakAuthorizationRequest authorizationRequest = new AuthorizationTokenService.KeycloakAuthorizationRequest(session.getProvider(AuthorizationProvider.class), tokenManager, event, this.request, cors, clientConnection);
    authorizationRequest.setTicket(formParams.getFirst("ticket"));
    authorizationRequest.setClaimToken(claimToken);
    authorizationRequest.setClaimTokenFormat(claimTokenFormat);
    authorizationRequest.setPct(formParams.getFirst("pct"));
    String rpt = formParams.getFirst("rpt");
    if (rpt != null) {
        AccessToken accessToken = session.tokens().decode(rpt, AccessToken.class);
        if (accessToken == null) {
            event.error(Errors.INVALID_REQUEST);
            throw new CorsErrorResponseException(cors, "invalid_rpt", "RPT signature is invalid", Status.FORBIDDEN);
        }
        authorizationRequest.setRpt(accessToken);
    }
    authorizationRequest.setScope(formParams.getFirst("scope"));
    String audienceParam = formParams.getFirst("audience");
    authorizationRequest.setAudience(audienceParam);
    authorizationRequest.setSubjectToken(accessTokenString);
    event.detail(Details.AUDIENCE, audienceParam);
    String submitRequest = formParams.getFirst("submit_request");
    authorizationRequest.setSubmitRequest(submitRequest == null ? true : Boolean.valueOf(submitRequest));
    // permissions have a format like RESOURCE#SCOPE1,SCOPE2
    List<String> permissions = formParams.get("permission");
    if (permissions != null) {
        event.detail(Details.PERMISSION, String.join("|", permissions));
        for (String permission : permissions) {
            String[] parts = permission.split("#");
            String resource = parts[0];
            if (parts.length == 1) {
                authorizationRequest.addPermission(resource);
            } else {
                String[] scopes = parts[1].split(",");
                authorizationRequest.addPermission(parts[0], scopes);
            }
        }
    }
    Metadata metadata = new Metadata();
    String responseIncludeResourceName = formParams.getFirst("response_include_resource_name");
    if (responseIncludeResourceName != null) {
        metadata.setIncludeResourceName(Boolean.parseBoolean(responseIncludeResourceName));
    }
    String responsePermissionsLimit = formParams.getFirst("response_permissions_limit");
    if (responsePermissionsLimit != null) {
        metadata.setLimit(Integer.parseInt(responsePermissionsLimit));
    }
    metadata.setResponseMode(formParams.getFirst("response_mode"));
    authorizationRequest.setMetadata(metadata);
    Response authorizationResponse = AuthorizationTokenService.instance().authorize(authorizationRequest);
    event.success();
    return authorizationResponse;
}
Also used : AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) Metadata(org.keycloak.representations.idm.authorization.AuthorizationRequest.Metadata) JWSInputException(org.keycloak.jose.jws.JWSInputException) JWSInput(org.keycloak.jose.jws.JWSInput) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) Response(javax.ws.rs.core.Response) HttpResponse(org.jboss.resteasy.spi.HttpResponse) ClientModel(org.keycloak.models.ClientModel) AuthorizationTokenService(org.keycloak.authorization.authorization.AuthorizationTokenService) AccessToken(org.keycloak.representations.AccessToken) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) AppAuthManager(org.keycloak.services.managers.AppAuthManager)

Aggregations

AccessToken (org.keycloak.representations.AccessToken)230 Test (org.junit.Test)129 OAuthClient (org.keycloak.testsuite.util.OAuthClient)104 AbstractKeycloakTest (org.keycloak.testsuite.AbstractKeycloakTest)54 RefreshToken (org.keycloak.representations.RefreshToken)45 AuthorizationResponse (org.keycloak.representations.idm.authorization.AuthorizationResponse)37 JWSInput (org.keycloak.jose.jws.JWSInput)29 Permission (org.keycloak.representations.idm.authorization.Permission)28 EventRepresentation (org.keycloak.representations.idm.EventRepresentation)27 Response (javax.ws.rs.core.Response)26 ClientResource (org.keycloak.admin.client.resource.ClientResource)22 VerificationException (org.keycloak.common.VerificationException)19 ClientRepresentation (org.keycloak.representations.idm.ClientRepresentation)19 AccessTokenResponse (org.keycloak.representations.AccessTokenResponse)18 IDToken (org.keycloak.representations.IDToken)18 AuthorizationRequest (org.keycloak.representations.idm.authorization.AuthorizationRequest)17 IOException (java.io.IOException)15 AuthzClient (org.keycloak.authorization.client.AuthzClient)15 ResourceRepresentation (org.keycloak.representations.idm.authorization.ResourceRepresentation)14 ArrayList (java.util.ArrayList)13