use of org.keycloak.dom.saml.v2.assertion.NameIDType in project keycloak by keycloak.
the class SAMLSloRequestParser method processSubElement.
@Override
protected void processSubElement(XMLEventReader xmlEventReader, LogoutRequestType target, SAMLProtocolQNames element, StartElement elementDetail) throws ParsingException {
switch(element) {
case ISSUER:
case SIGNATURE:
case EXTENSIONS:
parseCommonElements(element, elementDetail, xmlEventReader, target);
break;
case NAMEID:
NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
target.setNameID(nameID);
break;
case ENCRYPTED_ID:
Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
target.setEncryptedID(new EncryptedElementType(domElement));
break;
case SESSION_INDEX:
StaxParserUtil.getNextStartElement(xmlEventReader);
target.addSessionIndex(StaxParserUtil.getElementText(xmlEventReader));
break;
default:
throw LOGGER.parserUnknownTag(StaxParserUtil.getElementName(elementDetail), elementDetail.getLocation());
}
}
use of org.keycloak.dom.saml.v2.assertion.NameIDType in project keycloak by keycloak.
the class SAMLSubjectConfirmationParser method processSubElement.
@Override
protected void processSubElement(XMLEventReader xmlEventReader, SubjectConfirmationType target, SAMLAssertionQNames element, StartElement elementDetail) throws ParsingException {
switch(element) {
case NAMEID:
NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
target.setNameID(nameID);
break;
case ENCRYPTED_ID:
Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
target.setEncryptedID(new EncryptedElementType(domElement));
break;
case SUBJECT_CONFIRMATION_DATA:
SubjectConfirmationDataType subjectConfirmationData = SAMLSubjectConfirmationDataParser.INSTANCE.parse(xmlEventReader);
target.setSubjectConfirmationData(subjectConfirmationData);
break;
default:
throw LOGGER.parserUnknownTag(StaxParserUtil.getElementName(elementDetail), elementDetail.getLocation());
}
}
use of org.keycloak.dom.saml.v2.assertion.NameIDType in project keycloak by keycloak.
the class ClientTokenExchangeSAML2Test method testExchangeToSAML2SignedAndEncryptedAssertion.
@Test
@UncaughtServerErrorExpected
public void testExchangeToSAML2SignedAndEncryptedAssertion() throws Exception {
testingClient.server().run(ClientTokenExchangeSAML2Test::setupRealm);
oauth.realm(TEST);
oauth.clientId("client-exchanger");
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", "user", "password");
String accessToken = response.getAccessToken();
TokenVerifier<AccessToken> accessTokenVerifier = TokenVerifier.create(accessToken, AccessToken.class);
AccessToken token = accessTokenVerifier.parse().getToken();
Assert.assertEquals(token.getPreferredUsername(), "user");
Assert.assertTrue(token.getRealmAccess() == null || !token.getRealmAccess().isUserInRole("example"));
Map<String, String> params = new HashMap<>();
params.put(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.SAML2_TOKEN_TYPE);
{
response = oauth.doTokenExchange(TEST, accessToken, SAML_SIGNED_AND_ENCRYPTED_TARGET, "client-exchanger", "secret", params);
String exchangedTokenString = response.getAccessToken();
String assertionXML = new String(Base64Url.decode(exchangedTokenString), "UTF-8");
// Verify issued_token_type
Assert.assertEquals(OAuth2Constants.SAML2_TOKEN_TYPE, response.getIssuedTokenType());
// Verify assertion
Document assertionDoc = DocumentUtil.getDocument(assertionXML);
Element assertionElement = XMLEncryptionUtil.decryptElementInDocument(assertionDoc, privateKeyFromString(ENCRYPTION_PRIVATE_KEY));
Assert.assertTrue(AssertionUtil.isSignedElement(assertionElement));
AssertionType assertion = (AssertionType) SAMLParser.getInstance().parse(assertionElement);
Assert.assertTrue(AssertionUtil.isSignatureValid(assertionElement, publicKeyFromString(REALM_PUBLIC_KEY)));
// Audience
AudienceRestrictionType aud = (AudienceRestrictionType) assertion.getConditions().getConditions().get(0);
Assert.assertEquals(SAML_SIGNED_AND_ENCRYPTED_TARGET, aud.getAudience().get(0).toString());
// NameID
Assert.assertEquals("user", ((NameIDType) assertion.getSubject().getSubType().getBaseID()).getValue());
// Role mapping
List<String> roles = AssertionUtil.getRoles(assertion, null);
Assert.assertTrue(roles.contains("example"));
}
}
use of org.keycloak.dom.saml.v2.assertion.NameIDType in project keycloak by keycloak.
the class ClientTokenExchangeSAML2Test method testDirectImpersonation.
@Test
@UncaughtServerErrorExpected
public void testDirectImpersonation() throws Exception {
testingClient.server().run(ClientTokenExchangeSAML2Test::setupRealm);
Client httpClient = AdminClientUtil.createResteasyClient();
WebTarget exchangeUrl = httpClient.target(OAuthClient.AUTH_SERVER_ROOT).path("/realms").path(TEST).path("protocol/openid-connect/token");
System.out.println("Exchange url: " + exchangeUrl.getUri().toString());
// direct-legal can impersonate from token "user" to user "impersonated-user" and to "target" client
{
Response response = exchangeUrl.request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader("direct-legal", "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.SAML2_TOKEN_TYPE).param(OAuth2Constants.REQUESTED_SUBJECT, "impersonated-user").param(OAuth2Constants.AUDIENCE, SAML_SIGNED_TARGET)));
Assert.assertEquals(200, response.getStatus());
AccessTokenResponse accessTokenResponse = response.readEntity(AccessTokenResponse.class);
response.close();
String exchangedTokenString = accessTokenResponse.getToken();
String assertionXML = new String(Base64Url.decode(exchangedTokenString), "UTF-8");
// Verify issued_token_type
Assert.assertEquals(OAuth2Constants.SAML2_TOKEN_TYPE, accessTokenResponse.getOtherClaims().get(OAuth2Constants.ISSUED_TOKEN_TYPE));
// Verify assertion
Element assertionElement = DocumentUtil.getDocument(assertionXML).getDocumentElement();
Assert.assertTrue(AssertionUtil.isSignedElement(assertionElement));
AssertionType assertion = (AssertionType) SAMLParser.getInstance().parse(assertionElement);
Assert.assertTrue(AssertionUtil.isSignatureValid(assertionElement, publicKeyFromString(REALM_PUBLIC_KEY)));
// Audience
AudienceRestrictionType aud = (AudienceRestrictionType) assertion.getConditions().getConditions().get(0);
Assert.assertEquals(SAML_SIGNED_TARGET, aud.getAudience().get(0).toString());
// NameID
Assert.assertEquals("impersonated-user", ((NameIDType) assertion.getSubject().getSubType().getBaseID()).getValue());
// Role mapping
List<String> roles = AssertionUtil.getRoles(assertion, null);
Assert.assertTrue(roles.contains("example"));
}
// direct-public fails impersonation
{
Response response = exchangeUrl.request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader("direct-public", "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.SAML2_TOKEN_TYPE).param(OAuth2Constants.REQUESTED_SUBJECT, "impersonated-user").param(OAuth2Constants.AUDIENCE, SAML_SIGNED_TARGET)));
Assert.assertEquals(403, response.getStatus());
response.close();
}
// direct-no-secret fails impersonation
{
Response response = exchangeUrl.request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader("direct-no-secret", "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.SAML2_TOKEN_TYPE).param(OAuth2Constants.REQUESTED_SUBJECT, "impersonated-user").param(OAuth2Constants.AUDIENCE, SAML_SIGNED_TARGET)));
Assert.assertTrue(response.getStatus() >= 400);
response.close();
}
}
use of org.keycloak.dom.saml.v2.assertion.NameIDType in project keycloak by keycloak.
the class ClientTokenExchangeSAML2Test method testImpersonation.
@Test
@UncaughtServerErrorExpected
public void testImpersonation() throws Exception {
testingClient.server().run(ClientTokenExchangeSAML2Test::setupRealm);
oauth.realm(TEST);
oauth.clientId("client-exchanger");
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", "user", "password");
String accessToken = response.getAccessToken();
TokenVerifier<AccessToken> accessTokenVerifier = TokenVerifier.create(accessToken, AccessToken.class);
AccessToken token = accessTokenVerifier.parse().getToken();
Assert.assertEquals(token.getPreferredUsername(), "user");
Assert.assertTrue(token.getRealmAccess() == null || !token.getRealmAccess().isUserInRole("example"));
Map<String, String> params = new HashMap<>();
params.put(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.SAML2_TOKEN_TYPE);
// client-exchanger can impersonate from token "user" to user "impersonated-user" and to "target" client
{
params.put(OAuth2Constants.REQUESTED_SUBJECT, "impersonated-user");
response = oauth.doTokenExchange(TEST, accessToken, SAML_SIGNED_TARGET, "client-exchanger", "secret", params);
String exchangedTokenString = response.getAccessToken();
String assertionXML = new String(Base64Url.decode(exchangedTokenString), "UTF-8");
// Verify issued_token_type
Assert.assertEquals(OAuth2Constants.SAML2_TOKEN_TYPE, response.getIssuedTokenType());
// Verify assertion
Element assertionElement = DocumentUtil.getDocument(assertionXML).getDocumentElement();
Assert.assertTrue(AssertionUtil.isSignedElement(assertionElement));
AssertionType assertion = (AssertionType) SAMLParser.getInstance().parse(assertionElement);
Assert.assertTrue(AssertionUtil.isSignatureValid(assertionElement, publicKeyFromString(REALM_PUBLIC_KEY)));
// Audience
AudienceRestrictionType aud = (AudienceRestrictionType) assertion.getConditions().getConditions().get(0);
Assert.assertEquals(SAML_SIGNED_TARGET, aud.getAudience().get(0).toString());
// NameID
Assert.assertEquals("impersonated-user", ((NameIDType) assertion.getSubject().getSubType().getBaseID()).getValue());
// Role mapping
List<String> roles = AssertionUtil.getRoles(assertion, null);
Assert.assertTrue(roles.contains("example"));
}
}
Aggregations