use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.
the class LogoutTest method testFrontchannelLogoutDifferentBrowser.
@Test
public void testFrontchannelLogoutDifferentBrowser() {
adminClient.realm(REALM_NAME).clients().get(sales2Rep.getId()).update(ClientBuilder.edit(sales2Rep).frontchannelLogout(true).attribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_POST_ATTRIBUTE, "").build());
SAMLDocumentHolder samlResponse = prepareLogIntoTwoApps().clearCookies().logoutRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST, POST).nameId(nameIdRef::get).sessionIndex(sessionIndexRef::get).build().getSamlResponse(POST);
assertThat(samlResponse.getSamlObject(), isSamlStatusResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
}
use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.
the class AbstractSamlAuthenticationHandler method handleSamlResponse.
protected AuthOutcome handleSamlResponse(String samlResponse, String relayState, OnSessionCreated onCreateSession) {
SAMLDocumentHolder holder = null;
boolean postBinding = false;
String requestUri = facade.getRequest().getURI();
if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) {
int index = requestUri.indexOf('?');
if (index > -1) {
requestUri = requestUri.substring(0, index);
}
holder = extractRedirectBindingResponse(samlResponse);
} else {
postBinding = true;
holder = extractPostBindingResponse(samlResponse);
}
if (holder == null) {
log.error("Error parsing SAML document");
return failed(CHALLENGE_EXTRACTION_FAILURE);
}
final StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject();
// validate destination
if (statusResponse.getDestination() == null && containsUnencryptedSignature(holder, postBinding)) {
log.error("Destination field required.");
return failed(CHALLENGE_EXTRACTION_FAILURE);
}
if (!destinationValidator.validate(requestUri, statusResponse.getDestination())) {
log.error("Request URI '" + requestUri + "' does not match SAML request destination '" + statusResponse.getDestination() + "'");
return failedTerminal();
}
if (statusResponse instanceof ResponseType) {
try {
if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) {
try {
validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
} catch (VerificationException e) {
log.error("Failed to verify saml response signature", e);
return failed(CHALLENGE_INVALID_SIGNATURE);
}
}
return handleLoginResponse(holder, postBinding, onCreateSession);
} finally {
sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
}
} else {
if (sessionStore.isLoggingOut()) {
try {
if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) {
try {
validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY);
} catch (VerificationException e) {
log.error("Failed to verify saml response signature", e);
return failedTerminal();
}
}
return handleLogoutResponse(holder, statusResponse, relayState);
} finally {
sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
}
} else if (sessionStore.isLoggingIn()) {
try {
// KEYCLOAK-2107 - handle user not authenticated due passive mode. Return special outcome so different authentication mechanisms can behave accordingly.
StatusType status = statusResponse.getStatus();
if (checkStatusCodeValue(status.getStatusCode(), JBossSAMLURIConstants.STATUS_RESPONDER.get()) && checkStatusCodeValue(status.getStatusCode().getStatusCode(), JBossSAMLURIConstants.STATUS_NO_PASSIVE.get())) {
log.debug("Not authenticated due passive mode Status found in SAML response: " + status.toString());
return AuthOutcome.NOT_AUTHENTICATED;
}
return failed(createAuthChallenge403(statusResponse));
} finally {
sessionStore.setCurrentAction(SamlSessionStore.CurrentAction.NONE);
}
}
log.warn("Keycloak Adapter obtained Response, that is not understood. This may be because the containers " + "cookies are not properly configured with SameSite settings. Refer to KEYCLOAK-14103 for more details.");
return AuthOutcome.NOT_ATTEMPTED;
}
}
use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.
the class AbstractSamlAuthenticationHandler method handleSamlRequest.
protected AuthOutcome handleSamlRequest(String samlRequest, String relayState) {
SAMLDocumentHolder holder = null;
boolean postBinding = false;
String requestUri = facade.getRequest().getURI();
if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) {
// strip out query params
int index = requestUri.indexOf('?');
if (index > -1) {
requestUri = requestUri.substring(0, index);
}
holder = SAMLRequestParser.parseRequestRedirectBinding(samlRequest);
} else {
postBinding = true;
holder = SAMLRequestParser.parseRequestPostBinding(samlRequest);
}
if (holder == null) {
log.error("Error parsing SAML document");
return failedTerminal();
}
RequestAbstractType requestAbstractType = (RequestAbstractType) holder.getSamlObject();
if (requestAbstractType.getDestination() == null && containsUnencryptedSignature(holder, postBinding)) {
log.error("Destination field required.");
return failed(CHALLENGE_EXTRACTION_FAILURE);
}
if (!destinationValidator.validate(requestUri, requestAbstractType.getDestination())) {
log.error("Expected destination '" + requestUri + "' got '" + requestAbstractType.getDestination() + "'");
return failedTerminal();
}
if (requestAbstractType instanceof LogoutRequestType) {
if (deployment.getIDP().getSingleLogoutService().validateRequestSignature()) {
try {
validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY);
} catch (VerificationException e) {
log.error("Failed to verify saml request signature", e);
return failedTerminal();
}
}
LogoutRequestType logout = (LogoutRequestType) requestAbstractType;
return logoutRequest(logout, relayState);
} else {
log.error("unknown SAML request type");
return failedTerminal();
}
}
use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.
the class KcSamlBrokerFrontendUrlTest method testFrontendUrlInDestinationExpected.
@Test
public void testFrontendUrlInDestinationExpected() throws URISyntaxException {
SAMLDocumentHolder samlResponse = clientBuilderTrustingAllCertificates().idpInitiatedLogin(new URI(proxy.getUrl() + "/realms/" + bc.consumerRealmName() + "/protocol/saml"), "sales-post").build().login().idp(IDP_SAML_ALIAS).build().processSamlResponse(// AuthnRequest to producer IdP
SamlClient.Binding.POST).targetAttributeSamlRequest().build().login().user(USER_LOGIN, USER_PASSWORD).build().processSamlResponse(SamlClient.Binding.POST).transformObject(saml2Object -> {
assertThat(saml2Object, Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
ResponseType response = (ResponseType) saml2Object;
assertThat(response.getDestination(), startsWith(proxy.getUrl()));
return saml2Object;
}).build().updateProfile().username(USER_LOGIN).email(USER_EMAIL).firstName("Firstname").lastName("Lastname").build().followOneRedirect().getSamlResponse(SamlClient.Binding.POST);
assertThat(samlResponse.getSamlObject(), Matchers.isSamlResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
}
use of org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder in project keycloak by keycloak.
the class SAML2Request method getAuthnRequestType.
/**
* Get the AuthnRequestType from an input stream
*
* @param is Inputstream containing the AuthnRequest
*
* @return
*
* @throws ParsingException
* @throws ProcessingException
* @throws ConfigurationException
* @throws IllegalArgumentException inputstream is null
*/
public AuthnRequestType getAuthnRequestType(InputStream is) throws ConfigurationException, ProcessingException, ParsingException {
if (is == null)
throw logger.nullArgumentError("InputStream");
Document samlDocument = DocumentUtil.getDocument(is);
SAMLParser samlParser = SAMLParser.getInstance();
JAXPValidationUtil.checkSchemaValidation(samlDocument);
AuthnRequestType requestType = (AuthnRequestType) samlParser.parse(samlDocument);
samlDocumentHolder = new SAMLDocumentHolder(requestType, samlDocument);
return requestType;
}
Aggregations