use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class AssertionUtil method createAssertionSubject.
/**
* Given a user name, create a {@code SubjectType} that can then be inserted into an assertion
*
* @param userName
*
* @return
*/
public static SubjectType createAssertionSubject(String userName) {
SubjectType assertionSubject = new SubjectType();
STSubType subType = new STSubType();
NameIDType anil = new NameIDType();
anil.setValue(userName);
subType.addBaseID(anil);
assertionSubject.setSubType(subType);
return assertionSubject;
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class SAMLAssertionFactory method createSubject.
/**
* <p>
* Creates a {@code SubjectType} object with the specified values.
* </p>
*
* @param nameID the identifier of the subject.
* @param confirmation the {@code SubjectConfirmationType} that is used to establish the correspondence between the
* subject
* and claims of SAML statements.
*
* @return the constructed {@code SubjectType} instance.
*/
public static SubjectType createSubject(NameIDType nameID, SubjectConfirmationType confirmation) {
SubjectType subject = new SubjectType();
if (nameID != null) {
SubjectType.STSubType subType = new SubjectType.STSubType();
subType.addConfirmation(confirmation);
subType.addBaseID(nameID);
subject.setSubType(subType);
}
return subject;
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class UsernameTemplateMapper method setUserNameFromTemplate.
private void setUserNameFromTemplate(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) {
AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION);
String template = mapperModel.getConfig().get(TEMPLATE);
Matcher m = SUBSTITUTION.matcher(template);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String variable = m.group(1);
UnaryOperator<String> transformer = Optional.ofNullable(m.group(2)).map(TRANSFORMERS::get).orElse(UnaryOperator.identity());
if (variable.equals("ALIAS")) {
m.appendReplacement(sb, transformer.apply(context.getIdpConfig().getAlias()));
} else if (variable.equals("UUID")) {
m.appendReplacement(sb, transformer.apply(KeycloakModelUtils.generateId()));
} else if (variable.equals("NAMEID")) {
SubjectType subject = assertion.getSubject();
SubjectType.STSubType subType = subject.getSubType();
NameIDType subjectNameID = (NameIDType) subType.getBaseID();
m.appendReplacement(sb, transformer.apply(subjectNameID.getValue()));
} else if (variable.startsWith("ATTRIBUTE.")) {
String name = variable.substring("ATTRIBUTE.".length());
String value = "";
for (AttributeStatementType statement : assertion.getAttributeStatements()) {
for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
AttributeType attr = choice.getAttribute();
if (name.equals(attr.getName()) || name.equals(attr.getFriendlyName())) {
List<Object> attributeValue = attr.getAttributeValue();
if (attributeValue != null && !attributeValue.isEmpty()) {
value = attributeValue.get(0).toString();
}
break;
}
}
}
m.appendReplacement(sb, transformer.apply(value));
} else {
m.appendReplacement(sb, m.group(1));
}
}
m.appendTail(sb);
Target t = getTarget(mapperModel.getConfig().get(TARGET));
t.set(context, sb.toString());
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class BrokerTest method assertExpired.
private void assertExpired(XMLGregorianCalendar notBefore, XMLGregorianCalendar notOnOrAfter, boolean shouldPass) throws Exception {
Status expectedStatus = shouldPass ? Status.OK : Status.BAD_REQUEST;
final RealmResource realm = adminClient.realm(REALM_NAME);
try (IdentityProviderCreator idp = new IdentityProviderCreator(realm, addIdentityProvider("https://saml.idp/"))) {
new SamlClientBuilder().authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST, SAML_ASSERTION_CONSUMER_URL_SALES_POST, POST).build().login().idp(SAML_BROKER_ALIAS).build().processSamlResponse(REDIRECT).transformObject(this::createAuthnResponse).transformObject(resp -> {
// always invent a new user identified by a different email address
ResponseType rt = (ResponseType) resp;
AssertionType a = rt.getAssertions().get(0).getAssertion();
NameIDType nameId = new NameIDType();
nameId.setFormat(URI.create(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get()));
nameId.setValue(UUID.randomUUID() + "@random.email.org");
SubjectType subject = new SubjectType();
SubjectType.STSubType subType = new SubjectType.STSubType();
subType.addBaseID(nameId);
subject.setSubType(subType);
a.setSubject(subject);
ConditionsType conditions = a.getConditions();
conditions.setNotBefore(notBefore);
conditions.setNotOnOrAfter(notOnOrAfter);
return rt;
}).targetAttributeSamlResponse().targetUri(getSamlBrokerUrl(REALM_NAME)).build().assertResponse(org.keycloak.testsuite.util.Matchers.statusCodeIsHC(expectedStatus)).execute();
}
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class AbstractSamlAuthenticationHandler method handleLoginResponse.
protected AuthOutcome handleLoginResponse(SAMLDocumentHolder responseHolder, boolean postBinding, OnSessionCreated onCreateSession) {
if (!sessionStore.isLoggingIn()) {
log.warn("Adapter obtained LoginResponse, however containers session is not aware of sending any request. " + "This may be because the session cookies created by container are not properly configured " + "with SameSite settings. Refer to KEYCLOAK-14103 for more details.");
}
final ResponseType responseType = (ResponseType) responseHolder.getSamlObject();
AssertionType assertion = null;
if (!isSuccessfulSamlResponse(responseType) || responseType.getAssertions() == null || responseType.getAssertions().isEmpty()) {
return failed(createAuthChallenge403(responseType));
}
try {
assertion = AssertionUtil.getAssertion(responseHolder, responseType, deployment.getDecryptionKey());
ConditionsValidator.Builder cvb = new ConditionsValidator.Builder(assertion.getID(), assertion.getConditions(), destinationValidator);
try {
cvb.clockSkewInMillis(deployment.getIDP().getAllowedClockSkew());
cvb.addAllowedAudience(URI.create(deployment.getEntityID()));
if (responseType.getDestination() != null) {
// getDestination has been validated to match request URL already so it matches SAML endpoint
cvb.addAllowedAudience(URI.create(responseType.getDestination()));
}
} catch (IllegalArgumentException ex) {
// warning has been already emitted in DeploymentBuilder
}
if (!cvb.build().isValid()) {
return initiateLogin();
}
} catch (Exception e) {
log.error("Error extracting SAML assertion: " + e.getMessage());
return failed(CHALLENGE_EXTRACTION_FAILURE);
}
Element assertionElement = null;
if (deployment.getIDP().getSingleSignOnService().validateAssertionSignature()) {
try {
assertionElement = getAssertionFromResponse(responseHolder);
if (!AssertionUtil.isSignatureValid(assertionElement, deployment.getIDP().getSignatureValidationKeyLocator())) {
log.error("Failed to verify saml assertion signature");
return failed(CHALLENGE_INVALID_SIGNATURE);
}
} catch (Exception e) {
log.error("Error processing validation of SAML assertion: " + e.getMessage());
return failed(CHALLENGE_EXTRACTION_FAILURE);
}
}
SubjectType subject = assertion.getSubject();
SubjectType.STSubType subType = subject.getSubType();
NameIDType subjectNameID = subType == null ? null : (NameIDType) subType.getBaseID();
String principalName = subjectNameID == null ? null : subjectNameID.getValue();
Set<String> roles = new HashSet<>();
MultivaluedHashMap<String, String> attributes = new MultivaluedHashMap<>();
MultivaluedHashMap<String, String> friendlyAttributes = new MultivaluedHashMap<>();
Set<StatementAbstractType> statements = assertion.getStatements();
for (StatementAbstractType statement : statements) {
if (statement instanceof AttributeStatementType) {
AttributeStatementType attributeStatement = (AttributeStatementType) statement;
List<AttributeStatementType.ASTChoiceType> attList = attributeStatement.getAttributes();
for (AttributeStatementType.ASTChoiceType obj : attList) {
AttributeType attr = obj.getAttribute();
if (isRole(attr)) {
List<Object> attributeValues = attr.getAttributeValue();
if (attributeValues != null) {
for (Object attrValue : attributeValues) {
String role = getAttributeValue(attrValue);
log.debugv("Add role: {0}", role);
roles.add(role);
}
}
} else {
List<Object> attributeValues = attr.getAttributeValue();
if (attributeValues != null) {
for (Object attrValue : attributeValues) {
String value = getAttributeValue(attrValue);
if (attr.getName() != null) {
attributes.add(attr.getName(), value);
}
if (attr.getFriendlyName() != null) {
friendlyAttributes.add(attr.getFriendlyName(), value);
}
}
}
}
}
}
}
if (deployment.getPrincipalNamePolicy() == SamlDeployment.PrincipalNamePolicy.FROM_ATTRIBUTE) {
if (deployment.getPrincipalAttributeName() != null) {
String attribute = attributes.getFirst(deployment.getPrincipalAttributeName());
if (attribute != null)
principalName = attribute;
else {
attribute = friendlyAttributes.getFirst(deployment.getPrincipalAttributeName());
if (attribute != null)
principalName = attribute;
}
}
}
// use the configured role mappings provider to map roles if necessary.
if (deployment.getRoleMappingsProvider() != null) {
roles = deployment.getRoleMappingsProvider().map(principalName, roles);
}
// roles should also be there as regular attributes
// this mainly required for elytron and its ABAC nature
attributes.put(DEFAULT_ROLE_ATTRIBUTE_NAME, new ArrayList<>(roles));
AuthnStatementType authn = null;
for (Object statement : assertion.getStatements()) {
if (statement instanceof AuthnStatementType) {
authn = (AuthnStatementType) statement;
break;
}
}
URI nameFormat = subjectNameID == null ? null : subjectNameID.getFormat();
String nameFormatString = nameFormat == null ? JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get() : nameFormat.toString();
if (deployment.isKeepDOMAssertion() && assertionElement == null) {
// obtain the assertion from the response to add the DOM document to the principal
assertionElement = getAssertionFromResponseNoException(responseHolder);
}
final SamlPrincipal principal = new SamlPrincipal(assertion, deployment.isKeepDOMAssertion() ? getAssertionDocumentFromElement(assertionElement) : null, principalName, principalName, nameFormatString, attributes, friendlyAttributes);
final String sessionIndex = authn == null ? null : authn.getSessionIndex();
final XMLGregorianCalendar sessionNotOnOrAfter = authn == null ? null : authn.getSessionNotOnOrAfter();
SamlSession account = new SamlSession(principal, roles, sessionIndex, sessionNotOnOrAfter);
sessionStore.saveAccount(account);
onCreateSession.onSessionCreated(account);
// redirect to original request, it will be restored
String redirectUri = sessionStore.getRedirectUri();
if (redirectUri != null) {
facade.getResponse().setHeader("Location", redirectUri);
facade.getResponse().setStatus(302);
facade.getResponse().end();
} else {
log.debug("IDP initiated invocation");
}
log.debug("AUTHENTICATED authn");
return AuthOutcome.AUTHENTICATED;
}
Aggregations