use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class ArtifactBindingTest method testArtifactBindingLogoutTwoClientsPostWithSig.
@Test
public void testArtifactBindingLogoutTwoClientsPostWithSig() throws Exception {
getCleanup().addCleanup(ClientAttributeUpdater.forClient(adminClient, REALM_NAME, SAML_CLIENT_ID_SALES_POST_SIG).setAttribute(SamlConfigAttributes.SAML_ARTIFACT_BINDING, "true").setAttribute(SamlProtocol.SAML_SINGLE_LOGOUT_SERVICE_URL_ARTIFACT_ATTRIBUTE, "http://url").setFrontchannelLogout(true).update());
SAMLDocumentHolder response = new SamlClientBuilder().authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST2, SAML_ASSERTION_CONSUMER_URL_SALES_POST2, POST).build().login().user(bburkeUser).build().processSamlResponse(POST).transformObject(this::extractNameIdAndSessionIndexAndTerminate).build().authnRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_SIG, SAML_ASSERTION_CONSUMER_URL_SALES_POST_SIG, POST).signWith(SAML_CLIENT_SALES_POST_SIG_PRIVATE_KEY, SAML_CLIENT_SALES_POST_SIG_PUBLIC_KEY).build().login().sso(true).build().handleArtifact(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_SIG).signWith(SAML_CLIENT_SALES_POST_SIG_PRIVATE_KEY, SAML_CLIENT_SALES_POST_SIG_PUBLIC_KEY).build().logoutRequest(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST2, POST).nameId(nameIdRef::get).sessionIndex(sessionIndexRef::get).build().handleArtifact(getAuthServerSamlEndpoint(REALM_NAME), SAML_CLIENT_ID_SALES_POST_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.getSignature(), notNullValue());
assertThat(artifactResponse.getAny(), instanceOf(LogoutRequestType.class));
SamlDeployment deployment = SamlUtils.getSamlDeploymentForClient("sales-post");
SamlProtocolUtils.verifyDocumentSignature(response.getSamlDocument(), deployment.getIDP().getSignatureValidationKeyLocator());
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class AbstractSamlAuthenticator method validateRequest.
@Override
public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException {
if (log.isTraceEnabled()) {
log.trace("*** authenticate");
}
Request request = resolveRequest(req);
JettyHttpFacade facade = new JettyHttpFacade(request, (HttpServletResponse) res);
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
if (deployment == null || !deployment.isConfigured()) {
log.debug("*** deployment isn't configured return false");
return Authentication.UNAUTHENTICATED;
}
boolean isEndpoint = request.getRequestURI().substring(request.getContextPath().length()).endsWith("/saml");
if (!mandatory && !isEndpoint)
return new DeferredAuthentication(this);
JettySamlSessionStore tokenStore = getTokenStore(request, facade, deployment);
SamlAuthenticator authenticator = null;
if (isEndpoint) {
authenticator = new SamlAuthenticator(facade, deployment, tokenStore) {
@Override
protected void completeAuthentication(SamlSession account) {
}
@Override
protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
return new SamlEndpoint(facade, deployment, sessionStore);
}
};
} else {
authenticator = new SamlAuthenticator(facade, deployment, tokenStore) {
@Override
protected void completeAuthentication(SamlSession account) {
}
@Override
protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
return new BrowserHandler(facade, deployment, sessionStore);
}
};
}
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
if (facade.isEnded()) {
return Authentication.SEND_SUCCESS;
}
SamlSession samlSession = tokenStore.getAccount();
Authentication authentication = register(request, samlSession);
return authentication;
}
if (outcome == AuthOutcome.LOGGED_OUT) {
logoutCurrent(request);
if (deployment.getLogoutPage() != null) {
forwardToLogoutPage(request, (HttpServletResponse) res, deployment);
}
return Authentication.SEND_CONTINUE;
}
AuthChallenge challenge = authenticator.getChallenge();
if (challenge != null) {
challenge.challenge(facade);
}
return Authentication.SEND_CONTINUE;
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class AbstractSamlAuthenticator method logoutCurrent.
public void logoutCurrent(Request request) {
JettyHttpFacade facade = new JettyHttpFacade(request, null);
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
JettySamlSessionStore tokenStore = getTokenStore(request, facade, deployment);
tokenStore.logoutAccount();
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class SamlFilter method doFilter.
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
ServletHttpFacade facade = new ServletHttpFacade(request, response);
SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
if (deployment == null || !deployment.isConfigured()) {
response.sendError(403);
log.fine("deployment not configured");
return;
}
FilterSamlSessionStore tokenStore = new FilterSamlSessionStore(request, facade, 100000, idMapper, deployment);
boolean isEndpoint = request.getRequestURI().substring(request.getContextPath().length()).endsWith("/saml");
SamlAuthenticator authenticator;
if (isEndpoint) {
authenticator = new SamlAuthenticator(facade, deployment, tokenStore) {
@Override
protected void completeAuthentication(SamlSession account) {
}
@Override
protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
return new SamlEndpoint(facade, deployment, sessionStore);
}
};
} else {
authenticator = new SamlAuthenticator(facade, deployment, tokenStore) {
@Override
protected void completeAuthentication(SamlSession account) {
}
@Override
protected SamlAuthenticationHandler createBrowserHandler(HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
return new BrowserHandler(facade, deployment, sessionStore);
}
};
}
AuthOutcome outcome = authenticator.authenticate();
if (outcome == AuthOutcome.AUTHENTICATED) {
log.fine("AUTHENTICATED");
if (facade.isEnded()) {
return;
}
HttpServletRequestWrapper wrapper = tokenStore.getWrap();
chain.doFilter(wrapper, res);
return;
}
if (outcome == AuthOutcome.LOGGED_OUT) {
tokenStore.logoutAccount();
String logoutPage = deployment.getLogoutPage();
if (logoutPage != null) {
if (PROTOCOL_PATTERN.matcher(logoutPage).find()) {
response.sendRedirect(logoutPage);
log.log(Level.FINE, "Redirected to logout page {0}", logoutPage);
} else {
RequestDispatcher disp = req.getRequestDispatcher(logoutPage);
disp.forward(req, res);
}
return;
}
chain.doFilter(req, res);
return;
}
AuthChallenge challenge = authenticator.getChallenge();
if (challenge != null) {
log.fine("challenge");
challenge.challenge(facade);
return;
}
if (deployment.isIsPassive() && outcome == AuthOutcome.NOT_AUTHENTICATED) {
log.fine("PASSIVE_NOT_AUTHENTICATED");
if (facade.isEnded()) {
return;
}
chain.doFilter(req, res);
return;
}
if (!facade.isEnded()) {
response.sendError(403);
}
}
use of org.keycloak.adapters.saml.SamlDeployment in project keycloak by keycloak.
the class SamlFilter method init.
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
deploymentContext = (SamlDeploymentContext) filterConfig.getServletContext().getAttribute(SamlDeploymentContext.class.getName());
if (deploymentContext != null) {
idMapper = (SessionIdMapper) filterConfig.getServletContext().getAttribute(SessionIdMapper.class.getName());
return;
}
String configResolverClass = filterConfig.getInitParameter("keycloak.config.resolver");
if (configResolverClass != null) {
try {
SamlConfigResolver configResolver = (SamlConfigResolver) getClass().getClassLoader().loadClass(configResolverClass).newInstance();
deploymentContext = new SamlDeploymentContext(configResolver);
log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass);
} catch (Exception ex) {
log.log(Level.WARNING, "The specified resolver {0} could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: {1}", new Object[] { configResolverClass, ex.getMessage() });
deploymentContext = new SamlDeploymentContext(new DefaultSamlDeployment());
}
} else {
String fp = filterConfig.getInitParameter("keycloak.config.file");
InputStream is = null;
if (fp != null) {
try {
is = new FileInputStream(fp);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
} else {
String path = "/WEB-INF/keycloak-saml.xml";
String pathParam = filterConfig.getInitParameter("keycloak.config.path");
if (pathParam != null)
path = pathParam;
is = filterConfig.getServletContext().getResourceAsStream(path);
}
final SamlDeployment deployment;
if (is == null) {
log.info("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 filterConfig.getServletContext().getResourceAsStream(resource);
}
};
deployment = new DeploymentBuilder().build(is, loader);
} catch (ParsingException e) {
throw new RuntimeException(e);
}
}
deploymentContext = new SamlDeploymentContext(deployment);
log.fine("Keycloak is using a per-deployment configuration.");
}
idMapper = new InMemorySessionIdMapper();
filterConfig.getServletContext().setAttribute(SamlDeploymentContext.class.getName(), deploymentContext);
filterConfig.getServletContext().setAttribute(SessionIdMapper.class.getName(), idMapper);
}
Aggregations