Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow SAML authentication process for deep URLs #63

Open
wants to merge 13 commits into
base: 6.1
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<parent>
<groupId>pentaho</groupId>
<artifactId>pentaho-authentication-provider-samples</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>pentaho-saml-sample</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<packaging>kar</packaging>

<name>Pentaho SAML Authentication Provider .kar</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<parent>
<groupId>pentaho</groupId>
<artifactId>pentaho-authentication-provider-samples</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>pentaho-saml-ss2-proxies-extension</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<packaging>bundle</packaging>

<name>Pentaho SAML SS2 Proxies extension</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@
import org.pentaho.platform.proxy.api.IProxyCreator;
import org.pentaho.platform.spring.security.saml.ss2.proxies.creators.authentication.S2ExpiringUsernameAuthenticationProxyCreator;
import org.pentaho.platform.spring.security.saml.ss2.proxies.creators.authentication.S2SamlAuthenticationProxyCreator;
import org.pentaho.platform.spring.security.saml.ss2.proxies.creators.savedrequest.S2SamlSavedRequestProxyCreator;

public class ProxyCreatorActivator implements BundleActivator {

ServiceRegistration s2SamlAuthenticationProxyServiceRegistration;
ServiceRegistration s2ExpiringUsernameAuthenticationServiceRegistration;
ServiceRegistration s2SamlSavedRequestServiceRegistration;

@Override public void start( BundleContext bundleContext ) throws Exception {

s2SamlAuthenticationProxyServiceRegistration =
bundleContext.registerService( IProxyCreator.class, new S2SamlAuthenticationProxyCreator(), null );

s2SamlSavedRequestServiceRegistration =
bundleContext.registerService( IProxyCreator.class, new S2SamlSavedRequestProxyCreator(), null );

s2ExpiringUsernameAuthenticationServiceRegistration =
bundleContext.registerService( IProxyCreator.class, new S2ExpiringUsernameAuthenticationProxyCreator(), null );
Expand All @@ -26,6 +31,10 @@ public class ProxyCreatorActivator implements BundleActivator {
if( s2SamlAuthenticationProxyServiceRegistration != null ) {
s2SamlAuthenticationProxyServiceRegistration.unregister();
}

if( s2SamlSavedRequestServiceRegistration != null ) {
s2SamlSavedRequestServiceRegistration.unregister();
}

if( s2ExpiringUsernameAuthenticationServiceRegistration != null ) {
s2ExpiringUsernameAuthenticationServiceRegistration.unregister();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package org.pentaho.platform.spring.security.saml.ss2.proxies.creators.savedrequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.security.ui.savedrequest.SavedRequest;

public class S2SamlSavedRequestProxy implements Map.Entry<String,String> {

protected Logger logger = LoggerFactory.getLogger( getClass() );
protected Object target;

protected Method getRequestUrlMethod;
protected Method getServletPathMethod;
protected Method getQueryStringMethod;

public S2SamlSavedRequestProxy( Object target ) {

Assert.notNull( target );

this.target = target;

getRequestUrlMethod = ReflectionUtils.findMethod( target.getClass(), "getRequestUrl" );
getServletPathMethod = ReflectionUtils.findMethod( target.getClass(), "getServletPath" );
getQueryStringMethod = ReflectionUtils.findMethod( target.getClass(), "getQueryString" );
}

public boolean equals(Object o) {
try {
return ((String) getRequestUrlMethod.invoke( target )).equals((String) getRequestUrlMethod.invoke( o ))
&& ((String) getQueryStringMethod.invoke( target )).equals((String) getQueryStringMethod.invoke( o ));

} catch ( IllegalAccessException | InvocationTargetException e ) {
logger.error( e.getMessage(), e );
}

return false;
}

public String getKey() {
return "redirectURL";
}

public String getValue() {
int index = getRequestUrl().indexOf(getServletPath());
String value = getRequestUrl().substring(index);
return value;
}

public int hascode() {
return getValue().hashCode();
}

public String setValue(String value) {
logger.error( "Cannot set value", new Exception());
return null;
}

public String getRequestUrl() {
try {
return (String) getRequestUrlMethod.invoke( target );

} catch ( IllegalAccessException | InvocationTargetException e ) {
logger.error( e.getMessage(), e );
}

return null;
}

public String getServletPath() {
try {
return (String) getServletPathMethod.invoke( target );

} catch ( IllegalAccessException | InvocationTargetException e ) {
logger.error( e.getMessage(), e );
}

return null;
}

public String getQueryString() {
try {
return (String) getQueryStringMethod.invoke( target );

} catch ( IllegalAccessException | InvocationTargetException e ) {
logger.error( e.getMessage(), e );
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.pentaho.platform.spring.security.saml.ss2.proxies.creators.savedrequest;

import java.util.Map;

import org.pentaho.platform.proxy.api.IProxyCreator;
import org.springframework.security.Authentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class S2SamlSavedRequestProxyCreator implements IProxyCreator<Map.Entry<String,String>> {

private Logger logger = LoggerFactory.getLogger( getClass() );

public S2SamlSavedRequestProxyCreator() {
logger.info( "S2SamlSavedRequestProxyCreator ready;" );
}

@Override
public boolean supports( Class aClass ) {
/*
* Supports SavedRequest; Note that this is a spring-security-saml specific SavedRequest implementation
* and there is no spring-security 2.x counterpart to this object ( spring-security-saml requires spring-security 3.x )
*/
return "org.springframework.security.ui.savedrequest.SavedRequest".equals( aClass.getName() );
}

@Override
public S2SamlSavedRequestProxy create( Object o ) {
return new S2SamlSavedRequestProxy( o );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<parent>
<groupId>pentaho</groupId>
<artifactId>pentaho-authentication-provider-samples</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>pentaho-saml-ss4-proxies-extension</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<packaging>bundle</packaging>

<name>Pentaho SAML SS4 Proxies extension</name>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.pentaho.platform.spring.security.saml.ss4.proxies.creators.savedrequest;

import org.pentaho.platform.proxy.api.IProxyCreator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Map.Entry;


public class S4SamlSavedRequestProxyCreator implements IProxyCreator<Map.Entry<String,String>> {

private Logger logger = LoggerFactory.getLogger( getClass() );

public S4SamlSavedRequestProxyCreator() {
logger.info( "S4SamlSavedRequestProxyCreator ready" );
}

public boolean supports( Class aClass ) {
/*
* Supports the *custom* counterpart of spring-security-saml's SamlAuthenticationToken; Note that this
* is a spring-security-saml specific Authentication implementation and there is no direct spring-security 2.x
* counterpart to this object ( spring-security-saml requires spring-security 3.x )
*/
return "org.pentaho.platform.spring.security.saml.ss2.proxies.creators.savedrequest.S2SamlSavedRequestProxy".equals( aClass.getName() );
}

public Map.Entry<String,String> create( Object o ) {

try {

Method getKeyMethod = ReflectionUtils.findMethod( o.getClass(), "getKey" );
Method getValueMethod = ReflectionUtils.findMethod( o.getClass(), "getValue");

return new AbstractMap.SimpleEntry<String, String>((String) getKeyMethod.invoke( o ),(String) getValueMethod.invoke( o ));

} catch ( IllegalAccessException | InvocationTargetException e ) {
logger.error( e.getMessage(), e );
}

return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>pentaho</groupId>
<artifactId>pentaho-authentication-provider-samples</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.providers.ExpiringUsernameAuthenticationToken;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.Assert;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

public class PentahoSamlAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
Expand Down Expand Up @@ -56,7 +59,6 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
SecurityContextHolder.getContext().setAuthentication( authentication );
}


// legacy spring ( i.e. non-osgi spring.framework ) SecurityContext storing

IProxyFactory factory = PentahoSystem.get( IProxyFactory.class );
Expand All @@ -67,7 +69,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo

// pentaho auth storing

logger.info( "synchronizing current IPentahoSession with SecurityContext" ); //$NON-NLS-1$
logger.info( "Synchronizing current IPentahoSession with SecurityContext" ); //$NON-NLS-1$

IPentahoSession pentahoSession = PentahoSessionHolder.getSession();
Assert.notNull( pentahoSession, "PentahoSessionHolder doesn't have a session" );
Expand All @@ -76,10 +78,19 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
// Note: spring-security 2 expects an *array* of GrantedAuthorities ( ss4 uses a list )
pentahoSession.setAttribute( IPentahoSession.SESSION_ROLES,
proxyGrantedAuthorities( factory, authentication.getAuthorities() ) );
logger.info( "IPentahoSession.SESSION_ROLES :"+authentication.getAuthorities() );

// time to create this user's home folder
createUserHomeFolder( authentication.getName() );


Map.Entry<String, String> savedRequestProxy = factory.createProxy( request.getSession().getAttribute("SPRING_SECURITY_SAVED_REQUEST_KEY") );
if( savedRequestProxy != null) {
String requestUrl = savedRequestProxy.getValue();
logger.info( "Request URL: "+requestUrl);
setDefaultTargetUrl(requestUrl);
}

logger.info( "Calling super.onAuthenticationSuccess");
super.onAuthenticationSuccess( request, new SamlOnRedirectUpdateSessionResponseWrapper( response, request, true,
0, securityContextProxy, authentication ), authentication );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@

<!-- Handler deciding where to redirect user after successful login -->
<bean id="successRedirectHandler" class="org.pentaho.platform.spring.security.saml.PentahoSamlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/index.jsp"/>
<!--property name="defaultTargetUrl" value="/index.jsp"/-->
</bean>

<!-- Handler deciding where to redirect user after failed login -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ explicitly covering such access.
<![CDATA[CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/api/repos/dashboards/print=securityContextHolderAwareRequestFilter,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,preAuthenticatedSecurityFilter,httpSessionReuseDetectionFilter,logoutFilter,samlLogoutFilter,samlSingleLogoutFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,authenticationProcessingFilter,basicProcessingFilter,requestParameterProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
/webservices/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilterForWS,filterInvocationInterceptorForWS
/api/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilterForWS,filterInvocationInterceptorForWS
/plugin/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilterForWS,filterInvocationInterceptorForWS
/webservices/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptorForWS
/api/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptorForWS
/plugin/**=securityContextHolderAwareRequestFilterForWS,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,basicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptorForWS
/**=securityContextHolderAwareRequestFilter,httpSessionPentahoSessionContextIntegrationFilter,httpSessionContextIntegrationFilter,httpSessionReuseDetectionFilter,logoutFilter,samlLogoutFilter,samlSingleLogoutFilter,samlMetadataGeneratorFilter,samlWebSSOProcessingFilter,authenticationProcessingFilter,basicProcessingFilter,requestParameterProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor]]>
</value>
</property>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>pentaho</groupId>
<artifactId>pentaho-authentication-provider-samples</artifactId>
<version>6.1-SNAPSHOT</version>
<version>6.1.0.9-307</version>
<packaging>pom</packaging>

<name>Pentaho Authentication Provider Samples Base</name>
Expand Down