Skip to content

Commit

Permalink
Merge branch 'feature/uaa-ldap-authentication' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Filip Hanik committed May 23, 2014
2 parents 2798a09 + b582f22 commit 1c400c2
Show file tree
Hide file tree
Showing 61 changed files with 2,610 additions and 120 deletions.
6 changes: 3 additions & 3 deletions .cobertura-instrument.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ UAA_CLASSPATH=`mvn -pl uaa dependency:build-classpath -P coverage | grep -v "\["

set -x

java -cp $COMMON_CLASSPATH net.sourceforge.cobertura.instrument.Main common/target/classes --ignore CoverageController
java -cp $SCIM_CLASSPATH net.sourceforge.cobertura.instrument.Main scim/target/classes
java -cp $UAA_CLASSPATH net.sourceforge.cobertura.instrument.Main uaa/target/classes
java -cp common/target/classes:$COMMON_CLASSPATH net.sourceforge.cobertura.instrument.Main common/target/classes --ignore CoverageController
java -cp common/target/classes:scim/target/classes:$SCIM_CLASSPATH net.sourceforge.cobertura.instrument.Main scim/target/classes
java -cp common/target/classes:scim/target/classes:uaa/target/classes:$UAA_CLASSPATH net.sourceforge.cobertura.instrument.Main uaa/target/classes
1 change: 1 addition & 0 deletions .run-script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ elif [ "$1" = "stop" ]; then
fi

echo "spring_profiles: $TESTENV" > target/tomcat/webapps/uaa/WEB-INF/classes/uaa.yml
rm -f $CATALINA_OUT
target/tomcat/bin/startup.sh

SLEEP_TIME=120
Expand Down
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ env:
- TESTENV=default,coverage
- TESTENV=mysql,default,coverage
- TESTENV=postgresql,default,coverage
- TESTENV=ldap,default,coverage
- TESTENV=keystone,default,coverage
services:
- mysql
- postgresql
Expand All @@ -22,7 +24,11 @@ before_install:
- mysql -e 'create database uaa;'
- mysql -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('changeme');"
- mysql -e "SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('changeme');"
- if [ "$TESTENV" = "ldap,default,coverage" ]; then ./scripts/ldap/install-ldap.sh; fi
- if [ "$TESTENV" = "keystone,default,coverage" ]; then ./scripts/keystone/install-keystone.sh; fi
install:
- if [ "$TESTENV" = "ldap,default,coverage" ]; then ./scripts/ldap/configure-manifest.sh; fi
- if [ "$TESTENV" = "keystone,default,coverage" ]; then ./scripts/keystone/configure-manifest.sh; fi
- mvn install -DskipTests -P coverage --quiet
- mkdir -p target/tomcat && tar zxf tomcat.tar.gz -C target/tomcat --strip-components 1 && rm -rf target/tomcat/webapps/*
- mvn -Dwar.exploded.dir=`pwd`/target/tomcat/webapps/api --quiet -pl samples/api war:exploded
Expand Down
56 changes: 41 additions & 15 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,31 @@

<dependencies>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>${spring.security.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>${spring.ldap.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core-tiger</artifactId>
<version>${spring.ldap.version}</version>
</dependency>

<dependency>
<groupId>org.apache.directory.api</groupId>
<artifactId>api-ldap-model</artifactId>
<version>${apacheds.api.ldap.model.version}</version>
</dependency>


<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
Expand All @@ -91,6 +116,12 @@
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${spring.security.oauth.version}</version>
<exclusions>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
Expand Down Expand Up @@ -190,21 +221,22 @@
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.2</version>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
<version>1.7.7</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -233,12 +265,6 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* ******************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ******************************************************************************
*/

package org.cloudfoundry.identity.uaa.authentication;

import org.springframework.security.core.AuthenticationException;

public class AuthenticationPolicyRejectionException extends AuthenticationException {
public AuthenticationPolicyRejectionException(String msg, Throwable t) {
super(msg, t);
}

public AuthenticationPolicyRejectionException(String msg) {
super(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.authentication.AuthenticationPolicyRejectionException;
import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication;
import org.cloudfoundry.identity.uaa.authentication.UaaAuthenticationDetails;
import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal;
Expand Down Expand Up @@ -98,7 +99,7 @@ public Authentication authenticate(Authentication req) throws AuthenticationExce
if (!accountLoginPolicy.isAllowed(user, req)) {
logger.warn("Login policy rejected authentication for " + user.getUsername() + ", " + user.getId()
+ ". Ignoring login request.");
BadCredentialsException e = new BadCredentialsException("Login policy rejected authentication");
AuthenticationPolicyRejectionException e = new AuthenticationPolicyRejectionException("Login policy rejected authentication");
publish(new AuthenticationFailureLockedEvent(req, e));
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
* ******************************************************************************
* Cloud Foundry
* Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
*
* This product is licensed to you under the Apache License, Version 2.0 (the "License").
* You may not use this product except in compliance with the License.
*
* This product includes a number of subcomponents with
* separate copyright notices and license terms. Your use of these
* subcomponents is subject to the terms and conditions of the
* subcomponent's license, as noted in the LICENSE file.
* ******************************************************************************
*/

package org.cloudfoundry.identity.uaa.authentication.manager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import java.util.List;

/**
* Chained authentication manager that works of simple conditions
*/
public class ChainedAuthenticationManager implements AuthenticationManager {
public static final String IF_PREVIOUS_FALSE = "ifPreviousFalse";
public static final String IF_PREVIOUS_TRUE = "ifPreviousTrue";

protected final Log logger = LogFactory.getLog(getClass());

private AuthenticationManagerConfiguration[] delegates;

public ChainedAuthenticationManager() {
}

public AuthenticationManagerConfiguration[] getDelegates() {
return delegates;
}

public void setDelegates(AuthenticationManagerConfiguration[] delegates) {
this.delegates = delegates;
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication == null) {
return authentication;
}
UsernamePasswordAuthenticationToken output = null;
if (authentication instanceof UsernamePasswordAuthenticationToken) {
output = (UsernamePasswordAuthenticationToken) authentication;
} else {
output = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(),
authentication.getAuthorities());
output.setAuthenticated(authentication.isAuthenticated());
output.setDetails(authentication.getDetails());
}
boolean authenticated = false;
Authentication auth = null;
AuthenticationException lastException = null;
boolean lastResult = false;
boolean shallContinue = true;
for (int i=0; shallContinue && i<delegates.length; i++) {

boolean shallAuthenticate = (i==0) ||
(lastResult && IF_PREVIOUS_TRUE.equals(delegates[i].getRequired())) ||
((!lastResult) && IF_PREVIOUS_FALSE.equals(delegates[i].getRequired()));

if (shallAuthenticate) {
if (logger.isDebugEnabled()) {
logger.debug("Attempting chained authentication of " + output + " with manager:" + delegates[i].getAuthenticationManager() + " required:" + delegates[i].getRequired());
}
Authentication thisAuth = null;
try {
thisAuth = delegates[i].getAuthenticationManager().authenticate(auth!=null ? auth : output);
} catch (AuthenticationException x) {
if (logger.isDebugEnabled()) {
logger.debug("Chained authentication exception:", x);
}
lastException = x;
if (delegates[i].getStopIf()!=null && delegates[i].getStopIf().isAssignableFrom(x.getClass())) {
shallContinue = false;
}
}
lastResult = thisAuth != null && thisAuth.isAuthenticated();

if (lastResult) {
authenticated = true;
auth = thisAuth;
}
} else {
lastResult = false;
}
if (logger.isDebugEnabled()) {
logger.debug("Chained Authentication status of "+output+ " with manager:"+delegates[i]+"; Authenticated:"+authenticated);
}
}
if (authenticated) {
return auth;
} else if (lastException!=null) {
//we had at least one authentication exception, throw it
throw lastException;
} else {
//not authenticated, but return the last of the result
return auth;
}
}

public static class AuthenticationManagerConfiguration {
private AuthenticationManager authenticationManager;
private String required = null;
private Class<? extends AuthenticationException> stopIf;

public Class<? extends AuthenticationException> getStopIf() {
return stopIf;
}

public void setStopIf(Class<? extends AuthenticationException> stopIf) {
this.stopIf = stopIf;
}

public AuthenticationManagerConfiguration() {
}

public AuthenticationManagerConfiguration(AuthenticationManager authenticationManager, String required) {
this.authenticationManager = authenticationManager;
this.required = required;
}

public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}

public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}

public String getRequired() {
return required;
}

public void setRequired(String required) {
boolean valid = false;
if (IF_PREVIOUS_FALSE.equals(required) ||
IF_PREVIOUS_TRUE.equals(required)) {
valid = true;
}

if (!valid) {
throw new IllegalArgumentException(required+ " is not a valid value for property 'required'");
}

this.required = required;
}
}

}
Loading

0 comments on commit 1c400c2

Please sign in to comment.