use of org.keycloak.dom.saml.v2.protocol.StatusResponseType in project keycloak by keycloak.
the class SamlService method artifactResolve.
/**
* Takes an artifact resolve message and returns the artifact response, if the artifact is found belonging to a session
* of the issuer.
* @param artifactResolveMessage The artifact resolve message sent by the client
* @param artifactResolveHolder the document containing the artifact resolve message sent by the client
* @return a Response containing the SOAP message with the ArifactResponse
* @throws ParsingException
* @throws ConfigurationException
* @throws ProcessingException
*/
public Response artifactResolve(ArtifactResolveType artifactResolveMessage, SAMLDocumentHolder artifactResolveHolder) throws ParsingException, ConfigurationException, ProcessingException {
logger.debug("Received artifactResolve message for artifact " + artifactResolveMessage.getArtifact() + "\n" + "Message: \n" + DocumentUtil.getDocumentAsString(artifactResolveHolder.getSamlDocument()));
// Artifact from resolve request
String artifact = artifactResolveMessage.getArtifact();
if (artifact == null) {
logger.errorf("Artifact to resolve was null");
return emptyArtifactResponseMessage(artifactResolveMessage, null, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.getUri());
}
ArtifactResolver artifactResolver = getArtifactResolver(artifact);
if (artifactResolver == null) {
logger.errorf("Cannot find ArtifactResolver for artifact %s", artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, null, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.getUri());
}
// Obtain details of session that issued artifact and check if it corresponds to issuer of Resolve message
SamlArtifactSessionMappingModel sessionMapping = getArtifactSessionMappingStore().get(artifact);
if (sessionMapping == null) {
logger.errorf("No data stored for artifact %s", artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
UserSessionModel userSessionModel = session.sessions().getUserSession(realm, sessionMapping.getUserSessionId());
if (userSessionModel == null) {
logger.errorf("UserSession with id: %s, that corresponds to artifact: %s does not exist.", sessionMapping.getUserSessionId(), artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
AuthenticatedClientSessionModel clientSessionModel = userSessionModel.getAuthenticatedClientSessions().get(sessionMapping.getClientSessionId());
if (clientSessionModel == null) {
logger.errorf("ClientSession with id: %s, that corresponds to artifact: %s and UserSession: %s does not exist.", sessionMapping.getClientSessionId(), artifact, sessionMapping.getUserSessionId());
return emptyArtifactResponseMessage(artifactResolveMessage, null);
}
ClientModel clientModel = getAndCheckClientModel(sessionMapping.getClientSessionId(), artifactResolveMessage.getIssuer().getValue());
SamlClient samlClient = new SamlClient(clientModel);
// Check signature within ArtifactResolve request if client requires it
if (samlClient.requiresClientSignature()) {
try {
SamlProtocolUtils.verifyDocumentSignature(clientModel, artifactResolveHolder.getSamlDocument());
} catch (VerificationException e) {
SamlService.logger.error("request validation failed", e);
return emptyArtifactResponseMessage(artifactResolveMessage, clientModel);
}
}
// Obtain artifactResponse from clientSessionModel
String artifactResponseString;
try {
artifactResponseString = artifactResolver.resolveArtifact(clientSessionModel, artifact);
} catch (ArtifactResolverProcessingException e) {
logger.errorf(e, "Failed to resolve artifact: %s.", artifact);
return emptyArtifactResponseMessage(artifactResolveMessage, clientModel);
}
// Artifact is successfully resolved, we can remove session mapping from storage
getArtifactSessionMappingStore().remove(artifact);
Document artifactResponseDocument = null;
ArtifactResponseType artifactResponseType = null;
try {
SAMLDataMarshaller marshaller = new SAMLDataMarshaller();
artifactResponseType = marshaller.deserialize(artifactResponseString, ArtifactResponseType.class);
artifactResponseDocument = SamlProtocolUtils.convert(artifactResponseType);
} catch (ParsingException | ConfigurationException | ProcessingException e) {
logger.errorf(e, "Failed to obtain document from ArtifactResponseString: %s.", artifactResponseString);
return emptyArtifactResponseMessage(artifactResolveMessage, clientModel);
}
// If clientSession is in LOGGING_OUT action, now we can move it to LOGGED_OUT
if (CommonClientSessionModel.Action.LOGGING_OUT.name().equals(clientSessionModel.getAction())) {
clientSessionModel.setAction(CommonClientSessionModel.Action.LOGGED_OUT.name());
// If Keycloak sent LogoutResponse we need to also remove UserSession
if (artifactResponseType.getAny() instanceof StatusResponseType && artifactResponseString.contains(JBossSAMLConstants.LOGOUT_RESPONSE.get())) {
if (!UserSessionModel.State.LOGGED_OUT_UNCONFIRMED.equals(userSessionModel.getState())) {
logger.warnf("Keycloak issued LogoutResponse for clientSession %s, however user session %s was not in LOGGED_OUT_UNCONFIRMED state.", clientSessionModel.getId(), userSessionModel.getId());
}
AuthenticationManager.finishUnconfirmedUserSession(session, realm, userSessionModel);
}
}
return artifactResponseMessage(artifactResolveMessage, artifactResponseDocument, clientModel);
}
use of org.keycloak.dom.saml.v2.protocol.StatusResponseType in project keycloak by keycloak.
the class SAML2LogoutResponseBuilder method buildDocument.
public Document buildDocument() throws ProcessingException {
Document samlResponse = null;
try {
StatusResponseType statusResponse = buildModel();
SAML2Response saml2Response = new SAML2Response();
samlResponse = saml2Response.convert(statusResponse);
} catch (ConfigurationException e) {
throw new ProcessingException(e);
} catch (ParsingException e) {
throw new ProcessingException(e);
}
return samlResponse;
}
use of org.keycloak.dom.saml.v2.protocol.StatusResponseType in project keycloak by keycloak.
the class SAML2ErrorResponseBuilder method buildDocument.
public Document buildDocument() throws ProcessingException {
try {
StatusResponseType statusResponse = new ResponseType(IDGenerator.create("ID_"), XMLTimeUtil.getIssueInstant());
statusResponse.setStatus(JBossSAMLAuthnResponseFactory.createStatusTypeForResponder(status));
statusResponse.setIssuer(issuer);
statusResponse.setDestination(destination);
if (!this.extensions.isEmpty()) {
ExtensionsType extensionsType = new ExtensionsType();
for (NodeGenerator extension : this.extensions) {
extensionsType.addExtension(extension);
}
statusResponse.setExtensions(extensionsType);
}
SAML2Response saml2Response = new SAML2Response();
return saml2Response.convert(statusResponse);
} catch (ConfigurationException e) {
throw new ProcessingException(e);
} catch (ParsingException e) {
throw new ProcessingException(e);
}
}
use of org.keycloak.dom.saml.v2.protocol.StatusResponseType in project keycloak by keycloak.
the class SAMLResponseWriter method write.
public void write(ArtifactResponseType response) throws ProcessingException {
StaxUtil.writeStartElement(writer, PROTOCOL_PREFIX, JBossSAMLConstants.ARTIFACT_RESPONSE.get(), JBossSAMLURIConstants.PROTOCOL_NSURI.get());
StaxUtil.writeNameSpace(writer, PROTOCOL_PREFIX, JBossSAMLURIConstants.PROTOCOL_NSURI.get());
StaxUtil.writeNameSpace(writer, ASSERTION_PREFIX, JBossSAMLURIConstants.ASSERTION_NSURI.get());
StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.ASSERTION_NSURI.get());
writeBaseAttributes(response);
NameIDType issuer = response.getIssuer();
if (issuer != null) {
write(issuer, new QName(JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get(), ASSERTION_PREFIX));
}
Element sig = response.getSignature();
if (sig != null) {
StaxUtil.writeDOMElement(writer, sig);
}
ExtensionsType extensions = response.getExtensions();
if (extensions != null && extensions.getAny() != null && !extensions.getAny().isEmpty()) {
write(extensions);
}
StatusType status = response.getStatus();
if (status != null) {
write(status);
}
Object anyObj = response.getAny();
if (anyObj instanceof AuthnRequestType) {
AuthnRequestType authn = (AuthnRequestType) anyObj;
SAMLRequestWriter requestWriter = new SAMLRequestWriter(writer);
requestWriter.write(authn);
} else if (anyObj instanceof LogoutRequestType) {
LogoutRequestType logoutRequestType = (LogoutRequestType) anyObj;
SAMLRequestWriter requestWriter = new SAMLRequestWriter(writer);
requestWriter.write(logoutRequestType);
} else if (anyObj instanceof ResponseType) {
ResponseType rt = (ResponseType) anyObj;
write(rt);
} else if (anyObj instanceof StatusResponseType) {
StatusResponseType rt = (StatusResponseType) anyObj;
write(rt, new QName(PROTOCOL_NSURI.get(), JBossSAMLConstants.LOGOUT_RESPONSE.get(), "samlp"));
}
StaxUtil.writeEndElement(writer);
StaxUtil.flush(writer);
}
use of org.keycloak.dom.saml.v2.protocol.StatusResponseType in project keycloak by keycloak.
the class SamlDocumentStepBuilder method saml2Object2String.
public static String saml2Object2String(final SAML2Object transformed) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
XMLStreamWriter xmlStreamWriter = StaxUtil.getXMLStreamWriter(bos);
if (transformed instanceof AuthnRequestType) {
new SAMLRequestWriter(xmlStreamWriter).write((AuthnRequestType) transformed);
} else if (transformed instanceof LogoutRequestType) {
new SAMLRequestWriter(xmlStreamWriter).write((LogoutRequestType) transformed);
} else if (transformed instanceof ArtifactResolveType) {
new SAMLRequestWriter(xmlStreamWriter).write((ArtifactResolveType) transformed);
} else if (transformed instanceof AttributeQueryType) {
new SAMLRequestWriter(xmlStreamWriter).write((AttributeQueryType) transformed);
} else if (transformed instanceof ResponseType) {
new SAMLResponseWriter(xmlStreamWriter).write((ResponseType) transformed);
} else if (transformed instanceof ArtifactResponseType) {
new SAMLResponseWriter(xmlStreamWriter).write((ArtifactResponseType) transformed);
} else if (transformed instanceof StatusResponseType) {
new SAMLResponseWriter(xmlStreamWriter).write((StatusResponseType) transformed, SAMLProtocolQNames.LOGOUT_RESPONSE.getQName("samlp"));
} else {
Assert.assertNotNull("Unknown type: <null>", transformed);
Assert.fail("Unknown type: " + transformed.getClass().getName());
}
return new String(bos.toByteArray(), GeneralConstants.SAML_CHARSET);
} catch (ProcessingException ex) {
throw new RuntimeException(ex);
}
}
Aggregations