Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaHonchar committed Sep 6, 2018
2 parents f6b009b + b8cecbf commit fd04655
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 47 deletions.
10 changes: 10 additions & 0 deletions gui/admin-gui/pom.xml
Expand Up @@ -220,6 +220,16 @@
<version>2.5.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
Expand Down
Expand Up @@ -16,8 +16,20 @@

package com.evolveum.midpoint.web.boot;

import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.lang.reflect.Constructor;

/**
* Created by Viliam Repan (lazyman).
Expand All @@ -26,5 +38,51 @@
@Configuration
public class CasSecurityConfig {

// TODO move configuration from ctx-web-security-cas.xml here
@Value("${auth.cas.midpoint.url}")
private String casMidpointUrl;
@Value("${auth.cas.server.url}")
private String casServerUrl;
@Value("${auth.cas.ticketValidator}")
private String ticketValidator;

@Bean
public ServiceProperties serviceProperties() {
ServiceProperties properties = new ServiceProperties();
properties.setService(casMidpointUrl + "/login/cas");
properties.setSendRenew(false);

return properties;
}

@Bean
public CasAuthenticationEntryPoint authenticationEntryPoint() {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl(casServerUrl + "/login");
entryPoint.setServiceProperties(serviceProperties());

return entryPoint;
}

@Profile("cas")
@Bean
public AuthenticationProvider midPointAuthenticationProvider(UserDetailsService userDetailsService) throws Exception {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setAuthenticationUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService));
provider.setServiceProperties(serviceProperties());
provider.setTicketValidator(createTicketValidatorInstance());
provider.setKey("CAS_ID");

return provider;
}

private TicketValidator createTicketValidatorInstance() throws Exception {
if (!StringUtils.contains(ticketValidator, "\\.")) {
ticketValidator = "org.jasig.cas.client.validation." + ticketValidator;
}

Class<TicketValidator> type = (Class) Class.forName(ticketValidator);
Constructor<TicketValidator> c = type.getConstructor(String.class);

return c.newInstance(casServerUrl);
}
}
Expand Up @@ -23,44 +23,58 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter;

import java.util.Arrays;

/**
* Created by Viliam Repan (lazyman).
*/
@Order(SecurityProperties.BASIC_AUTH_ORDER - 1)
@Configuration
//TODO
//@EnableGlobalMethodSecurity(securedEnabled = true)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private Environment environment;
@Autowired
private AuthenticationProvider authenticationProvider;
@Autowired
private AuthenticationManager authenticationManager;

@Autowired
private MidPointGuiAuthorizationEvaluator accessDecisionManager;

@Value("${auth.sso.header:SM_USER}")
private String principalRequestHeader;

@Value("${auth.cas.server.url:}")
private String casServerUrl;

@Value("${security.enable-csrf:true}")
private boolean csrfEnabled;
@Value("${auth.logout.url:/}")
private String authLogoutUrl;
@Value("${auth.sso.header:SM_USER}")
private String principalRequestHeader;


@Profile("!cas")
@Bean
public WicketLoginUrlAuthenticationEntryPoint wicketAuthenticationEntryPoint() {
public AuthenticationEntryPoint authenticationEntryPoint() {
return new WicketLoginUrlAuthenticationEntryPoint("/login");
}

Expand All @@ -71,27 +85,15 @@ public MidPointGuiAuthorizationEvaluator accessDecisionManager(SecurityEnforcer
return new MidPointGuiAuthorizationEvaluator(securityEnforcer, securityContextManager, taskManager);
}

@Profile("sso")
@Bean
public RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter() throws Exception {
RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
filter.setPrincipalRequestHeader(principalRequestHeader);
filter.setAuthenticationManager(authenticationManager());

getHttp().addFilterBefore(filter, LogoutFilter.class);

return filter;
}

@Override
public void configure(WebSecurity web) throws Exception {
// Web (SOAP) services
// Web (SOAP) services
web.ignoring().antMatchers("/model/**");
web.ignoring().antMatchers("/ws/**");

// REST service
web.ignoring().antMatchers("/rest/**");

// Special intra-cluster service to download and delete report outputs
web.ignoring().antMatchers("/report");

Expand Down Expand Up @@ -139,24 +141,41 @@ protected void configure(HttpSecurity http) throws Exception {
.successHandler(authenticationSuccessHandler()).permitAll();

http.exceptionHandling()
.authenticationEntryPoint(wicketAuthenticationEntryPoint())
.authenticationEntryPoint(authenticationEntryPoint())
.accessDeniedHandler(accessDeniedHandler());

if (!csrfEnabled) {
http.csrf().disable();
}

http.headers().disable();

if (Arrays.stream(environment.getActiveProfiles()).anyMatch(p -> p.equalsIgnoreCase("cas"))) {
http.addFilterAt(casFilter(), CasAuthenticationFilter.class);
http.addFilterBefore(requestSingleLogoutFilter(), LogoutFilter.class);
// http.addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);
}

if (Arrays.stream(environment.getActiveProfiles()).anyMatch(p -> p.equalsIgnoreCase("sso"))) {
http.addFilterBefore(requestHeaderAuthenticationFilter(), LogoutFilter.class);
}
}

@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}

@Bean
public MidPointAccessDeniedHandler accessDeniedHandler() {
return new MidPointAccessDeniedHandler();
}

@Profile({"!ldap", "!cas"})
@Profile("default")
@Conditional(DefaultProfileOnlyCondition.class)
@Bean
public AuthenticationProvider authenticationProvider() {
public AuthenticationProvider midPointAuthenticationProvider() throws Exception {
return new MidPointAuthenticationProvider();
}

Expand All @@ -181,5 +200,57 @@ public AuditedLogoutHandler logoutHandler() {

return handler;
}

@Profile("sso")
@Bean
public RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter() {
RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
filter.setPrincipalRequestHeader(principalRequestHeader);
filter.setAuthenticationManager(authenticationManager);

return filter;
}

@Profile("cas")
@Bean
public CasAuthenticationFilter casFilter() {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);

return filter;
}

@Profile("cas")
@Bean
public LogoutFilter requestSingleLogoutFilter() {
LogoutFilter filter = new LogoutFilter(casServerUrl + "/logout", new SecurityContextLogoutHandler());
filter.setFilterProcessesUrl("/j_spring_cas_security_logout");

return filter;
}

// @Profile("cas")
// @Bean
// public SingleSignOutFilter singleSignOutFilter() {
// SingleSignOutFilter filter = new SingleSignOutFilter();
// filter.setCasServerUrlPrefix(casServerUrl);
//
// return filter;
// }

private static class DefaultProfileOnlyCondition implements Condition {

@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

if (context.getEnvironment() == null) {
return true;
}

String[] activeProfiles = context.getEnvironment().getActiveProfiles();

return !Arrays.stream(activeProfiles).anyMatch(p -> p.equalsIgnoreCase("cas") || p.equalsIgnoreCase("ldap"));
}
}
}

8 changes: 0 additions & 8 deletions gui/admin-gui/src/main/resources/application-cas.yml

This file was deleted.

11 changes: 0 additions & 11 deletions gui/admin-gui/src/main/resources/application-ldap.yml

This file was deleted.

22 changes: 21 additions & 1 deletion gui/admin-gui/src/main/resources/application.yml
Expand Up @@ -20,7 +20,27 @@ server:
auth:
logout:
url: / # NOTE: This URL is relative to application root

## Example SSO header authentication configuration
# sso:
# header: SM_USER
## Example CAS SSO configuration
# cas:
# midpoint:
# url: http://localhost:38080/midpoint
# server:
# url: http://localhost:8080/cas
# ticketValidator: Cas30ServiceTicketValidator
## Example LDAP authentication configuration
# ldap:
# host: ldap://localhost:389/dc=example,dc=com
# manager: cn=admin,dc=example,dc=com
# password: secret
# dn:
# pattern: uid={0},ou=people
#
# search:
# pattern: (uid={0})
# subtree: true

#security:
# enable-csrf: false # default for midpoint is true
Expand Down

0 comments on commit fd04655

Please sign in to comment.