use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class AbstractSamlAuthMech method authenticate.
/**
* Call this inside your authenticate method.
*/
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
UndertowHttpFacade facade = createFacade(exchange);
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
if (!deployment.isConfigured()) {
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
SamlSessionStore sessionStore = getTokenStore(exchange, facade, deployment, securityContext);
SamlAuthenticator authenticator = null;
if (exchange.getRequestPath().endsWith("/saml")) {
authenticator = new UndertowSamlEndpoint(facade, deploymentContext.resolveDeployment(facade), sessionStore);
} else {
authenticator = new UndertowSamlAuthenticator(securityContext, facade, deploymentContext.resolveDeployment(facade), sessionStore);
}
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
registerNotifications(securityContext);
return AuthenticationMechanismOutcome.AUTHENTICATED;
}
if (outcome == AuthOutcome.NOT_AUTHENTICATED) {
// See KEYCLOAK-2107, AbstractSamlAuthenticationHandler
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
if (outcome == AuthOutcome.LOGGED_OUT) {
securityContext.logout();
if (deployment.getLogoutPage() != null) {
redirectLogout(deployment, exchange);
}
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
AuthChallenge challenge = authenticator.getChallenge();
if (challenge != null) {
exchange.putAttachment(KEYCLOAK_CHALLENGE_ATTACHMENT_KEY, challenge);
if (authenticator instanceof UndertowSamlEndpoint) {
exchange.getSecurityContext().setAuthenticationRequired();
}
}
if (outcome == AuthOutcome.FAILED) {
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class SamlServletExtension method handleDeployment.
@Override
@SuppressWarnings("UseSpecificCatch")
public void handleDeployment(DeploymentInfo deploymentInfo, final ServletContext servletContext) {
if (!isAuthenticationMechanismPresent(deploymentInfo, "KEYCLOAK-SAML")) {
log.debug("auth-method is not keycloak saml!");
return;
}
log.debug("SamlServletException initialization");
// Possible scenarios:
// 1) The deployment has a keycloak.config.resolver specified and it exists:
// Outcome: adapter uses the resolver
// 2) The deployment has a keycloak.config.resolver and isn't valid (doesn't exist, isn't a resolver, ...) :
// Outcome: adapter is left unconfigured
// 3) The deployment doesn't have a keycloak.config.resolver , but has a keycloak.json (or equivalent)
// Outcome: adapter uses it
// 4) The deployment doesn't have a keycloak.config.resolver nor keycloak.json (or equivalent)
// Outcome: adapter is left unconfigured
SamlConfigResolver configResolver;
String configResolverClass = servletContext.getInitParameter("keycloak.config.resolver");
SamlDeploymentContext deploymentContext = null;
if (configResolverClass != null) {
try {
configResolver = (SamlConfigResolver) deploymentInfo.getClassLoader().loadClass(configResolverClass).newInstance();
deploymentContext = new SamlDeploymentContext(configResolver);
log.infov("Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass);
} catch (Exception ex) {
log.warn("The specified resolver " + configResolverClass + " could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: " + ex.getMessage());
deploymentContext = new SamlDeploymentContext(new DefaultSamlDeployment());
}
} else {
InputStream is = getConfigInputStream(servletContext);
final SamlDeployment deployment;
if (is == null) {
log.warn("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
deployment = new DefaultSamlDeployment();
} else {
try {
ResourceLoader loader = new ResourceLoader() {
@Override
public InputStream getResourceAsStream(String resource) {
return servletContext.getResourceAsStream(resource);
}
};
deployment = new DeploymentBuilder().build(is, loader);
} catch (ParsingException e) {
throw new RuntimeException(e);
}
}
deploymentContext = new SamlDeploymentContext(deployment);
log.debug("Keycloak is using a per-deployment configuration.");
}
servletContext.setAttribute(SamlDeploymentContext.class.getName(), deploymentContext);
UndertowUserSessionManagement userSessionManagement = new UndertowUserSessionManagement();
final ServletSamlAuthMech mech = createAuthMech(deploymentInfo, deploymentContext, userSessionManagement);
mech.addTokenStoreUpdaters(deploymentInfo);
// setup handlers
deploymentInfo.addAuthenticationMechanism("KEYCLOAK-SAML", new AuthenticationMechanismFactory() {
@Override
public AuthenticationMechanism create(String s, FormParserFactory formParserFactory, Map<String, String> stringStringMap) {
return mech;
}
});
// authentication
deploymentInfo.setIdentityManager(new IdentityManager() {
@Override
public Account verify(Account account) {
return account;
}
@Override
public Account verify(String id, Credential credential) {
throw new IllegalStateException("Should never be called in Keycloak flow");
}
@Override
public Account verify(Credential credential) {
throw new IllegalStateException("Should never be called in Keycloak flow");
}
});
ServletSessionConfig cookieConfig = deploymentInfo.getServletSessionConfig();
if (cookieConfig == null) {
cookieConfig = new ServletSessionConfig();
}
if (cookieConfig.getPath() == null) {
log.debug("Setting jsession cookie path to: " + deploymentInfo.getContextPath());
cookieConfig.setPath(deploymentInfo.getContextPath());
deploymentInfo.setServletSessionConfig(cookieConfig);
}
addEndpointConstraint(deploymentInfo);
ChangeSessionId.turnOffChangeSessionIdOnLogin(deploymentInfo);
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class KeycloakHttpServerAuthenticationMechanism method evaluateRequest.
@Override
public void evaluateRequest(HttpServerRequest request) throws HttpAuthenticationException {
LOGGER.debugf("Evaluating request for path [%s]", request.getRequestURI());
SamlDeploymentContext deploymentContext = getDeploymentContext(request);
if (deploymentContext == null) {
LOGGER.debugf("Ignoring request for path [%s] from mechanism [%s]. No deployment context found.", request.getRequestURI(), getMechanismName());
request.noAuthenticationInProgress();
return;
}
ElytronHttpFacade httpFacade = new ElytronHttpFacade(request, getSessionIdMapper(request), getSessionIdMapperUpdater(request), deploymentContext, callbackHandler);
SamlDeployment deployment = httpFacade.getDeployment();
if (!deployment.isConfigured()) {
request.noAuthenticationInProgress();
return;
}
if (deployment.getLogoutPage() != null && httpFacade.getRequest().getRelativePath().contains(deployment.getLogoutPage())) {
LOGGER.debugf("Ignoring request for [%s] and logout page [%s].", request.getRequestURI(), deployment.getLogoutPage());
httpFacade.authenticationCompleteAnonymous();
return;
}
SamlAuthenticator authenticator;
if (httpFacade.getRequest().getRelativePath().endsWith("/saml")) {
authenticator = new ElytronSamlEndpoint(httpFacade, deployment);
} else {
authenticator = new ElytronSamlAuthenticator(httpFacade, deployment, callbackHandler);
}
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
httpFacade.authenticationComplete();
return;
}
if (outcome == AuthOutcome.NOT_AUTHENTICATED) {
httpFacade.noAuthenticationInProgress(null);
return;
}
if (outcome == AuthOutcome.LOGGED_OUT) {
if (deployment.getLogoutPage() != null) {
redirectLogout(deployment, httpFacade);
}
httpFacade.authenticationInProgress();
return;
}
AuthChallenge challenge = authenticator.getChallenge();
if (challenge != null) {
httpFacade.noAuthenticationInProgress(challenge);
return;
}
if (outcome == AuthOutcome.FAILED) {
httpFacade.authenticationFailed();
return;
}
httpFacade.authenticationInProgress();
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class ArtifactBindingTest method testArtifactBindingWithResponseAndAssertionSignature.
@Test
public void testArtifactBindingWithResponseAndAssertionSignature() throws Exception {
SAMLDocumentHolder response = new SamlClientBuilder().authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_ASSERTION_AND_RESPONSE_SIG, SAML_ASSERTION_CONSUMER_URL_SALES_POST_ASSERTION_AND_RESPONSE_SIG, POST).setProtocolBinding(JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri()).signWith(SAML_CLIENT_SALES_POST_SIG_PRIVATE_KEY, SAML_CLIENT_SALES_POST_SIG_PUBLIC_KEY).build().login().user(bburkeUser).build().handleArtifact(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_ASSERTION_AND_RESPONSE_SIG).signWith(SAML_CLIENT_SALES_POST_SIG_PRIVATE_KEY, SAML_CLIENT_SALES_POST_SIG_PUBLIC_KEY).build().doNotFollowRedirects().executeAndTransform(this::getArtifactResponse);
assertThat(response.getSamlObject(), instanceOf(ArtifactResponseType.class));
ArtifactResponseType artifactResponse = (ArtifactResponseType) response.getSamlObject();
assertThat(artifactResponse, isSamlStatusResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
assertThat(artifactResponse.getAny(), instanceOf(ResponseType.class));
ResponseType samlResponse = (ResponseType) artifactResponse.getAny();
assertThat(samlResponse, isSamlStatusResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
assertThat(samlResponse.getAssertions().get(0).getAssertion().getSignature(), not(nullValue()));
SamlDeployment deployment = SamlUtils.getSamlDeploymentForClient("sales-post-assertion-and-response-sig");
// Checks the signature of the response as well as the signature of the assertion
SamlProtocolUtils.verifyDocumentSignature(response.getSamlDocument(), deployment.getIDP().getSignatureValidationKeyLocator());
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class ArtifactBindingTest method testArtifactBindingWithEncryptedAssertion.
@Test
public void testArtifactBindingWithEncryptedAssertion() throws Exception {
SAMLDocumentHolder response = new SamlClientBuilder().authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_ENC, SAML_ASSERTION_CONSUMER_URL_SALES_POST_ENC, POST).setProtocolBinding(JBossSAMLURIConstants.SAML_HTTP_ARTIFACT_BINDING.getUri()).signWith(SAML_CLIENT_SALES_POST_ENC_PRIVATE_KEY, SAML_CLIENT_SALES_POST_ENC_PUBLIC_KEY).build().login().user(bburkeUser).build().handleArtifact(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_ENC).signWith(SAML_CLIENT_SALES_POST_ENC_PRIVATE_KEY, SAML_CLIENT_SALES_POST_ENC_PUBLIC_KEY).build().doNotFollowRedirects().executeAndTransform(ARTIFACT_RESPONSE::extractResponse);
assertThat(response.getSamlObject(), instanceOf(ResponseType.class));
ResponseType loginResponse = (ResponseType) response.getSamlObject();
assertThat(loginResponse, isSamlStatusResponse(JBossSAMLURIConstants.STATUS_SUCCESS));
assertThat(loginResponse.getAssertions().get(0).getAssertion(), nullValue());
assertThat(loginResponse.getAssertions().get(0).getEncryptedAssertion(), not(nullValue()));
SamlDeployment deployment = SamlUtils.getSamlDeploymentForClient("sales-post-enc");
AssertionUtil.decryptAssertion(response, loginResponse, deployment.getDecryptionKey());
assertThat(loginResponse.getAssertions().get(0).getAssertion(), not(nullValue()));
assertThat(loginResponse.getAssertions().get(0).getEncryptedAssertion(), nullValue());
assertThat(loginResponse.getAssertions().get(0).getAssertion().getIssuer().getValue(), equalTo(getAuthServerRealmBase(REALM_NAME).toString()));
}
Aggregations