Skip to content

Commit

Permalink
Merge pull request #10 from atilling/master
Browse files Browse the repository at this point in the history
Shibboleth 5.1.x Support
  • Loading branch information
dima767 authored Jun 11, 2024
2 parents db74399 + 2bd4df1 commit 82861aa
Show file tree
Hide file tree
Showing 13 changed files with 69 additions and 71 deletions.
Binary file not shown.
Binary file not shown.
35 changes: 15 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## NOTE Documentation and release artifacts are being worked on. As such documenatation and/or artifacts may not match, we thank you for your patience!

## A Shibboleth IdP v4.X plugin for delegating authentication to an external SSO Server using the CAS protocol
## A Shibboleth IdP v5.X plugin for delegating authentication to an external SSO Server using the CAS protocol


This is a Shibboleth IdP external authentication plugin that delegates primary authentication to an external
Expand All @@ -22,7 +22,7 @@ Also, please do note that the Shibboleth IdP v3x+ has support for the CAS protoc
Software Requirements
-------------------------------------------------------------

This minimum supported version of Shibboleth Identity Provider is `4.3.0`.
This minimum supported version of Shibboleth Identity Provider is `5.1.0`.
See [releases](https://github.com/Unicon/shib-cas-authn/releases) to find the the appropriate version.


Expand All @@ -35,9 +35,8 @@ Installation
- Copy the no-conversation-state.jsp file (also found inside this repo in IDP_HOME/edit-webapp) to your IdP's `IDP_HOME/edit-webapp`
- Copy two included jar files (`cas-client-core-x.x.x.jar` and `shib-casuathenticator-x.x.x.jar`) into the `IDP_HOME/edit-webapp/WEB-INF/lib`.
- Copy and Update the IdP's `web.xml`.
- Update the IdP's `external-authn.xml` file.
- (Optional) Update the IdP's `general-authn.xml` file.
- Update the IdP's `idp.properties` file.
- Update the IdP's `global.xml` file.
- Update the IdP's `authn.properties` file.
- Rebuild the war file.

**NOTE:** You should **ALWAYS** refers to the `README.md` file that is [packaged with the release](https://github.com/Unicon/shib-cas-authn/releases) for instructions.
Expand All @@ -64,9 +63,9 @@ Example snippet `web.xml`:
...
```

#### Update the IdP's external-authn.xml file
#### Update the IdP's global.xml file

In the `IDP_HOME/authn/external-authn.xml` file, ensure the context path points to `Authn/External` as shown below.
In the `IDP_HOME/conf/global.xml` file, ensure the context path points to `Authn/External` as shown below.

```xml
<!-- Servlet context-relative path to wherever your implementation lives. -->
Expand All @@ -75,21 +74,10 @@ In the `IDP_HOME/authn/external-authn.xml` file, ensure the context path points
```


#### OPTIONAL Update the IdP's general-authn.xml file

You may also need to ensure the `authn/External` flow is able to accept passive and forced authentication if you wish to use those features. The `authn/External` bean is modified in the `IDP_HOME/authn/general-authn.xml` file as shown below. Note that non browser flow is not possible or supported so it should be false.
#### Update the IdP's authn.properties file

```xml
<bean id="authn/External" parent="shibboleth.AuthenticationFlow"
p:passiveAuthenticationSupported="true"
p:forcedAuthenticationSupported="true"
p:nonBrowserSupported="false" />
```


#### Update the IdP's idp.properties file

1. Set the `idp.authn.flows` to `External` in `IDP_HOME/conf/idp.properties`. Or, for advance cases, add `External` to the list if you have others.
1. Set the `idp.authn.flows` to `External` in `IDP_HOME/conf/authn/authn.properties`. Or, for advance cases, add `External` to the list if you have others.
1. Add new properties for the ShibCas plugin.

```properties
Expand Down Expand Up @@ -118,6 +106,13 @@ shibcas.serverName = https://shibserver.example.edu
# Specify if the Relying Party/Service Provider entityId should be appended as a separate entityId query string parameter
# or embedded in the "service" querystring parameter - `append` (default) or `embed`
# shibcas.entityIdLocation = append
...
idp.authn.Password.passiveAuthenticationSupported = true
idp.authn.Password.forcedAuthenticationSupported = true
...
idp.authn.External.nonBrowserSupported = false


...
```

Expand Down
12 changes: 6 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ apply plugin: 'maven-publish'

defaultTasks 'clean', 'distZip', 'distTar'

sourceCompatibility = 11
targetCompatibility = 11
sourceCompatibility = 17
targetCompatibility = 17

group = 'net.unicon'
version = project.version
Expand All @@ -27,24 +27,24 @@ configurations {
configurations.implementation.transitive = false

dependencies {
implementation "org.jasig.cas.client:cas-client-core:$project.casClientVersion"
implementation "org.apereo.cas.client:cas-client-core:$project.casClientVersion"

compileOnly "javax.servlet:javax.servlet-api:$project.servletVersion"
compileOnly "jakarta.servlet:jakarta.servlet-api:$project.servletVersion"
compileOnly "net.shibboleth.idp:idp-authn-api:$project.shibIdpVersion"
compileOnly "net.shibboleth.idp:idp-saml-api:$project.shibIdpVersion"
compileOnly "org.apache.commons:commons-lang3:$project.commonLangVersion"

testImplementation "junit:junit:$project.junitVersion"
testImplementation "net.shibboleth.idp:idp-authn-api:$project.shibIdpVersion"
testImplementation "net.shibboleth.idp:idp-saml-api:$project.shibIdpVersion"
testImplementation "javax.servlet:javax.servlet-api:$project.servletVersion"
testImplementation "jakarta.servlet:jakarta.servlet-api:$project.servletVersion"
testImplementation "org.mockito:mockito-core:$project.mockitoVersion"
testImplementation "org.powermock:powermock-api-mockito2:$project.powermockVersion"
testImplementation "org.powermock:powermock-module-junit4:$project.powermockVersion"
}

test {
jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED"
jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED", "--add-opens", "java.base/java.lang.reflect=ALL-UNNAMED"
}

distributions {
Expand Down
10 changes: 6 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
version=4.3.1
version=5.0.0

casClientVersion=3.6.4
casClientVersion=4.0.3
commonLangVersion=3.11
junitVersion=4.13.1
mockitoVersion=3.6.28
powermockVersion=2.0.9
servletVersion=4.0.1
shibIdpVersion=4.3.1
servletVersion=6.0.0
shibIdpVersion=5.0.0
org.gradle.jvmargs=-Xmx1536M \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import java.security.Principal;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.unicon.idp.authn.provider.extra;

import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;

/**
* This interface defines the interface a custom parameter builder must adopt. The implementing class needs to build a single string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.apereo.cas.client.authentication.AttributePrincipal;
import org.apereo.cas.client.validation.Assertion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import net.shibboleth.idp.authn.principal.PrincipalEvalPredicateFactory;
import net.shibboleth.idp.authn.principal.PrincipalSupportingComponent;
import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.apereo.cas.client.validation.Assertion;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.saml2.core.AuthnContext;
import org.slf4j.Logger;
Expand All @@ -17,8 +17,8 @@

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashSet;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package net.unicon.idp.externalauth;

import org.jasig.cas.client.validation.Assertion;
import org.apereo.cas.client.validation.Assertion;

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

/**
* This interface defines the public interface for a class that will translate the information from CAS to Shib. The translator
Expand Down
37 changes: 19 additions & 18 deletions src/main/java/net/unicon/idp/externalauth/ShibcasAuthServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
import net.unicon.idp.authn.provider.extra.EntityIdParameterBuilder;
import net.unicon.idp.authn.provider.extra.IParameterBuilder;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas10TicketValidator;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.jasig.cas.client.validation.Cas30ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidationException;
import org.apereo.cas.client.util.CommonUtils;
import org.apereo.cas.client.util.WebUtils;
import org.apereo.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator;
import org.apereo.cas.client.validation.Assertion;
import org.apereo.cas.client.validation.Cas10TicketValidator;
import org.apereo.cas.client.validation.Cas20ServiceTicketValidator;
import org.apereo.cas.client.validation.Cas30ServiceTicketValidator;
import org.apereo.cas.client.validation.TicketValidationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
Expand All @@ -21,13 +22,13 @@
import org.springframework.core.env.Environment;
import org.springframework.web.context.WebApplicationContext;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -64,8 +65,8 @@ public class ShibcasAuthServlet extends HttpServlet {
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
// TODO: We have the opportunity to give back more to Shib than just the PRINCIPAL_NAME_KEY. Identify additional information
try {
final String ticket = CommonUtils.safeGetParameter(request, artifactParameterName);
final String gatewayAttempted = CommonUtils.safeGetParameter(request, "gatewayAttempted");
final String ticket = WebUtils.safeGetParameter(request, artifactParameterName);
final String gatewayAttempted = WebUtils.safeGetParameter(request, "gatewayAttempted");
final String authenticationKey = ExternalAuthentication.startExternalAuthentication(request);
final boolean force = Boolean.parseBoolean(request.getAttribute(ExternalAuthentication.FORCE_AUTHN_PARAM).toString());
final boolean passive = Boolean.parseBoolean(request.getAttribute(ExternalAuthentication.PASSIVE_AUTHN_PARAM).toString());
Expand Down Expand Up @@ -263,7 +264,7 @@ private void buildTranslators(final Environment environment) {
* Use the CAS CommonUtils to build the CAS Service URL.
*/
protected String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response) {
String serviceUrl = CommonUtils.constructServiceUrl(request, response, null, serverName,
String serviceUrl = WebUtils.constructServiceUrl(request, response, null, serverName,
serviceParameterName, artifactParameterName, true);

if ("embed".equalsIgnoreCase(entityIdLocation)) {
Expand All @@ -289,7 +290,7 @@ protected String constructServiceUrl(final HttpServletRequest request, final Htt
if(!requestEntityIdLocation.equals(relayingPartyId)) {
throw new TicketValidationException(String.format("Validation failed. relayingPartyId attribute request %s doesn't match with entityId request parameter %s", relayingPartyId, requestEntityIdLocation));
}
return CommonUtils.constructServiceUrl(request, response, null, serverName, serviceParameterName, artifactParameterName, true);
return WebUtils.constructServiceUrl(request, response, null, serverName, serviceParameterName, artifactParameterName, true);
}
return constructServiceUrl(request, response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import net.shibboleth.idp.authn.ExternalAuthentication;
import net.shibboleth.idp.authn.ExternalAuthenticationException;
import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.jasig.cas.client.validation.Cas30ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidationException;
import org.apereo.cas.client.authentication.AttributePrincipal;
import org.apereo.cas.client.validation.Assertion;
import org.apereo.cas.client.validation.Cas20ServiceTicketValidator;
import org.apereo.cas.client.validation.Cas30ServiceTicketValidator;
import org.apereo.cas.client.validation.TicketValidationException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
Expand All @@ -20,11 +20,11 @@
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
Expand Down

0 comments on commit 82861aa

Please sign in to comment.