Perform internal introspect for the access token in the account app
Closes #27243 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
004805e21d
commit
562decde35
3 changed files with 77 additions and 6 deletions
|
@ -61,6 +61,7 @@ public class AccessTokenIntrospectionProvider implements TokenIntrospectionProvi
|
|||
this.tokenManager = new TokenManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response introspect(String token, EventBuilder eventBuilder) {
|
||||
AccessToken accessToken = null;
|
||||
try {
|
||||
|
@ -123,7 +124,7 @@ public class AccessTokenIntrospectionProvider implements TokenIntrospectionProvi
|
|||
}
|
||||
}
|
||||
|
||||
private AccessToken transformAccessToken(AccessToken token) {
|
||||
public AccessToken transformAccessToken(AccessToken token) {
|
||||
if (token == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.keycloak.services.resources.account;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.http.HttpRequest;
|
||||
import org.keycloak.http.HttpResponse;
|
||||
import org.keycloak.common.enums.AccountRestApiVersion;
|
||||
|
@ -26,6 +25,10 @@ import org.keycloak.models.ClientModel;
|
|||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.protocol.oidc.AccessTokenIntrospectionProvider;
|
||||
import org.keycloak.protocol.oidc.AccessTokenIntrospectionProviderFactory;
|
||||
import org.keycloak.protocol.oidc.TokenIntrospectionProvider;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.services.cors.Cors;
|
||||
import org.keycloak.services.managers.AppAuthManager;
|
||||
import org.keycloak.services.managers.Auth;
|
||||
|
@ -109,16 +112,26 @@ public class AccountLoader {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private AccountRestService getAccountRestService(ClientModel client, String versionStr) {
|
||||
AuthenticationManager.AuthResult authResult = new AppAuthManager.BearerTokenAuthenticator(session)
|
||||
.setAudience(client.getClientId())
|
||||
.authenticate();
|
||||
|
||||
if (authResult == null) {
|
||||
throw new NotAuthorizedException("Bearer token required");
|
||||
}
|
||||
Auth auth = new Auth(session.getContext().getRealm(), authResult.getToken(), authResult.getUser(), client, authResult.getSession(), false);
|
||||
|
||||
AccessToken accessToken = authResult.getToken();
|
||||
if (accessToken.getAudience() == null || accessToken.getResourceAccess(client.getClientId()) == null) {
|
||||
// transform for introspection to get the required claims
|
||||
AccessTokenIntrospectionProvider provider = (AccessTokenIntrospectionProvider) session.getProvider(TokenIntrospectionProvider.class,
|
||||
AccessTokenIntrospectionProviderFactory.ACCESS_TOKEN_TYPE);
|
||||
accessToken = provider.transformAccessToken(accessToken);
|
||||
}
|
||||
|
||||
if (!accessToken.hasAudience(client.getClientId())) {
|
||||
throw new NotAuthorizedException("Invalid audience for client " + client.getClientId());
|
||||
}
|
||||
|
||||
Auth auth = new Auth(session.getContext().getRealm(), accessToken, authResult.getUser(), client, authResult.getSession(), false);
|
||||
|
||||
Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2024 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.testsuite.account;
|
||||
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.ClientPoliciesRepresentation;
|
||||
import org.keycloak.representations.idm.ClientPolicyConditionConfigurationRepresentation;
|
||||
import org.keycloak.representations.idm.ClientProfilesRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.clientpolicy.condition.AnyClientConditionFactory;
|
||||
import org.keycloak.services.clientpolicy.executor.UseLightweightAccessTokenExecutorFactory;
|
||||
import org.keycloak.testsuite.util.ClientPoliciesUtil.ClientPoliciesBuilder;
|
||||
import org.keycloak.testsuite.util.ClientPoliciesUtil.ClientPolicyBuilder;
|
||||
import org.keycloak.testsuite.util.ClientPoliciesUtil.ClientProfileBuilder;
|
||||
import org.keycloak.testsuite.util.ClientPoliciesUtil.ClientProfilesBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author rmartinc
|
||||
*/
|
||||
public class AccountRestServiceLightweightTokenTest extends AccountRestServiceTest {
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
super.configureTestRealm(testRealm);
|
||||
|
||||
try {
|
||||
// enable lightweight tokens for any client in the realm
|
||||
ClientProfilesRepresentation profiles = new ClientProfilesBuilder().addProfile(
|
||||
new ClientProfileBuilder().createProfile("enable lightweight tokens", "Profile Lightweight Tokens")
|
||||
.addExecutor(UseLightweightAccessTokenExecutorFactory.PROVIDER_ID, null).toRepresentation()).toRepresentation();
|
||||
ClientPoliciesRepresentation policies = new ClientPoliciesBuilder().addPolicy(
|
||||
new ClientPolicyBuilder().createPolicy("enable lightweight tokens", "Policy Lightweight Tokens", true)
|
||||
.addCondition(AnyClientConditionFactory.PROVIDER_ID, new ClientPolicyConditionConfigurationRepresentation())
|
||||
.addProfile("enable lightweight tokens")
|
||||
.toRepresentation()).toRepresentation();
|
||||
testRealm.setParsedClientProfiles(profiles);
|
||||
testRealm.setParsedClientPolicies(policies);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue