Commit 645bc94e by Bolke de Bruin Committed by nixonrodrigues

ATLAS-3153 :- Add Keycloak authentication method to Atlas.

Keycloak is an open source Identity and Access Management solution aimed at modern applications and services. It makes it easy to secure applications and services with little to no code. This enabled Atlas to use OpenID Connect (OAUTH2) and allows integration with more services. Signed-off-by: 's avatarnixonrodrigues <nixon@apache.org>
parent 2c375b08
...@@ -7,6 +7,7 @@ Atlas supports following authentication methods ...@@ -7,6 +7,7 @@ Atlas supports following authentication methods
* *File* * *File*
* *Kerberos* * *Kerberos*
* *LDAP* * *LDAP*
* *Keycloak (OpenID Connect / OAUTH2)*
Following properties should be set true to enable the authentication of that type in =atlas-application.properties= file. Following properties should be set true to enable the authentication of that type in =atlas-application.properties= file.
...@@ -16,6 +17,7 @@ Following properties should be set true to enable the authentication of that typ ...@@ -16,6 +17,7 @@ Following properties should be set true to enable the authentication of that typ
atlas.authentication.method.kerberos=true|false atlas.authentication.method.kerberos=true|false
atlas.authentication.method.ldap=true|false atlas.authentication.method.ldap=true|false
atlas.authentication.method.file=true|false atlas.authentication.method.file=true|false
atlas.authentication.method.keycloak=true|false
</verbatim> </verbatim>
If two or more authentication methods are set to true, then the authentication falls back to the latter method if the earlier one fails. If two or more authentication methods are set to true, then the authentication falls back to the latter method if the earlier one fails.
...@@ -111,3 +113,29 @@ atlas.authentication.method.ldap.user.searchfilter=(uid={0}) ...@@ -111,3 +113,29 @@ atlas.authentication.method.ldap.user.searchfilter=(uid={0})
atlas.authentication.method.ldap.default.role=ROLE_USER atlas.authentication.method.ldap.default.role=ROLE_USER
</verbatim> </verbatim>
---++++ Keycloak Method.
To enable Keycloak authentication mode in Atlas, set the property =atlas.authentication.method.keycloak= to true and also set the property =atlas.authentication.method.keycloak.file= to the localtion of your =keycloak.json= in =atlas-application.properties=.
Also set =atlas.authentication.method.keycloak.ugi-groups= to false if you want to pickup groups from Keycloak. By default the groups will be picked up from the *roles* defined in Keycloak. In case you want to use the groups
you need to create a mapping in keycloak and define =atlas.authentication.method.keycloak.groups_claim= equal to the token claim name. Make sure *not* to use the full group path and add the information to the access token.
<verbatim>
atlas.authentication.method.keycloak=true
atlas.authentication.method.keycloak.file=/opt/atlas/conf/keycloak.json
atlas.authentication.method.keycloak.ugi-groups=false
</verbatim>
Setup you keycloak.json per instructions from Keycloak. Make sure to include ="principal-attribute": "preferred_username"= to ensure readable user names and ="autodetect-bearer-only": true=.
<verbatim>
{
"realm": "auth",
"auth-server-url": "http://keycloak-server/auth",
"ssl-required": "external",
"resource": "atlas",
"public-client": true,
"confidential-port": 0,
"principal-attribute": "preferred_username",
"autodetect-bearer-only": true
}
</verbatim>
...@@ -719,6 +719,10 @@ ...@@ -719,6 +719,10 @@
<hppc.version>0.8.1</hppc.version> <hppc.version>0.8.1</hppc.version>
<!-- Storm dependencies --> <!-- Storm dependencies -->
<!-- keycloak dependencies -->
<keycloak.version>6.0.1</keycloak.version>
<!-- keycloak dependencies -->
<PermGen>64m</PermGen> <PermGen>64m</PermGen>
<MaxPermGen>512m</MaxPermGen> <MaxPermGen>512m</MaxPermGen>
......
...@@ -468,6 +468,14 @@ ...@@ -468,6 +468,14 @@
<artifactId>hadoop-aws</artifactId> <artifactId>hadoop-aws</artifactId>
<version>${hadoop.version}</version> <version>${hadoop.version}</version>
</dependency> </dependency>
<!-- Keycloak -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>${keycloak.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -37,11 +37,14 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv ...@@ -37,11 +37,14 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
private boolean fileAuthenticationMethodEnabled = true; private boolean fileAuthenticationMethodEnabled = true;
private boolean pamAuthenticationEnabled = false; private boolean pamAuthenticationEnabled = false;
private boolean keycloakAuthenticationEnabled = false;
private String ldapType = "NONE"; private String ldapType = "NONE";
public static final String FILE_AUTH_METHOD = "atlas.authentication.method.file"; public static final String FILE_AUTH_METHOD = "atlas.authentication.method.file";
public static final String LDAP_AUTH_METHOD = "atlas.authentication.method.ldap"; public static final String LDAP_AUTH_METHOD = "atlas.authentication.method.ldap";
public static final String LDAP_TYPE = "atlas.authentication.method.ldap.type"; public static final String LDAP_TYPE = "atlas.authentication.method.ldap.type";
public static final String PAM_AUTH_METHOD = "atlas.authentication.method.pam"; public static final String PAM_AUTH_METHOD = "atlas.authentication.method.pam";
public static final String KEYCLOAK_AUTH_METHOD = "atlas.authentication.method.keycloak";
...@@ -55,15 +58,19 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv ...@@ -55,15 +58,19 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
final AtlasPamAuthenticationProvider pamAuthenticationProvider; final AtlasPamAuthenticationProvider pamAuthenticationProvider;
final AtlasKeycloakAuthenticationProvider atlasKeycloakAuthenticationProvider;
@Inject @Inject
public AtlasAuthenticationProvider(AtlasLdapAuthenticationProvider ldapAuthenticationProvider, public AtlasAuthenticationProvider(AtlasLdapAuthenticationProvider ldapAuthenticationProvider,
AtlasFileAuthenticationProvider fileAuthenticationProvider, AtlasFileAuthenticationProvider fileAuthenticationProvider,
AtlasADAuthenticationProvider adAuthenticationProvider, AtlasADAuthenticationProvider adAuthenticationProvider,
AtlasPamAuthenticationProvider pamAuthenticationProvider) { AtlasPamAuthenticationProvider pamAuthenticationProvider,
AtlasKeycloakAuthenticationProvider atlasKeycloakAuthenticationProvider) {
this.ldapAuthenticationProvider = ldapAuthenticationProvider; this.ldapAuthenticationProvider = ldapAuthenticationProvider;
this.fileAuthenticationProvider = fileAuthenticationProvider; this.fileAuthenticationProvider = fileAuthenticationProvider;
this.adAuthenticationProvider = adAuthenticationProvider; this.adAuthenticationProvider = adAuthenticationProvider;
this.pamAuthenticationProvider = pamAuthenticationProvider; this.pamAuthenticationProvider = pamAuthenticationProvider;
this.atlasKeycloakAuthenticationProvider = atlasKeycloakAuthenticationProvider;
} }
@PostConstruct @PostConstruct
...@@ -75,6 +82,8 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv ...@@ -75,6 +82,8 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
this.pamAuthenticationEnabled = configuration.getBoolean(PAM_AUTH_METHOD, false); this.pamAuthenticationEnabled = configuration.getBoolean(PAM_AUTH_METHOD, false);
this.keycloakAuthenticationEnabled = configuration.getBoolean(KEYCLOAK_AUTH_METHOD, false);
boolean ldapAuthenticationEnabled = configuration.getBoolean(LDAP_AUTH_METHOD, false); boolean ldapAuthenticationEnabled = configuration.getBoolean(LDAP_AUTH_METHOD, false);
if (ldapAuthenticationEnabled) { if (ldapAuthenticationEnabled) {
...@@ -118,6 +127,12 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv ...@@ -118,6 +127,12 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("Error while PAM authentication", ex); LOG.error("Error while PAM authentication", ex);
} }
} else if (keycloakAuthenticationEnabled) {
try {
authentication = atlasKeycloakAuthenticationProvider.authenticate(authentication);
} catch (Exception ex) {
LOG.error("Error while Keycloak authentication", ex);
}
} }
} }
...@@ -137,6 +152,21 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv ...@@ -137,6 +152,21 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
throw new AtlasAuthenticationException("Authentication failed."); throw new AtlasAuthenticationException("Authentication failed.");
} }
@Override
public boolean supports(Class<?> authentication) {
if (pamAuthenticationEnabled) {
return pamAuthenticationProvider.supports(authentication);
} else if (ldapType.equalsIgnoreCase("LDAP")) {
return ldapAuthenticationProvider.supports(authentication);
} else if (ldapType.equalsIgnoreCase("AD")) {
return adAuthenticationProvider.supports(authentication);
} else if (keycloakAuthenticationEnabled) {
return atlasKeycloakAuthenticationProvider.supports(authentication);
} else {
return super.supports(authentication);
}
}
public boolean isSsoEnabled() { public boolean isSsoEnabled() {
return ssoEnabled; return ssoEnabled;
} }
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.web.security;
import org.apache.atlas.ApplicationProperties;
import org.apache.commons.configuration.Configuration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class AtlasKeycloakAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
private final boolean groupsFromUGI;
private final String groupsClaim;
private final KeycloakAuthenticationProvider keycloakAuthenticationProvider;
public AtlasKeycloakAuthenticationProvider() throws Exception {
this.keycloakAuthenticationProvider = new KeycloakAuthenticationProvider();
Configuration configuration = ApplicationProperties.get();
this.groupsFromUGI = configuration.getBoolean("atlas.authentication.method.keycloak.ugi-groups", true);
this.groupsClaim = configuration.getString("atlas.authentication.method.keycloak.groups_claim");
}
@Override
public Authentication authenticate(Authentication authentication) {
authentication = keycloakAuthenticationProvider.authenticate(authentication);
if (groupsFromUGI) {
List<GrantedAuthority> groups = getAuthoritiesFromUGI(authentication.getName());
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
authentication = new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), groups);
} else if (groupsClaim != null) {
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken)authentication;
Map<String, Object> claims = token.getAccount().getKeycloakSecurityContext().getToken().getOtherClaims();
if (claims.containsKey(groupsClaim)) {
List<String> membership = (List<String>)claims.get(groupsClaim);
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (String group : membership) {
grantedAuthorities.add(new SimpleGrantedAuthority(group));
}
authentication = new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), grantedAuthorities);
}
}
return authentication;
}
@Override
public boolean supports(Class<?> aClass) {
return keycloakAuthenticationProvider.supports(aClass);
}
}
\ No newline at end of file
...@@ -25,8 +25,31 @@ import org.apache.atlas.web.filters.AtlasKnoxSSOAuthenticationFilter; ...@@ -25,8 +25,31 @@ import org.apache.atlas.web.filters.AtlasKnoxSSOAuthenticationFilter;
import org.apache.atlas.web.filters.StaleTransactionCleanupFilter; import org.apache.atlas.web.filters.StaleTransactionCleanupFilter;
import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.keycloak.adapters.AdapterDeploymentContext;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.adapters.springsecurity.AdapterDeploymentContextFactoryBean;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler;
import org.keycloak.adapters.springsecurity.config.KeycloakSpringConfigResolverWrapper;
import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter;
import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter;
import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter;
import org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter;
import org.keycloak.adapters.springsecurity.filter.QueryParamPresenceRequestMatcher;
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
...@@ -34,22 +57,34 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity; ...@@ -34,22 +57,34 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint; import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter; import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher; import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.security.web.header.writers.StaticHeadersWriter; import org.springframework.security.web.header.writers.StaticHeadersWriter;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.apache.atlas.AtlasConstants.ATLAS_MIGRATION_MODE_FILENAME; import static org.apache.atlas.AtlasConstants.ATLAS_MIGRATION_MODE_FILENAME;
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
@KeycloakConfiguration
public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(AtlasSecurityConfig.class); private static final Logger LOG = LoggerFactory.getLogger(AtlasSecurityConfig.class);
...@@ -66,6 +101,15 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -66,6 +101,15 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
private final StaleTransactionCleanupFilter staleTransactionCleanupFilter; private final StaleTransactionCleanupFilter staleTransactionCleanupFilter;
private final ActiveServerFilter activeServerFilter; private final ActiveServerFilter activeServerFilter;
public static final RequestMatcher KEYCLOAK_REQUEST_MATCHER = new OrRequestMatcher(new RequestMatcher[]{new AntPathRequestMatcher("/login.jsp"), new RequestHeaderRequestMatcher("Authorization"), new QueryParamPresenceRequestMatcher("access_token")});
@Value("${keycloak.configurationFile:WEB-INF/keycloak.json}")
private Resource keycloakConfigFileResource;
@Autowired(required = false)
private KeycloakConfigResolver keycloakConfigResolver;
private final boolean keycloakEnabled;
@Inject @Inject
public AtlasSecurityConfig(AtlasKnoxSSOAuthenticationFilter ssoAuthenticationFilter, public AtlasSecurityConfig(AtlasKnoxSSOAuthenticationFilter ssoAuthenticationFilter,
AtlasCSRFPreventionFilter atlasCSRFPreventionFilter, AtlasCSRFPreventionFilter atlasCSRFPreventionFilter,
...@@ -87,15 +131,27 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -87,15 +131,27 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
this.configuration = configuration; this.configuration = configuration;
this.staleTransactionCleanupFilter = staleTransactionCleanupFilter; this.staleTransactionCleanupFilter = staleTransactionCleanupFilter;
this.activeServerFilter = activeServerFilter; this.activeServerFilter = activeServerFilter;
this.keycloakEnabled = configuration.getBoolean(AtlasAuthenticationProvider.KEYCLOAK_AUTH_METHOD, false);
} }
public BasicAuthenticationEntryPoint getAuthenticationEntryPoint() { public AuthenticationEntryPoint getAuthenticationEntryPoint() throws Exception {
BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint(); AuthenticationEntryPoint authenticationEntryPoint;
basicAuthenticationEntryPoint.setRealmName("atlas.com");
return basicAuthenticationEntryPoint; if (keycloakEnabled) {
KeycloakAuthenticationEntryPoint keycloakAuthenticationEntryPoint = new KeycloakAuthenticationEntryPoint(adapterDeploymentContext());
keycloakAuthenticationEntryPoint.setRealm("atlas.com");
keycloakAuthenticationEntryPoint.setLoginUri("/login.jsp");
authenticationEntryPoint = keycloakAuthenticationEntryPoint;
} else {
BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
basicAuthenticationEntryPoint.setRealmName("atlas.com");
authenticationEntryPoint = basicAuthenticationEntryPoint;
}
return authenticationEntryPoint;
} }
public DelegatingAuthenticationEntryPoint getDelegatingAuthenticationEntryPoint() { public DelegatingAuthenticationEntryPoint getDelegatingAuthenticationEntryPoint() throws Exception {
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPointMap = new LinkedHashMap<>(); LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPointMap = new LinkedHashMap<>();
entryPointMap.put(new RequestHeaderRequestMatcher("User-Agent", "Mozilla"), atlasAuthenticationEntryPoint); entryPointMap.put(new RequestHeaderRequestMatcher("User-Agent", "Mozilla"), atlasAuthenticationEntryPoint);
DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(entryPointMap); DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(entryPointMap);
...@@ -110,19 +166,24 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -110,19 +166,24 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
public void configure(WebSecurity web) throws Exception { public void configure(WebSecurity web) throws Exception {
List<String> matchers = new ArrayList<>(
Arrays.asList("/css/**",
"/img/**",
"/libs/**",
"/js/**",
"/ieerror.html",
"/api/atlas/admin/status",
"/api/atlas/admin/metrics"));
if (!keycloakEnabled) {
matchers.add("/login.jsp");
}
web.ignoring() web.ignoring()
.antMatchers("/login.jsp", .antMatchers(matchers.toArray(new String[matchers.size()]));
"/css/**",
"/img/**",
"/libs/**",
"/js/**",
"/ieerror.html",
"/api/atlas/admin/status",
"/api/atlas/admin/metrics");
} }
protected void configure(HttpSecurity httpSecurity) throws Exception { protected void configure(HttpSecurity httpSecurity) throws Exception {
//@formatter:off //@formatter:off
httpSecurity httpSecurity
.authorizeRequests().anyRequest().authenticated() .authorizeRequests().anyRequest().authenticated()
...@@ -173,5 +234,81 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -173,5 +234,81 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
.addFilterBefore(ssoAuthenticationFilter, BasicAuthenticationFilter.class) .addFilterBefore(ssoAuthenticationFilter, BasicAuthenticationFilter.class)
.addFilterAfter(atlasAuthenticationFilter, SecurityContextHolderAwareRequestFilter.class) .addFilterAfter(atlasAuthenticationFilter, SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(csrfPreventionFilter, AtlasAuthenticationFilter.class); .addFilterAfter(csrfPreventionFilter, AtlasAuthenticationFilter.class);
if (keycloakEnabled) {
httpSecurity
.logout().addLogoutHandler(keycloakLogoutHandler()).and()
.addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(keycloakAuthenticatedActionsRequestFilter(), KeycloakSecurityContextRequestFilter.class);
}
}
@Bean
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
protected AdapterDeploymentContext adapterDeploymentContext() throws Exception {
AdapterDeploymentContextFactoryBean factoryBean;
String fileName = configuration.getString("atlas.authentication.method.keycloak.file");
if (fileName != null && !fileName.isEmpty()) {
keycloakConfigFileResource = new FileSystemResource(fileName);
factoryBean = new AdapterDeploymentContextFactoryBean(keycloakConfigFileResource);
} else {
Configuration conf = configuration.subset("atlas.authentication.method.keycloak");
AdapterConfig cfg = new AdapterConfig();
cfg.setRealm(conf.getString("realm", "atlas.com"));
cfg.setAuthServerUrl(conf.getString("auth-server-url", "https://localhost/auth"));
cfg.setResource(conf.getString("resource", "none"));
Map<String,Object> credentials = new HashMap<>();
credentials.put("secret", conf.getString("credentials-secret", "nosecret"));
cfg.setCredentials(credentials);
KeycloakDeployment dep = KeycloakDeploymentBuilder.build(cfg);
factoryBean = new AdapterDeploymentContextFactoryBean(new KeycloakConfigResolver() {
@Override
public KeycloakDeployment resolve(HttpFacade.Request request) {
return dep;
}
});
}
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
@Bean
protected KeycloakPreAuthActionsFilter keycloakPreAuthActionsFilter() {
return new KeycloakPreAuthActionsFilter(httpSessionManager());
}
@Bean
protected HttpSessionManager httpSessionManager() {
return new HttpSessionManager();
}
protected KeycloakLogoutHandler keycloakLogoutHandler() throws Exception {
return new KeycloakLogoutHandler(adapterDeploymentContext());
}
@Bean
protected KeycloakSecurityContextRequestFilter keycloakSecurityContextRequestFilter() {
return new KeycloakSecurityContextRequestFilter();
}
@Bean
protected KeycloakAuthenticatedActionsFilter keycloakAuthenticatedActionsRequestFilter() {
return new KeycloakAuthenticatedActionsFilter();
}
@Bean
protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
KeycloakAuthenticationProcessingFilter filter = new KeycloakAuthenticationProcessingFilter(authenticationManagerBean(), KEYCLOAK_REQUEST_MATCHER);
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
return filter;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment