parent
a56b38c5a6
commit
96c1cf3c49
4 changed files with 30 additions and 13 deletions
|
@ -38,7 +38,7 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, OIDCAccessTokenResponseMapper {
|
public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, OIDCAccessTokenResponseMapper, UserInfoTokenMapper {
|
||||||
|
|
||||||
private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
|
private static final List<ProviderConfigProperty> configProperties = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -102,6 +102,13 @@ public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements
|
||||||
String userSessionNote,
|
String userSessionNote,
|
||||||
String tokenClaimName, String jsonType,
|
String tokenClaimName, String jsonType,
|
||||||
boolean accessToken, boolean idToken) {
|
boolean accessToken, boolean idToken) {
|
||||||
|
return createClaimMapper(name, userSessionNote, tokenClaimName, jsonType, accessToken, idToken, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProtocolMapperModel createClaimMapper(String name,
|
||||||
|
String userSessionNote,
|
||||||
|
String tokenClaimName, String jsonType,
|
||||||
|
boolean accessToken, boolean idToken, boolean userInfo) {
|
||||||
ProtocolMapperModel mapper = new ProtocolMapperModel();
|
ProtocolMapperModel mapper = new ProtocolMapperModel();
|
||||||
mapper.setName(name);
|
mapper.setName(name);
|
||||||
mapper.setProtocolMapper(PROVIDER_ID);
|
mapper.setProtocolMapper(PROVIDER_ID);
|
||||||
|
@ -112,6 +119,7 @@ public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements
|
||||||
config.put(OIDCAttributeMapperHelper.JSON_TYPE, jsonType);
|
config.put(OIDCAttributeMapperHelper.JSON_TYPE, jsonType);
|
||||||
if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
|
if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
|
||||||
if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
|
if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
|
||||||
|
if (userInfo) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true");
|
||||||
mapper.setConfig(config);
|
mapper.setConfig(config);
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,10 @@
|
||||||
|
|
||||||
package org.keycloak.testsuite.federation.kerberos;
|
package org.keycloak.testsuite.federation.kerberos;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.ws.rs.client.Entity;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import org.ietf.jgss.GSSCredential;
|
import org.ietf.jgss.GSSCredential;
|
||||||
|
@ -40,16 +37,16 @@ import org.keycloak.models.ProtocolMapperModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
|
import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
|
import org.keycloak.representations.UserInfo;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.storage.UserStorageProvider;
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.testsuite.ActionURIUtils;
|
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.admin.ApiUtil;
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
|
||||||
import org.keycloak.testsuite.util.AccountHelper;
|
import org.keycloak.testsuite.util.AccountHelper;
|
||||||
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.TestAppHelper;
|
import org.keycloak.testsuite.util.TestAppHelper;
|
||||||
|
|
||||||
import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId;
|
import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId;
|
||||||
|
@ -186,7 +183,7 @@ public abstract class AbstractKerberosSingleRealmTest extends AbstractKerberosTe
|
||||||
ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
|
ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME,
|
||||||
KerberosConstants.GSS_DELEGATION_CREDENTIAL,
|
KerberosConstants.GSS_DELEGATION_CREDENTIAL,
|
||||||
KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String",
|
KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String",
|
||||||
true, false);
|
true, false, true);
|
||||||
ProtocolMapperRepresentation protocolMapperRep = ModelToRepresentation.toRepresentation(protocolMapper);
|
ProtocolMapperRepresentation protocolMapperRep = ModelToRepresentation.toRepresentation(protocolMapper);
|
||||||
ClientResource clientResource = findClientByClientId(testRealmResource(), "kerberos-app");
|
ClientResource clientResource = findClientByClientId(testRealmResource(), "kerberos-app");
|
||||||
Response response = clientResource.getProtocolMappers().createMapper(protocolMapperRep);
|
Response response = clientResource.getProtocolMappers().createMapper(protocolMapperRep);
|
||||||
|
@ -194,7 +191,8 @@ public abstract class AbstractKerberosSingleRealmTest extends AbstractKerberosTe
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
// SPNEGO login
|
// SPNEGO login
|
||||||
AccessToken token = assertSuccessfulSpnegoLogin("hnelson", "hnelson", "secret");
|
OAuthClient.AccessTokenResponse tokenResponse = assertSuccessfulSpnegoLogin("hnelson", "hnelson", "secret");
|
||||||
|
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
|
||||||
|
|
||||||
// Assert kerberos ticket in the accessToken can be re-used to authenticate against other 3rd party kerberos service (ApacheDS Server in this case)
|
// Assert kerberos ticket in the accessToken can be re-used to authenticate against other 3rd party kerberos service (ApacheDS Server in this case)
|
||||||
String serializedGssCredential = (String) token.getOtherClaims().get(KerberosConstants.GSS_DELEGATION_CREDENTIAL);
|
String serializedGssCredential = (String) token.getOtherClaims().get(KerberosConstants.GSS_DELEGATION_CREDENTIAL);
|
||||||
|
@ -203,6 +201,12 @@ public abstract class AbstractKerberosSingleRealmTest extends AbstractKerberosTe
|
||||||
String ldapResponse = invokeLdap(gssCredential, token.getPreferredUsername());
|
String ldapResponse = invokeLdap(gssCredential, token.getPreferredUsername());
|
||||||
Assert.assertEquals("Horatio Nelson", ldapResponse);
|
Assert.assertEquals("Horatio Nelson", ldapResponse);
|
||||||
|
|
||||||
|
// Assert kerberos ticket also in userinfo endpoint
|
||||||
|
UserInfo userInfo = oauth.doUserInfoRequest(tokenResponse.getAccessToken());
|
||||||
|
Assert.assertEquals(serializedGssCredential, userInfo.getOtherClaims().get(KerberosConstants.GSS_DELEGATION_CREDENTIAL));
|
||||||
|
// Clear USER_INFO_REQUEST event
|
||||||
|
events.poll();
|
||||||
|
|
||||||
// Logout
|
// Logout
|
||||||
oauth.openLogout();
|
oauth.openLogout();
|
||||||
events.poll();
|
events.poll();
|
||||||
|
@ -211,8 +215,11 @@ public abstract class AbstractKerberosSingleRealmTest extends AbstractKerberosTe
|
||||||
clientResource.getProtocolMappers().delete(protocolMapperId);
|
clientResource.getProtocolMappers().delete(protocolMapperId);
|
||||||
|
|
||||||
// Login and assert delegated credential not anymore
|
// Login and assert delegated credential not anymore
|
||||||
token = assertSuccessfulSpnegoLogin("hnelson", "hnelson", "secret");
|
tokenResponse = assertSuccessfulSpnegoLogin("hnelson", "hnelson", "secret");
|
||||||
|
token = oauth.verifyToken(tokenResponse.getAccessToken());
|
||||||
Assert.assertFalse(token.getOtherClaims().containsKey(KerberosConstants.GSS_DELEGATION_CREDENTIAL));
|
Assert.assertFalse(token.getOtherClaims().containsKey(KerberosConstants.GSS_DELEGATION_CREDENTIAL));
|
||||||
|
userInfo = oauth.doUserInfoRequest(tokenResponse.getAccessToken());
|
||||||
|
Assert.assertFalse(userInfo.getOtherClaims().containsKey(KerberosConstants.GSS_DELEGATION_CREDENTIAL));
|
||||||
|
|
||||||
events.clear();
|
events.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,11 +179,11 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
protected AccessToken assertSuccessfulSpnegoLogin(String loginUsername, String expectedUsername, String password) throws Exception {
|
protected OAuthClient.AccessTokenResponse assertSuccessfulSpnegoLogin(String loginUsername, String expectedUsername, String password) throws Exception {
|
||||||
return assertSuccessfulSpnegoLogin("kerberos-app", loginUsername, expectedUsername, password);
|
return assertSuccessfulSpnegoLogin("kerberos-app", loginUsername, expectedUsername, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AccessToken assertSuccessfulSpnegoLogin(String clientId, String loginUsername, String expectedUsername, String password) throws Exception {
|
protected OAuthClient.AccessTokenResponse assertSuccessfulSpnegoLogin(String clientId, String loginUsername, String expectedUsername, String password) throws Exception {
|
||||||
oauth.clientId(clientId);
|
oauth.clientId(clientId);
|
||||||
Response spnegoResponse = spnegoLogin(loginUsername, password);
|
Response spnegoResponse = spnegoLogin(loginUsername, password);
|
||||||
Assert.assertEquals(302, spnegoResponse.getStatus());
|
Assert.assertEquals(302, spnegoResponse.getStatus());
|
||||||
|
@ -206,7 +206,7 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
|
||||||
|
|
||||||
oauth.idTokenHint(tokenResponse.getIdToken());
|
oauth.idTokenHint(tokenResponse.getIdToken());
|
||||||
|
|
||||||
return token;
|
return tokenResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.keycloak.storage.ldap.kerberos.LDAPProviderKerberosConfig;
|
||||||
import org.keycloak.testsuite.Assert;
|
import org.keycloak.testsuite.Assert;
|
||||||
import org.keycloak.testsuite.util.KerberosRule;
|
import org.keycloak.testsuite.util.KerberosRule;
|
||||||
import org.keycloak.testsuite.KerberosEmbeddedServer;
|
import org.keycloak.testsuite.KerberosEmbeddedServer;
|
||||||
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
@ -67,7 +68,8 @@ public class KerberosLdapCrossRealmTrustTest extends AbstractKerberosTest {
|
||||||
@Test
|
@Test
|
||||||
public void test01SpnegoLoginCRTSuccess() throws Exception {
|
public void test01SpnegoLoginCRTSuccess() throws Exception {
|
||||||
// Login as user from realm KC2.COM . Realm KEYCLOAK.ORG will trust us
|
// Login as user from realm KC2.COM . Realm KEYCLOAK.ORG will trust us
|
||||||
AccessToken token = assertSuccessfulSpnegoLogin("hnelson2@KC2.COM", "hnelson2", "secret");
|
OAuthClient.AccessTokenResponse tokenResponse = assertSuccessfulSpnegoLogin("hnelson2@KC2.COM", "hnelson2", "secret");
|
||||||
|
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
|
||||||
|
|
||||||
Assert.assertEquals(token.getEmail(), "hnelson2@kc2.com");
|
Assert.assertEquals(token.getEmail(), "hnelson2@kc2.com");
|
||||||
assertUser("hnelson2", "hnelson2@kc2.com", "Horatio", "Nelson", false);
|
assertUser("hnelson2", "hnelson2@kc2.com", "Horatio", "Nelson", false);
|
||||||
|
|
Loading…
Reference in a new issue