mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 15:02:05 -03:30
Persistent user session for client scopes evaluate function
Closes #37202 Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
This commit is contained in:
parent
603ecf20eb
commit
5505f26cf8
@ -165,6 +165,9 @@ public interface ClientResource {
|
||||
@Path("/roles")
|
||||
RolesResource roles();
|
||||
|
||||
@Path("/evaluate-scopes")
|
||||
ClientScopeEvaluateResource clientScopesEvaluate();
|
||||
|
||||
/**
|
||||
* Get default client scopes. Only name and ids are returned.
|
||||
*
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2025 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.admin.client.resource;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.IDToken;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:ggrazian@redhat.com">Giuseppe Graziano</a>
|
||||
*/
|
||||
public interface ClientScopeEvaluateResource {
|
||||
|
||||
@GET
|
||||
@Path("generate-example-access-token")
|
||||
AccessToken generateAccessToken(@QueryParam("scope") String scopeParam, @QueryParam("userId") String userId, @QueryParam("audience") String audience);
|
||||
|
||||
@GET
|
||||
@Path("generate-example-id-token")
|
||||
IDToken generateExampleIdToken(@QueryParam("scope") String scopeParam, @QueryParam("userId") String userId, @QueryParam("audience") String audience);
|
||||
|
||||
|
||||
@GET
|
||||
@Path("generate-example-userinfo")
|
||||
Map<String, Object> generateExampleUserinfo(@QueryParam("scope") String scopeParam, @QueryParam("userId") String userId);
|
||||
|
||||
}
|
||||
@ -274,6 +274,7 @@ public class ClientScopeEvaluateResource {
|
||||
|
||||
private<R> R sessionAware(UserModel user, String scopeParam, String audienceParam, TriFunction<UserSessionModel, ClientSessionContext, ClientModel[], R> function) {
|
||||
AuthenticationSessionModel authSession = null;
|
||||
UserSessionModel userSession = null;
|
||||
AuthenticationSessionManager authSessionManager = new AuthenticationSessionManager(session);
|
||||
|
||||
try {
|
||||
@ -285,8 +286,8 @@ public class ClientScopeEvaluateResource {
|
||||
authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
|
||||
authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, scopeParam);
|
||||
|
||||
UserSessionModel userSession = new UserSessionManager(session).createUserSession(authSession.getParentSession().getId(), realm, user, user.getUsername(),
|
||||
clientConnection.getRemoteHost(), "example-auth", false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT);
|
||||
userSession = new UserSessionManager(session).createUserSession(authSession.getParentSession().getId(), realm, user, user.getUsername(),
|
||||
clientConnection.getRemoteHost(), "example-auth", false, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT);
|
||||
|
||||
AuthenticationManager.setClientScopesInSession(session, authSession);
|
||||
ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession);
|
||||
@ -302,6 +303,9 @@ public class ClientScopeEvaluateResource {
|
||||
if (authSession != null) {
|
||||
authSessionManager.removeAuthenticationSession(realm, authSession, false);
|
||||
}
|
||||
if (userSession != null) {
|
||||
session.sessions().removeUserSession(realm, userSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2025 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* 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.admin.client;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.IDToken;
|
||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:ggrazian@redhat.com">Giuseppe Graziano</a>
|
||||
*/
|
||||
public class ClientScopeEvaluateTest extends AbstractClientTest {
|
||||
|
||||
private ClientResource accountClient;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
accountClient = findClientResourceById("account");
|
||||
createTestUserWithAdminClient();
|
||||
getCleanup().addUserId(testUser.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateAccessToken() {
|
||||
AccessToken accessToken = accountClient.clientScopesEvaluate().generateAccessToken("openid", testUser.getId(), null);
|
||||
assertNotNull(accessToken);
|
||||
assertNotNull(accessToken.getSubject());
|
||||
assertNotNull(accessToken.getPreferredUsername());
|
||||
|
||||
List<UserSessionRepresentation> sessions = accountClient.getUserSessions(0, 5);
|
||||
assertEquals(0, sessions.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateIdToken() {
|
||||
IDToken idToken = accountClient.clientScopesEvaluate().generateExampleIdToken("openid", testUser.getId(), null);
|
||||
assertNotNull(idToken);
|
||||
assertNotNull(idToken.getSubject());
|
||||
assertNotNull(idToken.getPreferredUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateUserInfo() {
|
||||
Map<String, Object> userinfo = accountClient.clientScopesEvaluate().generateExampleUserinfo("openid", testUser.getId());
|
||||
assertFalse(userinfo.isEmpty());
|
||||
assertNotNull(userinfo.get(IDToken.SUBJECT));
|
||||
assertNotNull(userinfo.get(IDToken.PREFERRED_USERNAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateAccessTokenWithoutBasicScope() {
|
||||
String basicScopeId = ApiUtil.findClientScopeByName(testRealmResource(),"basic").toRepresentation().getId();
|
||||
accountClient.removeDefaultClientScope(basicScopeId);
|
||||
|
||||
AccessToken accessToken = accountClient.clientScopesEvaluate().generateAccessToken("openid", testUser.getId(), null);
|
||||
assertNotNull(accessToken);
|
||||
assertNull(accessToken.getSubject());
|
||||
|
||||
accountClient.addDefaultClientScope(basicScopeId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateAccessTokenWithOptionalScope() {
|
||||
String emailScopeId = ApiUtil.findClientScopeByName(testRealmResource(),"email").toRepresentation().getId();
|
||||
accountClient.removeDefaultClientScope(emailScopeId);
|
||||
accountClient.addOptionalClientScope(emailScopeId);
|
||||
|
||||
AccessToken accessToken = accountClient.clientScopesEvaluate().generateAccessToken("openid", testUser.getId(), null);
|
||||
assertNotNull(accessToken);
|
||||
assertNull(accessToken.getEmail());
|
||||
|
||||
accessToken = accountClient.clientScopesEvaluate().generateAccessToken("openid email", testUser.getId(), null);
|
||||
assertNotNull(accessToken);
|
||||
assertNotNull(accessToken.getEmail());
|
||||
|
||||
accountClient.removeOptionalClientScope(emailScopeId);
|
||||
accountClient.addDefaultClientScope(emailScopeId);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user