Hello All,
First off I'm a NOOB with SSO, so please educate me kindly on any ignorance within
my questions.
From my research thus far and previous mailing posts sent to this user
list:
Keycloak is very tuned to using a Servlet Container security approach with
keycloak adapters utilizing the .json/.xml configuration file. I've been able to get a
basic authentication working using a completely front end approach. To be clear it's
an Angular JS front end and it was extremely straight forward just porting over the
example. The problem is that I'm trying to tie the authentication to the server
application layer (Spring Security). I am pretty married to Spring Security at this point
and would like to authenticate via an application managed approach. There are multiple
libraries within Spring Security that support industry standards that are in compatible
with Keycloak (SAML, OpenID, OAuth etc).
To be fair I have't ruled out a Servlet Security approach but I've spent a weekend
(again SSO Noob here) trying to migrate my existing spring security (Application Managed
Security) application to a Container using the tomcat adapter and it's been painful to
say the least. I am still using Spring Boot and Java Config. In an attempt to decouple
all the existing security controls that are application managed I've been able to
basically accomplish removing the existing security : You can see the existing code and
output below for my entire current setup for a KeyCloakServerConfiguration Servlet and if
you see anything obvious let me know. I'm not sure how the forms login handoff is
suppose to occur at this point. Should it just be an iframe sourcing in the SSO login
form?
OK so what would be much much more convenient at this point is a few examples of
integrating manually with Keycloak rather then using the adapters. Does anyone have an
example or documentation on how to us SAML or OpenID at an application managed level
(Spring Security SAML or OpenID example would be amazing)? Specifically without using a
keycloak adapter. Thanks in advance for any support/information you can provide.
Best, Andrew
@Configuration
public class KeyCloakServerConfiguration {
@Bean
public EmbeddedServletContainerCustomizer getKeycloakContainerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(
ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
if (configurableEmbeddedServletContainer instanceof
TomcatEmbeddedServletContainerFactory) {
TomcatEmbeddedServletContainerFactory container =
(TomcatEmbeddedServletContainerFactory) configurableEmbeddedServletContainer;
KeycloakAuthenticatorValve authenticatorValve = new KeycloakAuthenticatorValve();
container.addContextValves(authenticatorValve);
container.addContextCustomizers(getKeycloakContextCustomizer());
}
}
};
}
@Bean
public TomcatContextCustomizer getKeycloakContextCustomizer() {
return new TomcatContextCustomizer() {
@Override
public void customize(Context context) {
SecurityConstraint secConstraints = new SecurityConstraint();
secConstraints.setAuthConstraint(true);
secConstraints.addAuthRole("ROLE_USER");
//The only time the application Should Allow Puts is when and administrator
//is authenticated with the site.
SecurityCollection putCollection = new SecurityCollection();
putCollection.addPattern("/**");
putCollection.addMethod("POST");
SecurityCollection getAuthenticatedMaterialsCollection = new SecurityCollection();
getAuthenticatedMaterialsCollection.addPattern("/**");
getAuthenticatedMaterialsCollection.addPattern("/*");
secConstraints.addCollection(putCollection);
secConstraints.addCollection(getAuthenticatedMaterialsCollection);
context.addConstraint(secConstraints);
LoginConfig loginConfig = new LoginConfig();
loginConfig.setAuthMethod("KEYCLOAK");
context.setLoginConfig(loginConfig);
context.addParameter("keycloak.config.resolver",
SpringBootKeycloakConfigResolver.class.getName());
}
};
}
public static class SpringBootKeycloakConfigResolver implements
KeycloakConfigResolver {
private KeycloakDeployment keycloakDeployment;
@Override
public KeycloakDeployment resolve(HttpFacade.Request request) {
if (keycloakDeployment != null) {
return keycloakDeployment;
}
InputStream configInputStream = getClass().getResourceAsStream(
"/keycloak.json");
if (configInputStream == null) {
keycloakDeployment = new KeycloakDeployment();
} else {
keycloakDeployment = KeycloakDeploymentBuilder
.build(configInputStream);
}
return keycloakDeployment;
}
}
Here is the console output. So what I gather is that it appears to be at least
intercepting the requests appropriately and it is successfully loading the .json resource
file.
[DEBUG] org.keycloak.adapters.PreAuthActionsHandler - adminRequest
http://localhost:8080/
[DEBUG] org.keycloak.adapters.KeycloakDeployment - resolveBrowserUrls
[DEBUG] org.keycloak.adapters.KeycloakDeployment - resolveNonBrowserUrls
[DEBUG] org.keycloak.adapters.KeycloakDeploymentBuilder - Use authServerUrl:
http://192.168.53.252:8080/auth, codeUrl:
http://192.168.53.252:8080/auth/realms/Spring-Development/protocol/openid...,
relativeUrls: NEVER