use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class SAMLIdentityProvider method authenticationFinished.
@Override
public void authenticationFinished(AuthenticationSessionModel authSession, BrokeredIdentityContext context) {
ResponseType responseType = (ResponseType) context.getContextData().get(SAMLEndpoint.SAML_LOGIN_RESPONSE);
AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION);
SubjectType subject = assertion.getSubject();
SubjectType.STSubType subType = subject.getSubType();
if (subType != null) {
NameIDType subjectNameID = (NameIDType) subType.getBaseID();
authSession.setUserSessionNote(SAMLEndpoint.SAML_FEDERATED_SUBJECT_NAMEID, subjectNameID.serializeAsString());
}
AuthnStatementType authn = (AuthnStatementType) context.getContextData().get(SAMLEndpoint.SAML_AUTHN_STATEMENT);
if (authn != null && authn.getSessionIndex() != null) {
authSession.setUserSessionNote(SAMLEndpoint.SAML_FEDERATED_SESSION_INDEX, authn.getSessionIndex());
}
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class SAMLEndpoint method validateInResponseToAttribute.
private boolean validateInResponseToAttribute(ResponseType responseType, String expectedRequestId) {
// If we are not expecting a request ID, don't bother
if (expectedRequestId == null || expectedRequestId.isEmpty())
return true;
// We are expecting a request ID so we are in SP-initiated login, attribute InResponseTo must be present
if (responseType.getInResponseTo() == null) {
logger.error("Response Validation Error: InResponseTo attribute was expected but not present in received response");
return false;
}
// Attribute is present, proceed with validation
// 1) Attribute Response > InResponseTo must not be empty
String responseInResponseToValue = responseType.getInResponseTo();
if (responseInResponseToValue.isEmpty()) {
logger.error("Response Validation Error: InResponseTo attribute was expected but it is empty in received response");
return false;
}
// 2) Attribute Response > InResponseTo must match request ID
if (!responseInResponseToValue.equals(expectedRequestId)) {
logger.error("Response Validation Error: received InResponseTo attribute does not match the expected request ID");
return false;
}
// If present, Assertion > Subject > Confirmation > SubjectConfirmationData > InResponseTo must also be validated
if (responseType.getAssertions().isEmpty())
return true;
SubjectType subjectElement = responseType.getAssertions().get(0).getAssertion().getSubject();
if (subjectElement != null) {
if (subjectElement.getConfirmation() != null && !subjectElement.getConfirmation().isEmpty()) {
SubjectConfirmationType subjectConfirmationElement = subjectElement.getConfirmation().get(0);
if (subjectConfirmationElement != null) {
SubjectConfirmationDataType subjectConfirmationDataElement = subjectConfirmationElement.getSubjectConfirmationData();
if (subjectConfirmationDataElement != null) {
if (subjectConfirmationDataElement.getInResponseTo() != null) {
// 3) Assertion > Subject > Confirmation > SubjectConfirmationData > InResponseTo is empty
String subjectConfirmationDataInResponseToValue = subjectConfirmationDataElement.getInResponseTo();
if (subjectConfirmationDataInResponseToValue.isEmpty()) {
logger.error("Response Validation Error: SubjectConfirmationData InResponseTo attribute was expected but it is empty in received response");
return false;
}
// 4) Assertion > Subject > Confirmation > SubjectConfirmationData > InResponseTo does not match request ID
if (!subjectConfirmationDataInResponseToValue.equals(expectedRequestId)) {
logger.error("Response Validation Error: received SubjectConfirmationData InResponseTo attribute does not match the expected request ID");
return false;
}
}
}
}
}
}
return true;
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class SAML2Response method createResponseType.
/**
* Create a ResponseType
*
* <b>NOTE:</b>: The PicketLink STS is used to issue/update the assertion
*
* If you want to control over the assertion being issued, then use
* {@link #createResponseType(String, SPInfoHolder, IDPInfoHolder, IssuerInfoHolder, AssertionType)}
*
* @param ID id of the response
* @param sp holder with the information about the Service Provider
* @param idp holder with the information on the Identity Provider
* @param issuerInfo holder with information on the issuer
*
* @return
*
* @throws ConfigurationException
* @throws ProcessingException
*/
public ResponseType createResponseType(String ID, SPInfoHolder sp, IDPInfoHolder idp, IssuerInfoHolder issuerInfo) throws ProcessingException {
String responseDestinationURI = sp.getResponseDestinationURI();
XMLGregorianCalendar issueInstant = XMLTimeUtil.getIssueInstant();
// Create assertion -> subject
SubjectType subjectType = new SubjectType();
// subject -> nameid
NameIDType nameIDType = new NameIDType();
nameIDType.setFormat(idp.getNameIDFormat() == null ? null : URI.create(idp.getNameIDFormat()));
nameIDType.setValue(idp.getNameIDFormatValue());
SubjectType.STSubType subType = new SubjectType.STSubType();
subType.addBaseID(nameIDType);
subjectType.setSubType(subType);
SubjectConfirmationType subjectConfirmation = new SubjectConfirmationType();
subjectConfirmation.setMethod(idp.getSubjectConfirmationMethod());
SubjectConfirmationDataType subjectConfirmationData = new SubjectConfirmationDataType();
subjectConfirmationData.setInResponseTo(sp.getRequestID());
subjectConfirmationData.setRecipient(responseDestinationURI);
// subjectConfirmationData.setNotBefore(issueInstant);
subjectConfirmationData.setNotOnOrAfter(issueInstant);
subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
subjectType.addConfirmation(subjectConfirmation);
AssertionType assertionType;
NameIDType issuerID = issuerInfo.getIssuer();
issueInstant = XMLTimeUtil.getIssueInstant();
ConditionsType conditions = null;
List<StatementAbstractType> statements = new LinkedList<>();
// generate an id for the new assertion.
String assertionID = IDGenerator.create("ID_");
assertionType = SAMLAssertionFactory.createAssertion(assertionID, issuerID, issueInstant, conditions, subjectType, statements);
try {
AssertionUtil.createTimedConditions(assertionType, ASSERTION_VALIDITY, CLOCK_SKEW);
} catch (ConfigurationException e) {
throw logger.processingError(e);
} catch (IssueInstantMissingException e) {
throw logger.processingError(e);
}
ResponseType responseType = createResponseType(ID, issuerInfo, assertionType);
// InResponseTo ID
responseType.setInResponseTo(sp.getRequestID());
// Destination
responseType.setDestination(responseDestinationURI);
return responseType;
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class SAML2AuthnRequestBuilder method createSubject.
private SubjectType createSubject(String value) {
NameIDType nameId = new NameIDType();
nameId.setValue(value);
nameId.setFormat(this.authnRequestType.getNameIDPolicy() != null ? this.authnRequestType.getNameIDPolicy().getFormat() : null);
SubjectType subject = new SubjectType();
SubjectType.STSubType subType = new SubjectType.STSubType();
subType.addBaseID(nameId);
subject.setSubType(subType);
return subject;
}
use of org.keycloak.dom.saml.v2.assertion.SubjectType in project keycloak by keycloak.
the class SAMLSubjectParser method processSubElement.
@Override
protected void processSubElement(XMLEventReader xmlEventReader, SubjectType target, SAMLAssertionQNames element, StartElement elementDetail) throws ParsingException {
SubjectType.STSubType subType;
switch(element) {
case NAMEID:
NameIDType nameID = SAMLParserUtil.parseNameIDType(xmlEventReader);
subType = new SubjectType.STSubType();
subType.addBaseID(nameID);
target.setSubType(subType);
break;
case ENCRYPTED_ID:
Element domElement = StaxParserUtil.getDOMElement(xmlEventReader);
subType = new SubjectType.STSubType();
subType.setEncryptedID(new EncryptedElementType(domElement));
target.setSubType(subType);
break;
case SUBJECT_CONFIRMATION:
target.addConfirmation(SAMLSubjectConfirmationParser.INSTANCE.parse(xmlEventReader));
break;
default:
throw LOGGER.parserUnknownTag(StaxParserUtil.getElementName(elementDetail), elementDetail.getLocation());
}
}
Aggregations