diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0f7628b27..1670cb60e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -24,52 +24,3 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 - ignore: - - dependency-name: org.springframework.boot:spring-boot-dependencies - versions: - - 2.4.4 - - dependency-name: org.springframework:spring-beans - versions: - - 5.3.5 - - dependency-name: org.springframework:spring-test - versions: - - 5.3.5 - - dependency-name: org.springframework:spring-web - versions: - - 5.3.5 - - dependency-name: org.springframework:spring-context - versions: - - 5.3.5 - - dependency-name: org.springframework:spring-core - versions: - - 5.3.5 - - dependency-name: org.apache.tomcat.embed:tomcat-embed-core - versions: - - 10.0.0 - - 10.0.2 - - 10.0.4 - - dependency-name: org.apache.tomcat:tomcat-catalina - versions: - - 10.0.0 - - 10.0.2 - - 10.0.4 - - dependency-name: org.eclipse.jetty:apache-jsp - versions: - - 11.0.0 - - 11.0.1 - - dependency-name: org.eclipse.jetty:jetty-annotations - versions: - - 11.0.0 - - 11.0.1 - - dependency-name: org.eclipse.jetty:jetty-plus - versions: - - 11.0.0 - - 11.0.1 - - dependency-name: org.eclipse.jetty:jetty-webapp - versions: - - 11.0.0 - - 11.0.1 - - dependency-name: org.eclipse.jetty:jetty-security - versions: - - 11.0.0 - - 11.0.1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6b964923..25303d615 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ env: SONATYPE_USER: ${{ secrets.SONATYPE_USER }} GH_TOKEN: ${{ secrets.GH_PAGES_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - JDK_CURRENT: 8 + JDK_CURRENT: 21 ########################################################################## @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 1 steps: - - uses: styfle/cancel-workflow-action@0.7.0 + - uses: styfle/cancel-workflow-action@0.13.1 with: access_token: ${{ github.token }} build: @@ -55,13 +55,14 @@ jobs: runs-on: ${{ matrix.os }} needs: cancel-previous-runs steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 # - name: Setup tmate session # uses: mxschmitt/action-tmate@v3 - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v5 with: java-version: ${{ env.JDK_CURRENT }} + distribution: 'temurin' - name: Build with Gradle run: mvn clean install @@ -72,11 +73,12 @@ jobs: needs: [build] if: ${{ github.event_name == 'push' }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v5 with: java-version: ${{ env.JDK_CURRENT }} + distribution: 'temurin' - name: Publish SNAPSHOTs if: ${{ env.SONATYPE_USER != null && env.SONATYPE_PWD != null }} run: mvn deploy --settings ./.github/workflows/settings.xml diff --git a/.mergify.yml b/.mergify.yml index 2f71fe38e..f9be0951e 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,32 +1,12 @@ -# -# Licensed to Apereo under one or more contributor license -# agreements. See the NOTICE file distributed with this work -# for additional information regarding copyright ownership. -# Apereo 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 the following location: -# -# 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. -# - pull_request_rules: -- name: automatic merge - conditions: - - status-success=build (ubuntu-latest) - - status-success=WIP - - "#changes-requested-reviews-by=0" - - base=master - - label=dependencies - actions: - merge: - method: merge - strict: false - delete_head_branch: \ No newline at end of file + - name: automatic merge + conditions: + - status-success=build (ubuntu-latest) + - status-success=WIP + - "#changes-requested-reviews-by=0" + - base=master + - label=dependencies + actions: + merge: + method: merge + update: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ed6686943..000000000 --- a/.travis.yml +++ /dev/null @@ -1,38 +0,0 @@ -# -# Licensed to Jasig under one or more contributor license -# agreements. See the NOTICE file distributed with this work -# for additional information regarding copyright ownership. -# Jasig 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 the following location: -# -# 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. -# - -language: java -sudo: required -branches: - only: - - master -cache: - directories: - - "$HOME/.m2/repository" -script: "mvn install --settings travis/settings.xml" -jdk: - - openjdk8 -env: - global: - - secure: "JM/FMiec3GYShrMlJQSW2QG208+V0GCAj2bsP5eF8q4yzgp6o4rT+r57KDIDD6MapRN+G1Pnl3WPcS0aQYnwOhPg4tA2De1bFUPaJltP47eHFfblpjZeHMxcauCQ6BwFFr8yuC0ORsYCW3TOK00Mxq4CRlTlg5iclzHyS/pnkLI=" - - secure: "eXfgf3v8Kw/L22DO39Y61os13bfNpop8Xpkmz+HZ1djQWavOkRn58gSg8EVjBYRPOrTuEbhEWb+s3qpx8j3qRdi6roMs9MTr5gEPTAyjTtJ/Zv1qhJ6OlEl2w5c2fRMsk5cB//mtxtZ+qMaz6sdZI2csbQ2xlhjz4AbGQL5i1lY=" - -after_success: -- chmod -R 777 ./travis/deploy-to-sonatype.sh -- ./travis/deploy-to-sonatype.sh diff --git a/LICENSE b/LICENSE index eef349383..52eeacd65 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,8 @@ ==== - Licensed to Jasig under one or more contributor license + Licensed to Apereo under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. - Jasig licenses this file to you under the Apache License, + Apereo 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: @@ -47,4 +47,4 @@ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/NOTICE b/NOTICE index 052663a24..c5b762607 100644 --- a/NOTICE +++ b/NOTICE @@ -40,19 +40,19 @@ This project includes: Jackson-core under The Apache Software License, Version 2.0 jackson-databind under The Apache Software License, Version 2.0 Jakarta Annotations API under EPL 2.0 or GPL2 w/ CPE - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - Distributed Proxy Storage Support: EhCache under Apache License Version 2.0 - Jasig CAS Client for Java - Distributed Proxy Storage Support: Memcached under Apache License Version 2.0 - Jasig CAS Client for Java - JBoss Integration under Apache License Version 2.0 - Jasig CAS Client for Java - Jetty Container Integration under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Spring Boot Support under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 6.x Integration under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 7.x Integration under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 8.5.x Integration under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 8.x Integration under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 9.0.x Integration under Apache License Version 2.0 + Apereo CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 + Apereo CAS Client for Java - Core under Apache License Version 2.0 + Apereo CAS Client for Java - Distributed Proxy Storage Support: EhCache under Apache License Version 2.0 + Apereo CAS Client for Java - Distributed Proxy Storage Support: Memcached under Apache License Version 2.0 + Apereo CAS Client for Java - JBoss Integration under Apache License Version 2.0 + Apereo CAS Client for Java - Jetty Container Integration under Apache License Version 2.0 + Apereo CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 + Apereo CAS Client for Java - Spring Boot Support under Apache License Version 2.0 + Apereo CAS Client for Java - Tomcat 6.x Integration under Apache License Version 2.0 + Apereo CAS Client for Java - Tomcat 7.x Integration under Apache License Version 2.0 + Apereo CAS Client for Java - Tomcat 8.5.x Integration under Apache License Version 2.0 + Apereo CAS Client for Java - Tomcat 8.x Integration under Apache License Version 2.0 + Apereo CAS Client for Java - Tomcat 9.0.x Integration under Apache License Version 2.0 Java Servlet API under CDDL + GPLv2 with classpath exception JavaBeans Activation Framework API jar under CDDL/GPLv2+CE javax.annotation API under CDDL + GPLv2 with classpath exception @@ -74,7 +74,6 @@ This project includes: Jetty :: Utilities :: Ajax(JSON) under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 Jetty :: Webapp Application Support under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 Jetty :: XML utilities under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Joda-Time under Apache License, Version 2.0 JUL to SLF4J bridge under MIT License JUnit under Eclipse Public License 1.0 Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License diff --git a/README.md b/README.md index af86b9447..f2d4904b6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Java Apereo CAS Client [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.jasig.cas.client/cas-client-core/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/org.jasig.cas.client/cas-client) +# Java Apereo CAS Client ## Intro @@ -7,7 +7,7 @@ This is the official home of the Java Apereo CAS client. The client consists of All client artifacts are published to Maven central. Depending on functionality, applications will need include one or more of the listed dependencies in their configuration. -## Build [![Build Status](https://travis-ci.org/apereo/java-cas-client.png?branch=master)](https://travis-ci.org/apereo/java-cas-client) +## Build ```bash git clone git@github.com:apereo/java-cas-client.git @@ -15,9 +15,6 @@ cd java-cas-client mvn clean package ``` -Please note that to be deployed in Maven Central, we mark a number of JARs as provided (related to JBoss and Memcache -Clients). In order to build the clients, you must enable the commented out repositories in the appropriate `pom.xml` -files in the modules (`cas-client-integration-jboss` and `cas-client-support-distributed-memcached`) or follow the instructions on how to install the file manually. ## Components @@ -26,7 +23,7 @@ files in the modules (`cas-client-integration-jboss` and `cas-client-support-dis ```xml - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${java.cas.client.version} @@ -36,7 +33,7 @@ files in the modules (`cas-client-integration-jboss` and `cas-client-support-dis ```xml - org.jasig.cas.client + org.apereo.cas.client cas-client-support-saml ${java.cas.client.version} @@ -46,7 +43,7 @@ files in the modules (`cas-client-integration-jboss` and `cas-client-support-dis ```xml - org.jasig.cas.client + org.apereo.cas.client cas-client-support-distributed-ehcache ${java.cas.client.version} @@ -56,87 +53,17 @@ files in the modules (`cas-client-integration-jboss` and `cas-client-support-dis ```xml - org.jasig.cas.client + org.apereo.cas.client cas-client-support-distributed-memcached ${java.cas.client.version} ``` -- Atlassian integration (Deprecated) is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-atlassian - ${java.cas.client.version} - -``` - -- JBoss integration is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-jboss - ${java.cas.client.version} - -``` - -- Tomcat 6 integration is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-tomcat-v6 - ${java.cas.client.version} - -``` - -- Tomcat 7 is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-tomcat-v7 - ${java.cas.client.version} - -``` - -- Tomcat 8.0.x is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-tomcat-v8 - ${java.cas.client.version} - -``` - -- Tomcat 8.5.x is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-tomcat-v85 - ${java.cas.client.version} - -``` - -- Tomcat 9.0.x is provided by this dependency: - -```xml - - org.jasig.cas.client - cas-client-integration-tomcat-v90 - ${java.cas.client.version} - -``` - - Spring Boot AutoConfiguration is provided by this dependency: ```xml - org.jasig.cas.client + org.apereo.cas.client cas-client-support-springboot ${java.cas.client.version} @@ -187,14 +114,14 @@ The client can be configured in `web.xml` via a series of `context-param`s and f An example application that is protected by the client is [available here](https://github.com/UniconLabs/cas-sample-java-webapp). - -#### org.jasig.cas.client.authentication.AuthenticationFilter + +#### org.apereo.cas.client.authentication.AuthenticationFilter The `AuthenticationFilter` is what detects whether a user needs to be authenticated or not. If a user needs to be authenticated, it will redirect the user to the CAS server. ```xml CAS Authentication Filter - org.jasig.cas.client.authentication.AuthenticationFilter + org.apereo.cas.client.authentication.AuthenticationFilter casServerUrlPrefix https://battags.ad.ess.rutgers.edu:8443/cas @@ -210,43 +137,42 @@ The `AuthenticationFilter` is what detects whether a user needs to be authentica ``` -| Property | Description | Required -|----------|-------|----------- -| `casServerUrlPrefix` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes (unless `casServerLoginUrl` is set) -| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login`. This overrides `casServerUrlPrefix`, if set. | Yes (unless `casServerUrlPrefix` is set) -| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes -| `service` | The service URL to send to the CAS server, i.e. `https://localhost:8443/yourwebapp/index.html` | No -| `renew` | specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No -| `gateway ` | specifies whether `gateway=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all) | No -| `artifactParameterName ` | specifies the name of the request parameter on where to find the artifact (i.e. `ticket`). | No -| `serviceParameterName ` | specifies the name of the request parameter on where to find the service (i.e. `service`) | No -| `encodeServiceUrl ` | Whether the client should auto encode the service url. Defaults to `true` | No -| `ignorePattern` | Defines the url pattern to ignore, when intercepting authentication requests. | No -| `ignoreUrlPatternType` | Defines the type of the pattern specified. Defaults to `REGEX`. Other types are `CONTAINS`, `EXACT`, `FULL_REGEX`. Can also accept a fully-qualified class name that implements `UrlPatternMatcherStrategy`. | No -| `gatewayStorageClass` | The storage class used to record gateway requests | No -| `authenticationRedirectStrategyClass` | The class name of the component to decide how to handle authn redirects to CAS | No -| `method` | The method used by the CAS server to send the user back to the application. Defaults to `null` | No +| Property | Description | Required | +|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------| +| `casServerUrlPrefix` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes (unless `casServerLoginUrl` is set) | +| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login`. This overrides `casServerUrlPrefix`, if set. | Yes (unless `casServerUrlPrefix` is set) | +| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes | +| `service` | The service URL to send to the CAS server, i.e. `https://localhost:8443/yourwebapp/index.html` | No | +| `renew` | specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No | +| `gateway ` | specifies whether `gateway=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all) | No | +| `artifactParameterName ` | specifies the name of the request parameter on where to find the artifact (i.e. `ticket`). | No | +| `serviceParameterName ` | specifies the name of the request parameter on where to find the service (i.e. `service`) | No | +| `encodeServiceUrl ` | Whether the client should auto encode the service url. Defaults to `true` | No | +| `ignorePattern` | Defines the url pattern to ignore, when intercepting authentication requests. | No | +| `ignoreUrlPatternType` | Defines the type of the pattern specified. Defaults to `REGEX`. Other types are `CONTAINS`, `EXACT`, `FULL_REGEX`. Can also accept a fully-qualified class name that implements `UrlPatternMatcherStrategy`. | No | +| `gatewayStorageClass` | The storage class used to record gateway requests | No | +| `authenticationRedirectStrategyClass` | The class name of the component to decide how to handle authn redirects to CAS | No | +| `method` | The method used by the CAS server to send the user back to the application. Defaults to `null` | No | ##### Ignore Patterns The following types are supported: -| Type | Description -|----------|------- -| `REGEX` | Matches the URL the `ignorePattern` using `Matcher#find()`. It matches the next occurrence within the substring that matches the regex. -| `CONTAINS` | Uses the `String#contains()` operation to determine if the url contains the specified pattern. Behavior is case-sensitive. -| `EXACT` | Uses the `String#equals()` operation to determine if the url exactly equals the specified pattern. Behavior is case-sensitive. -| `FULL_REGEX` | Matches the URL the `ignorePattern` using `Matcher#matches()`. It matches the expression against the entire string as it implicitly add a `^` at the start and `$` at the end of the pattern, so it will not match substring or part of the string. `^` and `$` are meta characters that represents start of the string and end of the string respectively. +| Type | Description | +|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `REGEX` | Matches the URL the `ignorePattern` using `Matcher#find()`. It matches the next occurrence within the substring that matches the regex. | +| `CONTAINS` | Uses the `String#contains()` operation to determine if the url contains the specified pattern. Behavior is case-sensitive. | +| `EXACT` | Uses the `String#equals()` operation to determine if the url exactly equals the specified pattern. Behavior is case-sensitive. | +| `FULL_REGEX` | Matches the URL the `ignorePattern` using `Matcher#matches()`. It matches the expression against the entire string as it implicitly add a `^` at the start and `$` at the end of the pattern, so it will not match substring or part of the string. `^` and `$` are meta characters that represents start of the string and end of the string respectively. | - - -#### org.jasig.cas.client.authentication.Saml11AuthenticationFilter + +#### org.apereo.cas.client.authentication.Saml11AuthenticationFilter The SAML 1.1 `AuthenticationFilter` is what detects whether a user needs to be authenticated or not. If a user needs to be authenticated, it will redirect the user to the CAS server. ```xml CAS Authentication Filter - org.jasig.cas.client.authentication.Saml11AuthenticationFilter + org.apereo.cas.client.authentication.Saml11AuthenticationFilter casServerLoginUrl https://somewhere.cas.edu:8443/cas/login @@ -262,27 +188,27 @@ The SAML 1.1 `AuthenticationFilter` is what detects whether a user needs to be a ``` -| Property | Description | Required -|----------|-------|----------- -| `casServerUrlPrefix` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes (unless `casServerLoginUrl` is set) -| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login`. This overrides `casServerUrlPrefix`, if set. | Yes (unless `casServerUrlPrefix` is set) -| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes -| `service` | The service URL to send to the CAS server, i.e. `https://localhost:8443/yourwebapp/index.html` | No -| `renew` | specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No -| `gateway ` | specifies whether `gateway=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all) | No -| `artifactParameterName ` | specifies the name of the request parameter on where to find the artifact (i.e. `SAMLart`). | No -| `serviceParameterName ` | specifies the name of the request parameter on where to find the service (i.e. `TARGET`) | No -| `encodeServiceUrl ` | Whether the client should auto encode the service url. Defaults to `true` | No -| `method` | The method used by the CAS server to send the user back to the application. Defaults to `null` | No - - -#### org.jasig.cas.client.validation.Cas10TicketValidationFilter +| Property | Description | Required | +|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------| +| `casServerUrlPrefix` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes (unless `casServerLoginUrl` is set) | +| `casServerLoginUrl` | Defines the location of the CAS server login URL, i.e. `https://localhost:8443/cas/login`. This overrides `casServerUrlPrefix`, if set. | Yes (unless `casServerUrlPrefix` is set) | +| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes | +| `service` | The service URL to send to the CAS server, i.e. `https://localhost:8443/yourwebapp/index.html` | No | +| `renew` | specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No | +| `gateway ` | specifies whether `gateway=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all) | No | +| `artifactParameterName ` | specifies the name of the request parameter on where to find the artifact (i.e. `SAMLart`). | No | +| `serviceParameterName ` | specifies the name of the request parameter on where to find the service (i.e. `TARGET`) | No | +| `encodeServiceUrl ` | Whether the client should auto encode the service url. Defaults to `true` | No | +| `method` | The method used by the CAS server to send the user back to the application. Defaults to `null` | No | + + +#### org.apereo.cas.client.validation.Cas10TicketValidationFilter Validates tickets using the CAS 1.0 Protocol. ```xml CAS Validation Filter - org.jasig.cas.client.validation.Cas10TicketValidationFilter + org.apereo.cas.client.validation.Cas10TicketValidationFilter casServerUrlPrefix https://somewhere.cas.edu:8443/cas @@ -298,26 +224,26 @@ Validates tickets using the CAS 1.0 Protocol. ``` -| Property | Description | Required -|----------|-------|----------- -| `casServerUrlPrefix ` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes -| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. `https://localhost:8443` (you must include the protocol, but port is optional if it's a standard port). | Yes -| `renew` | Specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No -| `redirectAfterValidation ` | Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to `true`. | No -| `useSession ` | Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to `true`. | No -| `exceptionOnValidationFailure ` | Whether to throw an exception or not on ticket validation failure. Defaults to `true`. | No -| `sslConfigFile` | A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for `protocol` which defaults to `SSL`, `keyStoreType`, `keyStorePath`, `keyStorePass`, `keyManagerType` which defaults to `SunX509` and `certificatePassword`. | No. -| `encoding` | Specifies the encoding charset the client should use | No -| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No - - -#### org.jasig.cas.client.validation.Saml11TicketValidationFilter +| Property | Description | Required | +|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `casServerUrlPrefix ` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes | +| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. `https://localhost:8443` (you must include the protocol, but port is optional if it's a standard port). | Yes | +| `renew` | Specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No | +| `redirectAfterValidation ` | Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to `true`. | No | +| `useSession ` | Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to `true`. | No | +| `exceptionOnValidationFailure ` | Whether to throw an exception or not on ticket validation failure. Defaults to `true`. | No | +| `sslConfigFile` | A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for `protocol` which defaults to `SSL`, `keyStoreType`, `keyStorePath`, `keyStorePass`, `keyManagerType` which defaults to `SunX509` and `certificatePassword`. | No. | +| `encoding` | Specifies the encoding charset the client should use | No | +| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No | + + +#### org.apereo.cas.client.validation.Saml11TicketValidationFilter Validates tickets using the SAML 1.1 protocol. ```xml CAS Validation Filter - org.jasig.cas.client.validation.Saml11TicketValidationFilter + org.apereo.cas.client.validation.Saml11TicketValidationFilter casServerUrlPrefix https://battags.ad.ess.rutgers.edu:8443/cas @@ -333,21 +259,21 @@ Validates tickets using the SAML 1.1 protocol. ``` -| Property | Description | Required -|----------|-------|----------- -| `casServerUrlPrefix ` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes -| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. `https://localhost:8443` (you must include the protocol, but port is optional if it's a standard port). | Yes -| `renew` | Specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No -| `redirectAfterValidation ` | Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to `true`. | No -| `useSession ` | Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to `true`. | No -| `exceptionOnValidationFailure ` | whether to throw an exception or not on ticket validation failure. Defaults to `true` | No -| `tolerance ` | The tolerance for drifting clocks when validating SAML tickets. Note that 10 seconds should be more than enough for most environments that have NTP time synchronization. Defaults to `1000 msec` | No -| `sslConfigFile` | A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for `protocol` which defaults to `SSL`, `keyStoreType`, `keyStorePath`, `keyStorePass`, `keyManagerType` which defaults to `SunX509` and `certificatePassword`. | No. -| `encoding` | Specifies the encoding charset the client should use | No -| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No - - -#### org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter +| Property | Description | Required | +|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `casServerUrlPrefix ` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes | +| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. `https://localhost:8443` (you must include the protocol, but port is optional if it's a standard port). | Yes | +| `renew` | Specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No | +| `redirectAfterValidation ` | Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to `true`. | No | +| `useSession ` | Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to `true`. | No | +| `exceptionOnValidationFailure ` | whether to throw an exception or not on ticket validation failure. Defaults to `true` | No | +| `tolerance ` | The tolerance for drifting clocks when validating SAML tickets. Note that 10 seconds should be more than enough for most environments that have NTP time synchronization. Defaults to `1000 msec` | No | +| `sslConfigFile` | A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for `protocol` which defaults to `SSL`, `keyStoreType`, `keyStorePath`, `keyStorePass`, `keyManagerType` which defaults to `SunX509` and `certificatePassword`. | No. | +| `encoding` | Specifies the encoding charset the client should use | No | +| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No | + + +#### org.apereo.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter Validates the tickets using the CAS 2.0 protocol. If you provide either the `acceptAnyProxy` or the `allowedProxyChains` parameters, a `Cas20ProxyTicketValidator` will be constructed. Otherwise a general `Cas20ServiceTicketValidator` will be constructed that does not accept proxy tickets. **Note**: If you are using proxy validation, you should place the `filter-mapping` of the validation filter before the authentication filter. @@ -355,7 +281,7 @@ Validates the tickets using the CAS 2.0 protocol. If you provide either the `acc ```xml CAS Validation Filter - org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter + org.apereo.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter casServerUrlPrefix https://battags.ad.ess.rutgers.edu:8443/cas @@ -371,42 +297,85 @@ Validates the tickets using the CAS 2.0 protocol. If you provide either the `acc ``` -| Property | Description | Required -|----------|-------|----------- -| `casServerUrlPrefix ` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes -| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. `https://localhost:8443` (you must include the protocol, but port is optional if it's a standard port). | Yes -| `renew` | Specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No -| `redirectAfterValidation ` | Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to `true`. | No -| `useSession ` | Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to `true`. | No -| `exceptionOnValidationFailure ` | whether to throw an exception or not on ticket validation failure. Defaults to `true` | No -| `proxyReceptorUrl ` | The URL to watch for `PGTIOU/PGT` responses from the CAS server. Should be defined from the root of the context. For example, if your application is deployed in `/cas-client-app` and you want the proxy receptor URL to be `/cas-client-app/my/receptor` you need to configure proxyReceptorUrl to be `/my/receptor`. | No -| `acceptAnyProxy ` | Specifies whether any proxy is OK. Defaults to `false`. | No -| `allowedProxyChains ` | Specifies the proxy chain. Each acceptable proxy chain should include a space-separated list of URLs (for exact match) or regular expressions of URLs (starting by the `^` character). Each acceptable proxy chain should appear on its own line. | No -| `proxyCallbackUrl` | The callback URL to provide the CAS server to accept Proxy Granting Tickets. | No -| `proxyGrantingTicketStorageClass ` | Specify an implementation of the ProxyGrantingTicketStorage class that has a no-arg constructor. | No -| `sslConfigFile` | A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for `protocol` which defaults to `SSL`, `keyStoreType`, `keyStorePath`, `keyStorePass`, `keyManagerType` which defaults to `SunX509` and `certificatePassword`. | No. -| `encoding` | Specifies the encoding charset the client should use | No -| `secretKey` | The secret key used by the `proxyGrantingTicketStorageClass` if it supports encryption. | No -| `cipherAlgorithm` | The algorithm used by the `proxyGrantingTicketStorageClass` if it supports encryption. Defaults to `DESede` | No -| `millisBetweenCleanUps` | Startup delay for the cleanup task to remove expired tickets from the storage. Defaults to `60000 msec` | No -| `ticketValidatorClass` | Ticket validator class to use/create | No -| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No -| `privateKeyPath` | The path to a private key to decrypt PGTs directly sent encrypted as an attribute | No -| `privateKeyAlgorithm` | The algorithm of the private key. Defaults to `RSA` | No - -#### org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter +| Property | Description | Required | +|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `casServerUrlPrefix ` | The start of the CAS server URL, i.e. `https://localhost:8443/cas` | Yes | +| `serverName` | The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. `https://localhost:8443` (you must include the protocol, but port is optional if it's a standard port). | Yes | +| `renew` | Specifies whether `renew=true` should be sent to the CAS server. Valid values are either `true/false` (or no value at all). Note that `renew` cannot be specified as local `init-param` setting. | No | +| `redirectAfterValidation ` | Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to `true`. | No | +| `useSession ` | Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to `true`. | No | +| `exceptionOnValidationFailure ` | whether to throw an exception or not on ticket validation failure. Defaults to `true` | No | +| `proxyReceptorUrl ` | The URL to watch for `PGTIOU/PGT` responses from the CAS server. Should be defined from the root of the context. For example, if your application is deployed in `/cas-client-app` and you want the proxy receptor URL to be `/cas-client-app/my/receptor` you need to configure proxyReceptorUrl to be `/my/receptor`. | No | +| `acceptAnyProxy ` | Specifies whether any proxy is OK. Defaults to `false`. | No | +| `allowedProxyChains ` | Specifies the proxy chain. Each acceptable proxy chain should include a space-separated list of URLs (for exact match) or regular expressions of URLs (starting by the `^` character). Each acceptable proxy chain should appear on its own line. | No | +| `proxyCallbackUrl` | The callback URL to provide the CAS server to accept Proxy Granting Tickets. | No | +| `proxyGrantingTicketStorageClass ` | Specify an implementation of the ProxyGrantingTicketStorage class that has a no-arg constructor. | No | +| `sslConfigFile` | A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for `protocol` which defaults to `SSL`, `keyStoreType`, `keyStorePath`, `keyStorePass`, `keyManagerType` which defaults to `SunX509` and `certificatePassword`. | No. | +| `encoding` | Specifies the encoding charset the client should use | No | +| `secretKey` | The secret key used by the `proxyGrantingTicketStorageClass` if it supports encryption. | No | +| `cipherAlgorithm` | The algorithm used by the `proxyGrantingTicketStorageClass` if it supports encryption. Defaults to `DESede` | No | +| `millisBetweenCleanUps` | Startup delay for the cleanup task to remove expired tickets from the storage. Defaults to `60000 msec` | No | +| `ticketValidatorClass` | Ticket validator class to use/create | No | +| `hostnameVerifier` | Hostname verifier class name, used when making back-channel calls | No | +| `privateKeyPath` | The path to a private key to decrypt PGTs directly sent encrypted as an attribute | No | +| `privateKeyAlgorithm` | The algorithm of the private key. Defaults to `RSA` | No | + +#### org.apereo.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter Validates the tickets using the CAS 3.0 protocol. If you provide either the `acceptAnyProxy` or the `allowedProxyChains` parameters, a `Cas30ProxyTicketValidator` will be constructed. Otherwise a general `Cas30ServiceTicketValidator` will be constructed that does not accept proxy tickets. Supports all configurations that are available for `Cas20ProxyReceivingTicketValidationFilter`. -#### org.jasig.cas.client.validation.json.Cas30JsonProxyReceivingTicketValidationFilter -Indentical to `Cas30ProxyReceivingTicketValidationFilter`, yet the filter is able to accept validation responses from CAS +#### org.apereo.cas.client.validation.Cas30JsonProxyReceivingTicketValidationFilter +Identical to `Cas30ProxyReceivingTicketValidationFilter`, yet the filter is able to accept validation responses from CAS that are formatted as JSON per guidelines laid out by the CAS protocol. See the [protocol documentation](https://apereo.github.io/cas/5.1.x/protocol/CAS-Protocol-Specification.html) for more info. + +#### org.apereo.cas.client.validation.CasJWTTicketValidationFilter +Validates service tickets that issued by the CAS server as JWTs. + +Supported JWTs are: + +- The JWT must be signed and encrypted, in that order, or... +- The JWT must be encrypted and signed, in that order, or... +- The JWT must be encrypted. + +```xml + + CAS Validation Filter + org.apereo.cas.client.validation.CasJWTTicketValidationFilter + + signingKey + ... + + + encryptionKey + ... + + + + CAS Validation Filter + /* + +``` + +| Property | Description | Required | +|---------------------------|------------------------------------------------------------------------------------------|----------| +| `signingKey ` | The signing key. Only `AES` secret keys are supported. | Yes | +| `encryptionKey ` | The encryption key. Only `AES` secret keys are supported. | Yes | +| `expectedIssuer ` | `iss` claim value that is required to match what is in the JWT. | Yes | +| `expectedAudience ` | `aud` claim value that is required to match what is in the JWT. | Yes | +| `encryptionKeyAlgorithm ` | Default is `AES`. | No | +| `encryptionKeyAlgorithm ` | Default is `AES`. | No | +| `requiredClaims ` | Default is `sub,aud,iat,jti,exp,iss`. | No | +| `base64EncryptionKey ` | If encryption key should be base64-decoded first. Default is `true`. | No | +| `base64SigningKey ` | If encryption key should be base64-decoded first. Default is `false`. | No | +| `maxClockSkew ` | Maximum acceptable clock skew when validating expiration dates. Default is `60` seconds. | No | + ##### Proxy Authentication vs. Distributed Caching -The client has support for clustering and distributing the TGT state among application nodes that are behind a load balancer. In order to do so, the parameter needs to be defined as such for the filter. +The client has support for clustering and distributing the TGT state among application nodes that are behind a load balancer. In order to do so, +the parameter needs to be defined as such for the filter. ###### Ehcache @@ -415,14 +384,14 @@ Configure the client: ```xml proxyGrantingTicketStorageClass - org.jasig.cas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl + org.apereo.cas.client.EhcacheBackedProxyGrantingTicketStorageImpl ``` The setting provides an implementation for proxy storage using EhCache to take advantage of its replication features so that the PGT is successfully replicated and shared among nodes, regardless which node is selected as the result of the load balancer rerouting. Configuration of this parameter is not enough. The EhCache configuration needs to enable the replication mechanism through once of its suggested ways. A sample of that configuration based on RMI replication can be found here. Please note that while the sample is done for a distributed ticket registry implementation, the basic idea and configuration should easily be transferable. -When loading from the `web.xml`, the Jasig CAS Client relies on a series of default values, one of which being that the cache must be configured in the default location (i.e. `classpath:ehcache.xml`). +When loading from the `web.xml`, the Apereo CAS Client relies on a series of default values, one of which being that the cache must be configured in the default location (i.e. `classpath:ehcache.xml`). ```xml proxyGrantingTicketStorageClass - org.jasig.cas.client.proxy. MemcachedBackedProxyGrantingTicketStorageImpl + org.apereo.cas.client.proxy.MemcachedBackedProxyGrantingTicketStorageImpl ``` When loading from the `web.xml`, the Client relies on a series of default values, one of which being that the list of memcached servers must be defined in `/cas/casclient_memcached_hosts.txt` on the classpath). The file is a simple list of `:` on separate lines. **BE SURE NOT TO HAVE EXTRA LINE BREAKS**. - -#### org.jasig.cas.client.util.HttpServletRequestWrapperFilter + +#### org.apereo.cas.client.HttpServletRequestWrapperFilter + Wraps an `HttpServletRequest` so that the `getRemoteUser` and `getPrincipal` return the CAS related entries. ```xml CAS HttpServletRequest Wrapper Filter - org.jasig.cas.client.util.HttpServletRequestWrapperFilter + org.apereo.cas.client.HttpServletRequestWrapperFilter CAS HttpServletRequest Wrapper Filter @@ -471,19 +442,20 @@ Wraps an `HttpServletRequest` so that the `getRemoteUser` and `getPrincipal` ret ``` -| Property | Description | Required -|----------|-------|----------- -| `roleAttribute` | Used to determine the principal role. | No -| `ignoreCase` | Whether role checking should ignore case. Defaults to `false` | No +| Property | Description | Required | +|-----------------|---------------------------------------------------------------|----------| +| `roleAttribute` | Used to determine the principal role. | No | +| `ignoreCase` | Whether role checking should ignore case. Defaults to `false` | No | - -#### org.jasig.cas.client.util.AssertionThreadLocalFilter + + +#### org.apereo.cas.client.AssertionThreadLocalFilter Places the `Assertion` in a `ThreadLocal` for portions of the application that need access to it. This is useful when the Web application that this filter "fronts" needs to get the Principal name, but it has no access to the `HttpServletRequest`, hence making `getRemoteUser()` call impossible. ```xml CAS Assertion Thread Local Filter - org.jasig.cas.client.util.AssertionThreadLocalFilter + org.apereo.cas.client.AssertionThreadLocalFilter CAS Assertion Thread Local Filter @@ -491,20 +463,20 @@ Places the `Assertion` in a `ThreadLocal` for portions of the application that n ``` - -#### org.jasig.cas.client.util.ErrorRedirectFilter -Filters that redirects to the supplied url based on an exception. Exceptions and the urls are configured via init filter name/param values. + -| Property | Description | Required -|----------|-------|----------- -| `defaultErrorRedirectPage` | Default url to redirect to, in case no error matches are found. | Yes -| `java.lang.Exception` | Fully qualified exception name. Its value must be redirection url | No +#### org.apereo.cas.client.ErrorRedirectFilter +Filters that redirects to the supplied url based on an exception. Exceptions and the urls are configured via init filter name/param values. +| Property | Description | Required | +|----------------------------|-------------------------------------------------------------------|----------| +| `defaultErrorRedirectPage` | Default url to redirect to, in case no error matches are found. | Yes | +| `java.lang.Exception` | Fully qualified exception name. Its value must be redirection url | No | ```xml CAS Error Redirect Filter - org.jasig.cas.client.util.ErrorRedirectFilter + org.apereo.cas.client.ErrorRedirectFilter java.lang.Exception /error.jsp @@ -522,6 +494,7 @@ Filters that redirects to the supplied url based on an exception. Exceptions an + ### Client Configuration Using Spring Configuration via Spring IoC will depend heavily on `DelegatingFilterProxy` class. For each filter that will be configured for CAS via Spring, a corresponding `DelegatingFilterProxy` is needed in the web.xml. @@ -550,7 +523,7 @@ As the `HttpServletRequestWrapperFilter` and `AssertionThreadLocalFilter` have n ```xml - + @@ -575,10 +548,10 @@ As the `HttpServletRequestWrapperFilter` and `AssertionThreadLocalFilter` have n ```xml - + @@ -590,10 +563,10 @@ Configuration to validate tickets: ```xml - + @@ -604,12 +577,12 @@ Configuration to accept a Proxy Granting Ticket: ```xml @@ -622,11 +595,11 @@ Configuration to accept any Proxy Ticket (and Proxy Granting Tickets): ```xml - @@ -640,11 +613,11 @@ Configuration to accept Proxy Ticket from a chain (and Proxy Granting Tickets): ```xml - @@ -670,7 +643,7 @@ The specific filters can be configured in the following ways. Please see the Jav ```xml - org.jasig.cas.client + org.apereo.cas.client cas-client-support-springboot ${java.cas.client.version} @@ -681,7 +654,7 @@ The specific filters can be configured in the following ways. Please see the Jav ```groovy dependencies { ... - compile 'org.jasig.cas.client:cas-client-support-springboot:${java.cas.client.version}' + implementation 'org.apereo.cas.client:cas-client-support-springboot:${java.cas.client.version}' ... } ``` @@ -798,36 +771,6 @@ class CasProtectedApplication implements CasClientConfigurer { authenticationFilter.getInitParameters().put("serviceParameterName", "targetService"); } } -``` - - - -### Client Configuration Using JNDI - -Configuring the CAS client via JNDI is essentially the same as configuring the client via the `web.xml`, except the properties will reside in JNDI and not in the `web.xml`. -All properties that are placed in JNDI should be placed under `java:comp/env/cas` - -We use the following conventions: -1. JNDI will first look in `java:comp/env/cas/{SHORT FILTER NAME}/{PROPERTY NAME}` (i.e. `java:comp/env/cas/AuthenticationFilter/serverName`) -2. JNDI will as a last resort look in `java:comp/env/cas/{PROPERTY NAME}` (i.e. `java:comp/env/cas/serverName`) - - -#### Example -This is an update to the `META-INF/context.xml` that is included in Tomcat's Manager application: - -```xml - - - - - - - - - ``` @@ -838,14 +781,14 @@ The `SingleSignOutFilter` can affect character encoding. This becomes most obvio #### Configuration -| Property | Description | Required -|----------|-------|----------- -| `artifactParameterName` | The ticket artifact parameter name. Defaults to `ticket`| No -| `logoutParameterName` | Defaults to `logoutRequest` | No -| `relayStateParameterName` | Defaults to `RelayState` | No -| `eagerlyCreateSessions` | Defaults to `true` | No -| `artifactParameterOverPost` | Defaults to `false` | No -| `logoutCallbackPath` | The path which is expected to receive logout callback requests from the CAS server. This is necessary if your app needs access to the raw input stream when handling form posts. If not configured, the default behavior will check every form post for a logout parameter. | No +| Property | Description | Required | +|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `artifactParameterName` | The ticket artifact parameter name. Defaults to `ticket` | No | +| `logoutParameterName` | Defaults to `logoutRequest` | No | +| `relayStateParameterName` | Defaults to `RelayState` | No | +| `eagerlyCreateSessions` | Defaults to `true` | No | +| `artifactParameterOverPost` | Defaults to `false` | No | +| `logoutCallbackPath` | The path which is expected to receive logout callback requests from the CAS server. This is necessary if your app needs access to the raw input stream when handling form posts. If not configured, the default behavior will check every form post for a logout parameter. | No | #### CAS Protocol @@ -853,7 +796,7 @@ The `SingleSignOutFilter` can affect character encoding. This becomes most obvio ```xml CAS Single Sign Out Filter - org.jasig.cas.client.session.SingleSignOutFilter + org.apereo.cas.client.session.SingleSignOutFilter ... @@ -862,7 +805,7 @@ The `SingleSignOutFilter` can affect character encoding. This becomes most obvio ... - org.jasig.cas.client.session.SingleSignOutHttpSessionListener + org.apereo.cas.client.session.SingleSignOutHttpSessionListener ``` @@ -872,7 +815,7 @@ The `SingleSignOutFilter` can affect character encoding. This becomes most obvio ```xml CAS Single Sign Out Filter - org.jasig.cas.client.session.SingleSignOutFilter + org.apereo.cas.client.session.SingleSignOutFilter artifactParameterName SAMLart @@ -885,7 +828,7 @@ The `SingleSignOutFilter` can affect character encoding. This becomes most obvio ... - org.jasig.cas.client.session.SingleSignOutHttpSessionListener + org.apereo.cas.client.session.SingleSignOutHttpSessionListener ``` @@ -912,8 +855,8 @@ It is expected that for JEE applications both authentication and authorization s ``` cas { - org.jasig.cas.client.jaas.CasLoginModule required - ticketValidatorClass="org.jasig.cas.client.validation.Saml11TicketValidator" + jaas.org.apereo.cas.client.CasLoginModule required + ticketValidatorClass="org.apereo.cas.client.validation.Saml11TicketValidator" casServerUrlPrefix="https://cas.example.com/cas" tolerance="20000" service="https://webapp.example.com/webapp" @@ -927,618 +870,24 @@ cas { ``` -| Property | Description | Required -|----------|-------|-----------| -| `ticketValidatorClass ` | Fully-qualified class name of CAS ticket validator class. | Yes -| `casServerUrlPrefix` | URL to root of CAS Web application context. | Yes -| `service` | CAS service parameter that may be overridden by callback handler. **Note**: service must be specified by at least one component such that it is available at service ticket validation time. | No -| `defaultRoles` | Comma-delimited list of static roles applied to all authenticated principals. | No -| `roleAttributeNames` | Comma-delimited list of attribute names that describe role data delivered to CAS in the service-ticket validation response that should be applied to the current authenticated principal. | No -| `principalGroupName` | The name of a group principal containing the primary principal name of the current JAAS subject. The default value is `CallerPrincipal`. | No -| `roleGroupName` | The name of a group principal containing all role data. The default value is `Roles`. | No -| `cacheAssertions` | Flag to enable assertion caching. This may be required for JAAS providers that attempt to periodically reauthenticate to renew principal. Since CAS tickets are one-time-use, a cached assertion must be provided on reauthentication. | No -| `cacheTimeout` | Assertion cache timeout in minutes. | No -| `tolerance` | The tolerance for drifting clocks when validating SAML tickets. | No +| Property | Description | Required | +|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `ticketValidatorClass ` | Fully-qualified class name of CAS ticket validator class. | Yes | +| `casServerUrlPrefix` | URL to root of CAS Web application context. | Yes | +| `service` | CAS service parameter that may be overridden by callback handler. **Note**: service must be specified by at least one component such that it is available at service ticket validation time. | No | +| `defaultRoles` | Comma-delimited list of static roles applied to all authenticated principals. | No | +| `roleAttributeNames` | Comma-delimited list of attribute names that describe role data delivered to CAS in the service-ticket validation response that should be applied to the current authenticated principal. | No | +| `principalGroupName` | The name of a group principal containing the primary principal name of the current JAAS subject. The default value is `CallerPrincipal`. | No | +| `roleGroupName` | The name of a group principal containing all role data. The default value is `Roles`. | No | +| `cacheAssertions` | Flag to enable assertion caching. This may be required for JAAS providers that attempt to periodically reauthenticate to renew principal. Since CAS tickets are one-time-use, a cached assertion must be provided on reauthentication. | No | +| `cacheTimeout` | Assertion cache timeout in minutes. | No | +| `tolerance` | The tolerance for drifting clocks when validating SAML tickets. | No | ### Programmatic JAAS login using the Servlet 3 -A `org.jasig.cas.client.jaas.Servlet3AuthenticationFilter` servlet filter that performs a programmatic JAAS login using the Servlet 3.0 `HttpServletRequest#login()` facility. This component should be compatible with any servlet container that supports the Servlet 3.0/JEE6 specification. +A `jaas.org.apereo.cas.client.Servlet3AuthenticationFilter` servlet filter that performs a programmatic JAAS login using the Servlet 3.0 `HttpServletRequest#login()` facility. This component should be compatible with any servlet container that supports the Servlet 3.0/JEE6 specification. The filter executes when it receives a CAS ticket and expects the `CasLoginModule` JAAS module to perform the CAS ticket validation in order to produce an `AssertionPrincipal` from which the CAS assertion is obtained and inserted into the session to enable SSO. If a `service` init-param is specified for this filter, it supersedes the service defined for the `CasLoginModule`. - - -## JBoss Integration - -In keeping with CAS integration for Java applications, a JEE container-specific servlet filter is needed to protect JEE Web applications. The JBoss `WebAuthenticationFilter` component provided a convenient integration piece between a servlet filter and the JAAS framework, so a complete integration solution is available only for JBoss AS versions that provide the `WebAuthenticationFilter` class. The JAAS support should be extensible to any JEE container with additional development. - -For JBoss it is vitally important to use the correct values for `principalGroupName` and `roleGroupName`. Additionally, the `cacheAssertions` and `cacheTimeout` are required since JBoss by default attempts to reauthenticate the JAAS principal with a fairly aggressive default timeout. Since CAS tickets are single-use authentication tokens by default, assertion caching is required to support periodic reauthentication. - - -### Configure Servlet Filters - -Integration with the servlet pipeline is required for a number of purposes: - -1. Examine servlet request for an authenticated session -2. Redirect to CAS server for unauthenticated sessions -3. Provide service URL and CAS ticket to JAAS pipeline for validation - -The `WebAuthenticationFilter` performs these operations for the JBoss AS container. It is important to note that this filter simply collects the service URL and CAS ticket from the request and passes it to the JAAS pipeline. It is assumed that the `CasLoginModule` will be present in the JAAS pipeline to consume the data and perform ticket validation. The following web.xml excerpts demonstrate how to integrate WebAuthenticationFilter into a JEE Web application. - - -```xml -... - - CASWebAuthenticationFilter - org.jasig.cas.client.jboss.authentication.WebAuthenticationFilter - - - - CASAuthenticationFilter - org.jasig.cas.client.authentication.AuthenticationFilter - - casServerLoginUrl - https://cas.example.com/cas/login - - -... - -... -``` - -The JAAS LoginModule configuration in `conf/login-config.xml` may require the following changes in a JBoss environment: - -```xml - - - - org.jasig.cas.client.validation.Saml11TicketValidator - http://yourcasserver/cas - 20000 - admin,user - memberOf,eduPersonAffiliation,authorities - CallerPrincipal - Roles - true - 480 - - - -``` -It may be necessary to modify the JBoss `server.xml` and uncomment: - -```xml - -``` - -Remember not to add `` and `` elements in your `web.xml`. - -If you have any trouble, you can enable the log of cas in `jboss-logging.xml` by adding: - -```xml - - - -``` - - -## Tomcat 6/7/8/9 Integration -The client supports container-based CAS authentication and authorization support for the Tomcat servlet container. - -Suppose a single Tomcat container hosts multiple Web applications with similar authentication and authorization needs. Prior to Tomcat container support, each application would require a similar configuration of CAS servlet filters and authorization configuration in the `web.xml` servlet descriptor. Using the new container-based authentication/authorization feature, a single CAS configuration can be applied to the container and leveraged by all Web applications hosted by the container. - -CAS authentication support for Tomcat is based on the Tomcat-specific Realm component. The Realm component has a fairly broad surface area and RealmBase is provided as a convenient superclass for custom implementations; the CAS realm implementations derive from `RealmBase`. Unfortunately RealmBase and related components have proven to change over both major and minor number releases, which requires version-specific CAS components for integration. We have provided 3 packages with similar components with the hope of supporting all 6.x, 7.x and 8.x versions. **No support for 5.x is provided.** - - -### Component Overview -In the following discussion of components, only the Tomcat 8.x components are mentioned. Tomcat 8.0.x components are housed inside -`org.jasig.cas.client.tomcat.v8` while Tomcat 8.5.x components are inside `org.jasig.cas.client.tomcat.v85`. Tomcat 9 packages are -available at `org.jasig.cas.client.tomcat.v90`. You should be able to use the same exact configuration between the two modules provided package names are adjusted for each release. - -The Tomcat 7.0.x and 6.0.x components have exactly the same name, but **are in the tomcat.v7 and tomcat.v6 packages**, e.g. -`org.jasig.cas.client.tomcat.v7.Cas20CasAuthenticator` or `org.jasig.cas.client.tomcat.v6.Cas20CasAuthenticator`. - - -#### Authenticators -Authenticators are responsible for performing CAS authentication using a particular protocol. All protocols supported by the Jasig Java CAS client are supported: CAS 1.0, CAS 2.0, and SAML 1.1. The following components provide protocol-specific support: - -``` -org.jasig.cas.client.tomcat.v8.Cas10CasAuthenticator -org.jasig.cas.client.tomcat.v8.Cas20CasAuthenticator -org.jasig.cas.client.tomcat.v8.Cas20ProxyCasAuthenticator -org.jasig.cas.client.tomcat.v8.Saml11Authenticator -``` - - -#### Realms -In terms of CAS configuration, Tomcat realms serve as containers for users and role definitions. The roles defined in a Tomcat realm may be referenced in the web.xml servlet descriptor to define authorization constraints on Web applications hosted by the container. Two sources of user/role data are supported: - -``` -org.jasig.cas.client.tomcat.v8.PropertiesCasRealm -org.jasig.cas.client.tomcat.v8.AssertionCasRealm -``` - -`PropertiesCasRealm` uses a Java properties file as a source of static user/role information. This component is conceptually similar to the `MemoryRealm` component that ships with Tomcat and defines user/role data via XML configuration. The PropertiesCasRealm is different in that it explicitly lacks support for passwords, which have no use with CAS. - -`AssertionCasRealm` is designed to be used in conjunction with the SAML 1.1. protocol to take advantage of CAS attribute release to provide for dynamic user/role data driven by the CAS server. With this component the deployer may define a role attribute, e.g. memberOf, which could be backed by LDAP group membership information. In that case the user would be added to all roles defined in the SAML attribute assertion for values of the the `memberOf` attribute. - - -#### Valves -A number of Tomcat valves are provided to handle functionality outside Realms and Authenticators. - -##### Logout Valves -Logout valves provide a way of destroying the CAS authentication state bound to the container for a particular user/session; the destruction of authenticated state is synonymous with logout for the container and its hosted applications. (Note this does not destroy the CAS SSO session.) The implementations provide various strategies to map a URI onto the state-destroying logout function. - -``` -org.jasig.cas.client.tomcat.v8.StaticUriLogoutValve -org.jasig.cas.client.tomcat.v8.RegexUriLogoutValve -``` - -##### SingleSignOutValve -The `org.jasig.cas.client.tomcat.v8.SingleSignOutValve` allows the container to participate in CAS single sign-out. In particular this valve handles the SAML LogoutRequest message sent from the CAS server that is delivered when the CAS SSO session ends. - -##### ProxyCallbackValve -The `org.jasig.cas.client.tomcat.v8.ProxyCallbackValve` provides a handler for watching request URIs for requests that contain a proxy callback request in support of the CAS 2.0 protocol proxy feature. - - -### Container Setup -The version-specific CAS libraries must be placed on the container classpath, `$CATALINA_HOME/lib`. - - -### Context Configuration -The Realm, Authenticator, and Valve components are wired together inside a Tomcat Context configuration element. The location and scope of the Context determines the scope of the applied configuration. To apply a CAS configuration to every Web application hosted in the container, configure the default Context at `$CATALINA_HOME/conf/context.xml`. Note that individual Web applications/servlets can override the default context; see the Context Container reference for more information. - -Alternatively, CAS configuration can be applied to individual Web applications through a Context configuration element located in a `$CONTEXT_NAME.xml` file placed in `$CATALINA_HOME/conf/$ENGINE/$HOST`, where `$ENGINE` is typically Catalina and `$HOST` is `localhost`, `$CATALINA_HOME/conf/Catalina/localhost`. For example, to configure the Tomcat manager servlet, a `manager.xml` file contains Context configuration elements. - -```xml - - - - - - - - - - - - -``` - -The following example shows how to configure a Context for dynamic role data provided by the CAS attribute release feature. - -```xml - - - - - - - - - -``` - - -## Jetty Integration -Since version 3.4.2, the Java CAS Client supports Jetty container integration via the following module: - -```xml - - org.jasig.cas.client - cas-client-integration-jetty - ${cas-client.version} - -``` - -Both programmatic (embedded) and context configuration are supported. - -### Jetty Embedded Configuration -``` -# CAS configuration parameters -String hostName = "app.example.com"; -String casServerBaseUrl = "cas.example.com/cas"; -String casRoleAttribute = "memberOf"; -boolean casRenew = false; -int casTolerance = 5000; - -# Jetty wiring -WebAppContext context = new WebAppContext("/path/to/context", "contextPath"); -context.setTempDirectory("/tmp/jetty/work")); -context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); -SessionCookieConfig config = context.getSessionHandler().getSessionManager().getSessionCookieConfig(); -config.setHttpOnly(true); -config.setSecure(true); -Saml11TicketValidator validator = new Saml11TicketValidator(casServerBaseUrl); -validator.setRenew(casRenew); -validator.setTolerance(casTolerance); -CasAuthenticator authenticator = new CasAuthenticator(); -authenticator.setRoleAttribute(casRoleAttribute); -authenticator.setServerNames(hostName); -authenticator.setTicketValidator(validator); -context.getSecurityHandler().setAuthenticator(authenticator); -``` - -### Jetty Context Configuration -```xml - - - - - / - /webapps/yourapp - - - - app.example.com - - - https://cas.example.com/cas - - - - - - - -``` - - -## Atlassian Integration -The clien includes Atlassian Confluence and JIRA support. Support is enabled by a custom CAS authenticator that extends the default authenticators. - - -### Configuration - - -#### $JIRA_HOME Location - -- WAR/EAR Installation: /webapp -`/opt/atlassian/jira/atlassian-jira-enterprise-x.y.z/webapp` - -- Standalone: /atlassian-jira -`/opt/atlassian/jira/atlassian-jira-enterprise-x.y.z-standalone/atlassian-jira` - - -#### $CONFLUENCE_INSTALL Description - -- /confluence -`/opt/atlassian/confluence/confluence-x.y.z/confluence` - - -#### Changes to web.xml -Add the CAS filters to the end of the filter list. See `web.xml` configuration of the client. - - - -#### Modify the seraph-config.xml -To rely on the Single Sign Out functionality to sign off of Jira, comment out the normal logout URL and replace it with the CAS logout URL. Also, change the login links to point to the CAS login service. - -```xml - - - login.url - - http://cas.institution.edu/cas/login?service=${originalurl} - - - - link.login.url - - - http://cas.institution.edu/cas/login?service=${originalurl} - - - - logout.url - - https://cas.institution.edu/cas/logout - -``` - - -#### CAS Authenticator -Comment out the `DefaultAuthenticator` like so in `[$JIRA_HOME|$CONFLUENCE_INSTALL]/WEB-INF/classes/seraph-config.xml`: - -```xml - - - -``` - -For JIRA, add in the Client Jira Authenticator: - -```xml - - - -``` - -For Confluence, add in the Client Confluence Authenticator: - -```xml - - - -``` - - -#### Confluence CAS Logout - -As of this writing, Atlassian doesn't support a config option yet (like Jira). To rely on the Single Sign Out functionality to sign off of Confluence we need to modify the logout link. - - -- Copy `$CONFLUENCE_INSTALL/WEB-INF/lib/confluence-x.x.x.jar` to a temporary directory -- `mkdir /tmp/confluence-jar && cp WEB-INF/lib/confluence-x.y.z.jar /tmp/confluence-jar` -- Unpack the jar -- `cd /tmp/confluence-jar && jar xvf confluence-x.y.z.jar` -- `cp xwork.xml $CONFLUENCE_INSTALL/WEB-INF/classes` -- `cp xwork.xml $CONFLUENCE_INSTALL/WEB-INF/classes/ && cd $CONFLUENCE_INSTALL/WEB-INF/classes/` -- Edit `$CONFLUENCE_INSTALL/WEB-INF/classes/xwork.xml`, find the logout action and comment out the success result and replace it with this one: - -```xml - - -https://cas.institution.edu/cas/logout - -``` - - -#### Copy Jars -Copy cas-client-core-x.y.x.jar and cas-client-integration-atlassian-x.y.x.jar to `$JIRA_HOME/WEB-INF/lib` - - -## Spring Security Integration -This configuration tested against the sample application that is included with Spring Security. As of this writing, replacing the `applicationContext-security.xml` in the sample application with the one below would enable this alternative configuration. We can not guarantee this version will work without modification in future versions of Spring Security. - - -### Changes to web.xml - -```xml -... - - contextConfigLocation - - /WEB-INF/applicationContext-security.xml - - - - - log4jConfigLocation - /WEB-INF/classes/log4j.properties - - - - webAppRootKey - cas.root - - - - CAS Single Sign Out Filter - org.jasig.cas.client.session.SingleSignOutFilter - - casServerUrlPrefix - https://cas.example.com/cas - - - - - springSecurityFilterChain - org.springframework.web.filter.DelegatingFilterProxy - - - - CAS Single Sign Out Filter - /* - - - - springSecurityFilterChain - /* - - - - org.jasig.cas.client.session.SingleSignOutHttpSessionListener - - - - org.springframework.web.context.ContextLoaderListener - - - - org.springframework.web.util.Log4jConfigListener - - - - 403 - /casfailed.jsp - -... -``` - -The important additions to the `web.xml` include the addition of the 403 error page. 403 is what the CAS Validation Filter will throw if it has a problem with the ticket. Also, if you want Single Log Out, you should enable the `SingleSignOutHttpSessionListener`. - - -### Changes to applicationContext-security.xml - -```xml -... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -... -``` - -1. You should replace the `userService` with something that checks your user storage. -2. Replace the `serverName` and `casServerLoginUrl` with your values (or better yet, externalize them). -3. Replace the URLs with the URL configuration for your application. diff --git a/cas-client-core/NOTICE b/cas-client-core/NOTICE index 3e0a7e711..5e01c5329 100644 --- a/cas-client-core/NOTICE +++ b/cas-client-core/NOTICE @@ -27,7 +27,7 @@ This project includes: Jackson-annotations under The Apache Software License, Version 2.0 Jackson-core under The Apache Software License, Version 2.0 jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 + Apereo CAS Client for Java - Core under Apache License Version 2.0 Java Servlet API under CDDL + GPLv2 with classpath exception JavaBeans Activation Framework API jar under CDDL/GPLv2+CE JAXB Core under CDDL+GPL License diff --git a/cas-client-core/pom.xml b/cas-client-core/pom.xml index cb7c2ca28..4fed89698 100644 --- a/cas-client-core/pom.xml +++ b/cas-client-core/pom.xml @@ -20,21 +20,21 @@ --> - org.jasig.cas.client - 3.6.4 + org.apereo.cas.client + 4.1.2-SNAPSHOT cas-client 4.0.0 cas-client-core jar - Jasig CAS Client for Java - Core + Apereo CAS Client for Java - Core org.apache.maven.plugins maven-jar-plugin - 3.1.1 + 3.5.1 @@ -50,16 +50,21 @@ xml-security xmlsec - 1.3.0 + ${xmlsec.version} runtime true + + com.nimbusds + nimbus-jose-jwt + + com.fasterxml.jackson.core jackson-databind - + org.springframework spring-beans @@ -72,7 +77,7 @@ spring-web provided - + org.springframework spring-test diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java b/cas-client-core/src/main/java/org/apereo/cas/client/Protocol.java similarity index 94% rename from cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java rename to cas-client-core/src/main/java/org/apereo/cas/client/Protocol.java index c51929b0d..429a281b2 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/Protocol.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/Protocol.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client; +package org.apereo.cas.client; /** * Simple enumeration to hold/capture some of the standard request parameters used by the various protocols. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AttributePrincipal.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AttributePrincipal.java similarity index 94% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/AttributePrincipal.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/AttributePrincipal.java index 23480fb90..3e4dcfdc6 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AttributePrincipal.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AttributePrincipal.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; import java.io.Serializable; import java.security.Principal; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AttributePrincipalImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AttributePrincipalImpl.java similarity index 82% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/AttributePrincipalImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/AttributePrincipalImpl.java index f67c006e0..3e85f8bb9 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AttributePrincipalImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AttributePrincipalImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,15 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + +import org.apereo.cas.client.proxy.ProxyRetriever; +import org.apereo.cas.client.util.CommonUtils; -import java.util.Collections; -import java.util.Map; -import org.jasig.cas.client.proxy.ProxyRetriever; -import org.jasig.cas.client.util.CommonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serial; +import java.util.Collections; +import java.util.Map; + /** * Concrete implementation of the AttributePrincipal interface. * @@ -36,6 +39,7 @@ public class AttributePrincipalImpl extends SimplePrincipal implements Attribute private static final Logger LOGGER = LoggerFactory.getLogger(AttributePrincipalImpl.class); /** Unique Id for Serialization */ + @Serial private static final long serialVersionUID = -1443182634624927187L; /** Map of key/value pairs about this principal. */ @@ -53,7 +57,7 @@ public class AttributePrincipalImpl extends SimplePrincipal implements Attribute * @param name the unique identifier for the principal. */ public AttributePrincipalImpl(final String name) { - this(name, Collections. emptyMap()); + this(name, Collections.emptyMap()); } /** @@ -74,8 +78,8 @@ public AttributePrincipalImpl(final String name, final Map attri * @param proxyRetriever the ProxyRetriever implementation to call back to the CAS server. */ public AttributePrincipalImpl(final String name, final String proxyGrantingTicket, - final ProxyRetriever proxyRetriever) { - this(name, Collections. emptyMap(), proxyGrantingTicket, proxyRetriever); + final ProxyRetriever proxyRetriever) { + this(name, Collections.emptyMap(), proxyGrantingTicket, proxyRetriever); } /** @@ -87,7 +91,7 @@ public AttributePrincipalImpl(final String name, final String proxyGrantingTicke * @param proxyRetriever the ProxyRetriever implementation to call back to the CAS server. */ public AttributePrincipalImpl(final String name, final Map attributes, - final String proxyGrantingTicket, final ProxyRetriever proxyRetriever) { + final String proxyGrantingTicket, final ProxyRetriever proxyRetriever) { super(name); this.attributes = attributes; this.proxyGrantingTicket = proxyGrantingTicket; @@ -96,11 +100,6 @@ public AttributePrincipalImpl(final String name, final Map attri CommonUtils.assertNotNull(this.attributes, "attributes cannot be null."); } - @Override - public Map getAttributes() { - return this.attributes; - } - @Override public String getProxyTicketFor(final String service) { if (proxyGrantingTicket != null) { @@ -110,4 +109,18 @@ public String getProxyTicketFor(final String service) { LOGGER.debug("No ProxyGrantingTicket was supplied, so no Proxy Ticket can be retrieved."); return null; } + + @Override + public Map getAttributes() { + return this.attributes; + } + + /** + * Returns the proxy granting ticket associated with this principal, if available. + * + * @return the proxy granting ticket or null + */ + public String getProxyGrantingTicket() { + return proxyGrantingTicket; + } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AuthenticationFilter.java similarity index 77% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/AuthenticationFilter.java index 3ffebfbaf..af9ed2b55 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AuthenticationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,23 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; - -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.jasig.cas.client.validation.Assertion; - -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +package org.apereo.cas.client.authentication; + +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.util.AbstractCasFilter; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.ReflectUtils; +import org.apereo.cas.client.validation.Assertion; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -56,6 +56,16 @@ * @since 3.0 */ public class AuthenticationFilter extends AbstractCasFilter { + private static final Map> PATTERN_MATCHER_TYPES = + new HashMap<>(); + + static { + PATTERN_MATCHER_TYPES.put("CONTAINS", ContainsPatternUrlPatternMatcherStrategy.class); + PATTERN_MATCHER_TYPES.put("REGEX", RegexUrlPatternMatcherStrategy.class); + PATTERN_MATCHER_TYPES.put("FULL_REGEX", EntireRegionRegexUrlPatternMatcherStrategy.class); + PATTERN_MATCHER_TYPES.put("EXACT", ExactUrlPatternMatcherStrategy.class); + } + /** * The URL to the CAS Server login. */ @@ -82,16 +92,6 @@ public class AuthenticationFilter extends AbstractCasFilter { private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass = null; - private static final Map> PATTERN_MATCHER_TYPES = - new HashMap>(); - - static { - PATTERN_MATCHER_TYPES.put("CONTAINS", ContainsPatternUrlPatternMatcherStrategy.class); - PATTERN_MATCHER_TYPES.put("REGEX", RegexUrlPatternMatcherStrategy.class); - PATTERN_MATCHER_TYPES.put("FULL_REGEX", EntireRegionRegexUrlPatternMatcherStrategy.class); - PATTERN_MATCHER_TYPES.put("EXACT", ExactUrlPatternMatcherStrategy.class); - } - public AuthenticationFilter() { this(Protocol.CAS2); } @@ -100,12 +100,24 @@ protected AuthenticationFilter(final Protocol protocol) { super(protocol); } + @Override + public void init() { + super.init(); + + final var message = String.format( + "one of %s and %s must not be null.", + ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), + ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName()); + + CommonUtils.assertNotNull(this.casServerLoginUrl, message); + } + @Override protected void initInternal(final FilterConfig filterConfig) throws ServletException { if (!isIgnoreInitConfiguration()) { super.initInternal(filterConfig); - final String loginUrl = getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL); + final var loginUrl = getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL); if (loginUrl != null) { setCasServerLoginUrl(loginUrl); } else { @@ -116,11 +128,11 @@ protected void initInternal(final FilterConfig filterConfig) throws ServletExcep setGateway(getBoolean(ConfigurationKeys.GATEWAY)); setMethod(getString(ConfigurationKeys.METHOD)); - final String ignorePattern = getString(ConfigurationKeys.IGNORE_PATTERN); - final String ignoreUrlPatternType = getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE); + final var ignorePattern = getString(ConfigurationKeys.IGNORE_PATTERN); + final var ignoreUrlPatternType = getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE); if (ignorePattern != null) { - final Class ignoreUrlMatcherClass = PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType); + final var ignoreUrlMatcherClass = PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType); if (ignoreUrlMatcherClass != null) { this.ignoreUrlPatternMatcherStrategyClass = ReflectUtils.newInstance(ignoreUrlMatcherClass.getName()); } else { @@ -136,13 +148,13 @@ protected void initInternal(final FilterConfig filterConfig) throws ServletExcep } } - final Class gatewayStorageClass = getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS); + final var gatewayStorageClass = getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS); if (gatewayStorageClass != null) { setGatewayStorage(ReflectUtils.newInstance(gatewayStorageClass)); } - final Class authenticationRedirectStrategyClass = getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS); + final var authenticationRedirectStrategyClass = getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS); if (authenticationRedirectStrategyClass != null) { this.authenticationRedirectStrategy = ReflectUtils.newInstance(authenticationRedirectStrategyClass); @@ -150,24 +162,12 @@ protected void initInternal(final FilterConfig filterConfig) throws ServletExcep } } - @Override - public void init() { - super.init(); - - final String message = String.format( - "one of %s and %s must not be null.", - ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), - ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName()); - - CommonUtils.assertNotNull(this.casServerLoginUrl, message); - } - @Override public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; + final var request = (HttpServletRequest) servletRequest; + final var response = (HttpServletResponse) servletResponse; if (isRequestUrlExcluded(request)) { logger.debug("Request is ignored."); @@ -175,17 +175,17 @@ public final void doFilter(final ServletRequest servletRequest, final ServletRes return; } - final HttpSession session = request.getSession(false); - final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null; + final var session = request.getSession(false); + final var assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null; if (assertion != null) { filterChain.doFilter(request, response); return; } - final String serviceUrl = constructServiceUrl(request, response); - final String ticket = retrieveTicketFromRequest(request); - final boolean wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl); + final var serviceUrl = constructServiceUrl(request, response); + final var ticket = retrieveTicketFromRequest(request); + final var wasGatewayed = this.gateway && this.gatewayStorage.hasGatewayedAlready(request, serviceUrl); if (CommonUtils.isNotBlank(ticket) || wasGatewayed) { filterChain.doFilter(request, response); @@ -204,7 +204,7 @@ public final void doFilter(final ServletRequest servletRequest, final ServletRes logger.debug("Constructed service url: {}", modifiedServiceUrl); - final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, + final var urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway, this.method); logger.debug("redirecting to \"{}\"", urlToRedirectTo); @@ -235,22 +235,22 @@ public final void setGatewayStorage(final GatewayResolver gatewayStorage) { this.gatewayStorage = gatewayStorage; } + public final void setIgnoreUrlPatternMatcherStrategyClass( + final UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass) { + this.ignoreUrlPatternMatcherStrategyClass = ignoreUrlPatternMatcherStrategyClass; + } + private boolean isRequestUrlExcluded(final HttpServletRequest request) { if (this.ignoreUrlPatternMatcherStrategyClass == null) { return false; } - final StringBuffer urlBuffer = request.getRequestURL(); + final var urlBuffer = request.getRequestURL(); if (request.getQueryString() != null) { urlBuffer.append("?").append(request.getQueryString()); } - final String requestUri = urlBuffer.toString(); + final var requestUri = urlBuffer.toString(); return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri); } - public final void setIgnoreUrlPatternMatcherStrategyClass( - final UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass) { - this.ignoreUrlPatternMatcherStrategyClass = ignoreUrlPatternMatcherStrategyClass; - } - } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationRedirectStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AuthenticationRedirectStrategy.java similarity index 88% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationRedirectStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/AuthenticationRedirectStrategy.java index fe754fc88..620711559 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationRedirectStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/AuthenticationRedirectStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * Interface to abstract the authentication strategy for redirecting. The traditional method was to always just redirect, @@ -30,6 +31,7 @@ * @author Scott Battaglia * @since 3.3.0 */ +@FunctionalInterface public interface AuthenticationRedirectStrategy { /** @@ -41,6 +43,6 @@ public interface AuthenticationRedirectStrategy { * @throws IOException the exception to throw if there is some type of error. This will bubble up through the filter. */ void redirect(HttpServletRequest request, HttpServletResponse response, String potentialRedirectUrl) - throws IOException; + throws IOException; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ContainsPatternUrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/ContainsPatternUrlPatternMatcherStrategy.java similarity index 91% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/ContainsPatternUrlPatternMatcherStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/ContainsPatternUrlPatternMatcherStrategy.java index 0da841a22..aa271cb1d 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ContainsPatternUrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/ContainsPatternUrlPatternMatcherStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,18 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; /** * A pattern matcher that looks inside the url to find the exact pattern specified. - * + * * @author Misagh Moayyed * @since 3.3.1 */ public final class ContainsPatternUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy { private String pattern; - + @Override public boolean matches(final String url) { return url.contains(this.pattern); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java index 083c92411..370410b6f 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/DefaultAuthenticationRedirectStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * Implementation of the {@link AuthenticationRedirectStrategy} class that preserves the original behavior that existed prior to 3.3.0. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultGatewayResolverImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/DefaultGatewayResolverImpl.java similarity index 80% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultGatewayResolverImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/DefaultGatewayResolverImpl.java index b3ca242e5..743a0b036 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/DefaultGatewayResolverImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/DefaultGatewayResolverImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; public final class DefaultGatewayResolverImpl implements GatewayResolver { @@ -27,13 +26,13 @@ public final class DefaultGatewayResolverImpl implements GatewayResolver { @Override public boolean hasGatewayedAlready(final HttpServletRequest request, final String serviceUrl) { - final HttpSession session = request.getSession(false); + final var session = request.getSession(false); if (session == null) { return false; } - final boolean result = session.getAttribute(CONST_CAS_GATEWAY) != null; + final var result = session.getAttribute(CONST_CAS_GATEWAY) != null; return result; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/EntireRegionRegexUrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/EntireRegionRegexUrlPatternMatcherStrategy.java similarity index 94% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/EntireRegionRegexUrlPatternMatcherStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/EntireRegionRegexUrlPatternMatcherStrategy.java index 1e95064c1..05dd49318 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/EntireRegionRegexUrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/EntireRegionRegexUrlPatternMatcherStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/ExactUrlPatternMatcherStrategy.java similarity index 89% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/ExactUrlPatternMatcherStrategy.java index 8500a7d82..41818c26a 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/ExactUrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/ExactUrlPatternMatcherStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,12 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; /** * A pattern matcher that produces a successful match if the pattern * specified matches the given url exactly and equally. - * + * * @author Misagh Moayyed * @since 3.3.1 */ @@ -29,7 +29,8 @@ public final class ExactUrlPatternMatcherStrategy implements UrlPatternMatcherSt private String pattern; - public ExactUrlPatternMatcherStrategy() {} + public ExactUrlPatternMatcherStrategy() { + } public ExactUrlPatternMatcherStrategy(final String pattern) { this.setPattern(pattern); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java similarity index 83% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java index 51fbb7011..94330d95a 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,13 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + +import org.apereo.cas.client.util.CommonUtils; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import java.io.PrintWriter; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.jasig.cas.client.util.CommonUtils; /** * Implementation of the redirect strategy that can handle a Faces Ajax request in addition to the standard redirect style. @@ -43,10 +44,10 @@ public void redirect(final HttpServletRequest request, final HttpServletResponse response.setContentType("text/xml"); response.setStatus(200); - final PrintWriter writer = response.getWriter(); + final var writer = response.getWriter(); writer.write(""); writer.write(String.format("", - potentialRedirectUrl)); + potentialRedirectUrl)); } else { response.sendRedirect(potentialRedirectUrl); } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/GatewayResolver.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/GatewayResolver.java similarity index 90% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/GatewayResolver.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/GatewayResolver.java index 28ce5afbc..1ade30ef3 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/GatewayResolver.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/GatewayResolver.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Implementations of this should only have a default constructor if * you plan on constructing them via the web.xml. - * + * * @author Scott Battaglia * @version $Revision$ * @since 1.0 @@ -33,7 +33,7 @@ public interface GatewayResolver { /** * Determines if the request has been gatewayed already. Should also do gateway clean up. - * + * * @param request the Http Servlet Request * @param serviceUrl the service url * @return true if yes, false otherwise. @@ -42,7 +42,7 @@ public interface GatewayResolver { /** * Storage the request for gatewaying and return the service url, which can be modified. - * + * * @param request the HttpServletRequest. * @param serviceUrl the service url * @return the potentially modified service url to redirect to diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/RegexUrlPatternMatcherStrategy.java similarity index 94% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/RegexUrlPatternMatcherStrategy.java index d6924504a..48f39b3d3 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/RegexUrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/RegexUrlPatternMatcherStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/SimplePrincipal.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/SimplePrincipal.java similarity index 91% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/SimplePrincipal.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/SimplePrincipal.java index 299e7c44a..84d6b3a6c 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/SimplePrincipal.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/SimplePrincipal.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + +import org.apereo.cas.client.util.CommonUtils; +import java.io.Serial; import java.io.Serializable; import java.security.Principal; -import org.jasig.cas.client.util.CommonUtils; /** * Simple security principal implementation. @@ -33,6 +35,7 @@ public class SimplePrincipal implements Principal, Serializable { /** SimplePrincipal.java */ + @Serial private static final long serialVersionUID = -5645357206342793145L; /** The unique identifier for this principal. */ @@ -52,8 +55,8 @@ public final String getName() { return this.name; } - public String toString() { - return getName(); + public int hashCode() { + return 37 * getName().hashCode(); } public boolean equals(final Object o) { @@ -66,7 +69,7 @@ public boolean equals(final Object o) { } } - public int hashCode() { - return 37 * getName().hashCode(); + public String toString() { + return getName(); } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/UrlPatternMatcherStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/UrlPatternMatcherStrategy.java similarity index 93% rename from cas-client-core/src/main/java/org/jasig/cas/client/authentication/UrlPatternMatcherStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/authentication/UrlPatternMatcherStrategy.java index ab8112e75..a9b88816c 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/UrlPatternMatcherStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/authentication/UrlPatternMatcherStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + /** * Defines an abstraction by which request urls can be matches against a given pattern. * New instances for all extensions for this strategy interface will be created per @@ -33,7 +34,7 @@ public interface UrlPatternMatcherStrategy { * @return true if match is successful */ boolean matches(String url); - + /** * The pattern against which the url is compared * @param pattern diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/BaseConfigurationStrategy.java similarity index 64% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/BaseConfigurationStrategy.java index c1c794a54..be28c4ad6 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/BaseConfigurationStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/BaseConfigurationStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; + +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.ReflectUtils; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,60 +36,51 @@ public abstract class BaseConfigurationStrategy implements ConfigurationStrategy @Override public final boolean getBoolean(final ConfigurationKey configurationKey) { - return getValue(configurationKey, new Parser() { - @Override - public Boolean parse(final String value) { - return CommonUtils.toBoolean(value); - } - }); + return getValue(configurationKey, CommonUtils::toBoolean); } @Override - public final long getLong(final ConfigurationKey configurationKey) { - return getValue(configurationKey, new Parser() { - @Override - public Long parse(final String value) { - return CommonUtils.toLong(value, configurationKey.getDefaultValue()); - } - }); + public final String getString(final ConfigurationKey configurationKey) { + return getValue(configurationKey, value -> value); } @Override - public final int getInt(final ConfigurationKey configurationKey) { - return getValue(configurationKey, new Parser() { - @Override - public Integer parse(final String value) { - return CommonUtils.toInt(value, configurationKey.getDefaultValue()); - } - }); + public final long getLong(final ConfigurationKey configurationKey) { + return getValue(configurationKey, value -> CommonUtils.toLong(value, configurationKey.getDefaultValue())); } @Override - public final String getString(final ConfigurationKey configurationKey) { - return getValue(configurationKey, new Parser() { - @Override - public String parse(final String value) { - return value; - } - }); + public final int getInt(final ConfigurationKey configurationKey) { + return getValue(configurationKey, value -> CommonUtils.toInt(value, configurationKey.getDefaultValue())); } @Override public Class getClass(final ConfigurationKey> configurationKey) { - return getValue(configurationKey, new Parser>() { - @Override - public Class parse(final String value) { - try { - return ReflectUtils.loadClass(value); - } catch (final IllegalArgumentException e) { - return configurationKey.getDefaultValue(); - } + return getValue(configurationKey, value -> { + try { + return ReflectUtils.loadClass(value); + } catch (final IllegalArgumentException e) { + return configurationKey.getDefaultValue(); } }); } + /** + * Retrieve the String value for this key. Returns null if there is no value. + * + * @param configurationKey the key to retrieve. MUST NOT BE NULL. + * @return the String if its found, null otherwise. + */ + protected abstract String get(ConfigurationKey configurationKey); + + @FunctionalInterface + private interface Parser { + + T parse(String value); + } + private T getValue(final ConfigurationKey configurationKey, final Parser parser) { - final String value = getWithCheck(configurationKey); + final var value = getWithCheck(configurationKey); if (CommonUtils.isBlank(value)) { logger.trace("No value found for property {}, returning default {}", configurationKey.getName(), configurationKey.getDefaultValue()); @@ -105,17 +97,4 @@ private String getWithCheck(final ConfigurationKey configurationKey) { return get(configurationKey); } - - /** - * Retrieve the String value for this key. Returns null if there is no value. - * - * @param configurationKey the key to retrieve. MUST NOT BE NULL. - * @return the String if its found, null otherwise. - */ - protected abstract String get(ConfigurationKey configurationKey); - - private interface Parser { - - T parse(String value); - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKey.java similarity index 92% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKey.java index 1e0eebeef..396f76fad 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKey.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKey.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import org.jasig.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.CommonUtils; /** * Holder class to represent a particular configuration key and its optional default value. @@ -60,7 +60,7 @@ public String getName() { public E getDefaultValue() { return this.defaultValue; } - + @Override public String toString() { return getName(); diff --git a/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKeys.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKeys.java new file mode 100644 index 000000000..5468a6384 --- /dev/null +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationKeys.java @@ -0,0 +1,89 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client.configuration; + +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.authentication.AuthenticationRedirectStrategy; +import org.apereo.cas.client.authentication.DefaultGatewayResolverImpl; +import org.apereo.cas.client.authentication.GatewayResolver; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.validation.Cas20ServiceTicketValidator; + +import javax.net.ssl.HostnameVerifier; + +/** + * Holder interface for all known configuration keys. + * + * @author Scott Battaglia + * @since 3.4.0 + */ +public interface ConfigurationKeys { + + ConfigurationKey ARTIFACT_PARAMETER_NAME = new ConfigurationKey<>("artifactParameterName", Protocol.CAS2.getArtifactParameterName()); + ConfigurationKey SERVER_NAME = new ConfigurationKey<>("serverName", null); + ConfigurationKey SERVICE = new ConfigurationKey<>("service"); + ConfigurationKey RENEW = new ConfigurationKey<>("renew", Boolean.FALSE); + ConfigurationKey LOGOUT_PARAMETER_NAME = new ConfigurationKey<>("logoutParameterName", "logoutRequest"); + ConfigurationKey ARTIFACT_PARAMETER_OVER_POST = new ConfigurationKey<>("artifactParameterOverPost", Boolean.FALSE); + ConfigurationKey EAGERLY_CREATE_SESSIONS = new ConfigurationKey<>("eagerlyCreateSessions", Boolean.TRUE); + ConfigurationKey ENCODE_SERVICE_URL = new ConfigurationKey<>("encodeServiceUrl", Boolean.TRUE); + ConfigurationKey SSL_CONFIG_FILE = new ConfigurationKey<>("sslConfigFile", null); + ConfigurationKey ROLE_ATTRIBUTE = new ConfigurationKey<>("roleAttribute", null); + ConfigurationKey IGNORE_CASE = new ConfigurationKey<>("ignoreCase", Boolean.FALSE); + ConfigurationKey CAS_SERVER_LOGIN_URL = new ConfigurationKey<>("casServerLoginUrl", null); + ConfigurationKey GATEWAY = new ConfigurationKey<>("gateway", Boolean.FALSE); + ConfigurationKey METHOD = new ConfigurationKey<>("method", null); + ConfigurationKey> AUTHENTICATION_REDIRECT_STRATEGY_CLASS = + new ConfigurationKey<>("authenticationRedirectStrategyClass", null); + ConfigurationKey> GATEWAY_STORAGE_CLASS = + new ConfigurationKey<>("gatewayStorageClass", DefaultGatewayResolverImpl.class); + ConfigurationKey CAS_SERVER_URL_PREFIX = new ConfigurationKey<>("casServerUrlPrefix", null); + ConfigurationKey ENCODING = new ConfigurationKey<>("encoding", null); + ConfigurationKey TOLERANCE = new ConfigurationKey<>("tolerance", 1000L); + ConfigurationKey PRIVATE_KEY_PATH = new ConfigurationKey<>("privateKeyPath", null); + ConfigurationKey PRIVATE_KEY_ALGORITHM = new ConfigurationKey<>("privateKeyAlgorithm", "RSA"); + + /** + * @deprecated As of 3.4. This constant is not used by the client and will + * be removed in future versions. + */ + @Deprecated + ConfigurationKey DISABLE_XML_SCHEMA_VALIDATION = new ConfigurationKey<>("disableXmlSchemaValidation", Boolean.FALSE); + ConfigurationKey IGNORE_PATTERN = new ConfigurationKey<>("ignorePattern", null); + ConfigurationKey IGNORE_URL_PATTERN_TYPE = new ConfigurationKey<>("ignoreUrlPatternType", "REGEX"); + ConfigurationKey> HOSTNAME_VERIFIER = new ConfigurationKey<>("hostnameVerifier", null); + ConfigurationKey HOSTNAME_VERIFIER_CONFIG = new ConfigurationKey<>("hostnameVerifierConfig", null); + ConfigurationKey EXCEPTION_ON_VALIDATION_FAILURE = new ConfigurationKey<>("exceptionOnValidationFailure", Boolean.TRUE); + ConfigurationKey REDIRECT_AFTER_VALIDATION = new ConfigurationKey<>("redirectAfterValidation", Boolean.TRUE); + ConfigurationKey USE_SESSION = new ConfigurationKey<>("useSession", Boolean.TRUE); + ConfigurationKey SECRET_KEY = new ConfigurationKey<>("secretKey", null); + ConfigurationKey CIPHER_ALGORITHM = new ConfigurationKey<>("cipherAlgorithm", "DESede"); + ConfigurationKey PROXY_RECEPTOR_URL = new ConfigurationKey<>("proxyReceptorUrl", null); + ConfigurationKey> PROXY_GRANTING_TICKET_STORAGE_CLASS = + new ConfigurationKey<>("proxyGrantingTicketStorageClass", ProxyGrantingTicketStorageImpl.class); + ConfigurationKey MILLIS_BETWEEN_CLEAN_UPS = new ConfigurationKey<>("millisBetweenCleanUps", 60000); + ConfigurationKey ACCEPT_ANY_PROXY = new ConfigurationKey<>("acceptAnyProxy", Boolean.FALSE); + ConfigurationKey ALLOWED_PROXY_CHAINS = new ConfigurationKey<>("allowedProxyChains", null); + ConfigurationKey> TICKET_VALIDATOR_CLASS = new ConfigurationKey<>("ticketValidatorClass", null); + ConfigurationKey PROXY_CALLBACK_URL = new ConfigurationKey<>("proxyCallbackUrl", null); + ConfigurationKey RELAY_STATE_PARAMETER_NAME = new ConfigurationKey<>("relayStateParameterName", "RelayState"); + ConfigurationKey LOGOUT_CALLBACK_PATH = new ConfigurationKey<>("logoutCallbackPath", null); + ConfigurationKey JSONP_CALLBACK_PARAMETER_NAME = new ConfigurationKey<>("jsonpCallbackParameterName", "callback"); +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationStrategy.java similarity index 94% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationStrategy.java index 5b6a5dc99..525397d01 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategy.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationStrategy.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; /** * Abstraction to allow for pluggable methods for retrieving filter configuration. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationStrategyName.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationStrategyName.java index a8326c109..a5da2b6f9 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationStrategyName.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/ConfigurationStrategyName.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,9 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; + +import org.apereo.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.CommonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +44,7 @@ private ConfigurationStrategyName(final Class c } /** - * Static helper method that will resolve a simple string to either an enum value or a {@link org.jasig.cas.client.configuration.ConfigurationStrategy} class. + * Static helper method that will resolve a simple string to either an enum value or a {@link ConfigurationStrategy} class. * * @param value the value to attempt to resolve. * @return the underlying class that this maps to (either via simple name or fully qualified class name). @@ -53,19 +54,19 @@ public static Class resolveToConfigurationStrat return DEFAULT.configurationStrategyClass; } - for (final ConfigurationStrategyName csn : values()) { + for (final var csn : values()) { if (csn.name().equalsIgnoreCase(value)) { return csn.configurationStrategyClass; } } try { - final Class clazz = Class.forName(value); + final var clazz = Class.forName(value); if (ConfigurationStrategy.class.isAssignableFrom(clazz)) { return (Class) clazz; } - } catch (final ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { LOGGER.error("Unable to locate strategy {} by name or class name. Using default strategy instead.", value, e); } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/JndiConfigurationStrategyImpl.java similarity index 81% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/JndiConfigurationStrategyImpl.java index 32ef7296a..2baf19c93 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/JndiConfigurationStrategyImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/JndiConfigurationStrategyImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; + +import org.apereo.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.CommonUtils; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; import javax.naming.InitialContext; import javax.naming.NamingException; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; /** * Loads configuration information from JNDI, using the defaultValue if it can't. @@ -49,21 +50,31 @@ public JndiConfigurationStrategyImpl(final String environmentPrefix) { this.environmentPrefix = environmentPrefix; } + @Override + public final void init(final FilterConfig filterConfig, final Class clazz) { + this.simpleFilterName = clazz.getSimpleName(); + try { + this.context = new InitialContext(); + } catch (final NamingException e) { + logger.error("Unable to create InitialContext. No properties can be loaded via JNDI.", e); + } + } + @Override protected final String get(final ConfigurationKey configurationKey) { if (context == null) { return null; } - final String propertyName = configurationKey.getName(); - final String filterValue = loadFromContext(context, this.environmentPrefix + this.simpleFilterName + "/" + propertyName); + final var propertyName = configurationKey.getName(); + final var filterValue = loadFromContext(context, this.environmentPrefix + this.simpleFilterName + "/" + propertyName); if (CommonUtils.isNotBlank(filterValue)) { logger.info("Property [{}] loaded from JNDI Filter Specific Property with value [{}]", propertyName, filterValue); return filterValue; } - final String rootValue = loadFromContext(context, this.environmentPrefix + propertyName); + final var rootValue = loadFromContext(context, this.environmentPrefix + propertyName); if (CommonUtils.isNotBlank(rootValue)) { logger.info("Property [{}] loaded from JNDI with value [{}]", propertyName, rootValue); @@ -73,22 +84,11 @@ protected final String get(final ConfigurationKey configurationKey) { return null; } - private String loadFromContext(final InitialContext context, final String path) { + private static String loadFromContext(final InitialContext context, final String path) { try { return (String) context.lookup(path); } catch (final NamingException e) { return null; } } - - - @Override - public final void init(final FilterConfig filterConfig, final Class clazz) { - this.simpleFilterName = clazz.getSimpleName(); - try { - this.context = new InitialContext(); - } catch (final NamingException e) { - logger.error("Unable to create InitialContext. No properties can be loaded via JNDI.", e); - } - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/LegacyConfigurationStrategyImpl.java similarity index 74% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/LegacyConfigurationStrategyImpl.java index 22b31c591..0f5badadf 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/LegacyConfigurationStrategyImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/LegacyConfigurationStrategyImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,16 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import org.jasig.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.CommonUtils; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; /** - * Replicates the original behavior by checking the {@link org.jasig.cas.client.configuration.WebXmlConfigurationStrategyImpl} first, and then - * the {@link org.jasig.cas.client.configuration.JndiConfigurationStrategyImpl} before using the defaultValue. + * Replicates the original behavior by checking the {@link WebXmlConfigurationStrategyImpl} first, and then + * the {@link JndiConfigurationStrategyImpl} before using the defaultValue. * * @author Scott Battaglia * @since 3.4.0 @@ -44,7 +44,7 @@ public void init(final FilterConfig filterConfig, final Class @Override protected String get(final ConfigurationKey key) { - final String value1 = this.webXmlConfigurationStrategy.get(key); + final var value1 = this.webXmlConfigurationStrategy.get(key); if (CommonUtils.isNotBlank(value1)) { return value1; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/PropertiesConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/PropertiesConfigurationStrategyImpl.java similarity index 74% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/PropertiesConfigurationStrategyImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/PropertiesConfigurationStrategyImpl.java index c88c75d41..5d4830429 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/PropertiesConfigurationStrategyImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/PropertiesConfigurationStrategyImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import org.jasig.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.CommonUtils; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; @@ -47,41 +48,41 @@ public final class PropertiesConfigurationStrategyImpl extends BaseConfiguration private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesConfigurationStrategyImpl.class); - private String simpleFilterName; - private final Properties properties = new Properties(); - @Override - protected String get(final ConfigurationKey configurationKey) { - final String property = configurationKey.getName(); - final String filterSpecificProperty = this.simpleFilterName + "." + property; - - final String filterSpecificValue = this.properties.getProperty(filterSpecificProperty); - - if (CommonUtils.isNotEmpty(filterSpecificValue)) { - return filterSpecificValue; - } - - return this.properties.getProperty(property); - } + private String simpleFilterName; @Override public void init(final FilterConfig filterConfig, final Class filterClazz) { this.simpleFilterName = filterClazz.getSimpleName(); - final String fileLocationFromFilterConfig = filterConfig.getInitParameter(CONFIGURATION_FILE_LOCATION); - final boolean filterConfigFileLoad = loadPropertiesFromFile(fileLocationFromFilterConfig); + final var fileLocationFromFilterConfig = filterConfig.getInitParameter(CONFIGURATION_FILE_LOCATION); + final var filterConfigFileLoad = loadPropertiesFromFile(fileLocationFromFilterConfig); if (!filterConfigFileLoad) { - final String fileLocationFromServletConfig = filterConfig.getServletContext().getInitParameter(CONFIGURATION_FILE_LOCATION); - final boolean servletContextFileLoad = loadPropertiesFromFile(fileLocationFromServletConfig); + final var fileLocationFromServletConfig = filterConfig.getServletContext().getInitParameter(CONFIGURATION_FILE_LOCATION); + final var servletContextFileLoad = loadPropertiesFromFile(fileLocationFromServletConfig); if (!servletContextFileLoad) { - final boolean defaultConfigFileLoaded = loadPropertiesFromFile(DEFAULT_CONFIGURATION_FILE_LOCATION); + final var defaultConfigFileLoaded = loadPropertiesFromFile(DEFAULT_CONFIGURATION_FILE_LOCATION); CommonUtils.assertTrue(defaultConfigFileLoaded, "unable to load properties to configure CAS client"); } } } + @Override + protected String get(final ConfigurationKey configurationKey) { + final var property = configurationKey.getName(); + final var filterSpecificProperty = this.simpleFilterName + "." + property; + + final var filterSpecificValue = this.properties.getProperty(filterSpecificProperty); + + if (CommonUtils.isNotEmpty(filterSpecificValue)) { + return filterSpecificValue; + } + + return this.properties.getProperty(property); + } + private boolean loadPropertiesFromFile(final String file) { if (CommonUtils.isEmpty(file)) { return false; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/SystemPropertiesConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/SystemPropertiesConfigurationStrategyImpl.java similarity index 87% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/SystemPropertiesConfigurationStrategyImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/SystemPropertiesConfigurationStrategyImpl.java index c8f1ba6d0..f224c139e 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/SystemPropertiesConfigurationStrategyImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/SystemPropertiesConfigurationStrategyImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; /** * Load all configuration from system properties. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/WebXmlConfigurationStrategyImpl.java similarity index 76% rename from cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/configuration/WebXmlConfigurationStrategyImpl.java index d9dbc00fa..82f51acce 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/configuration/WebXmlConfigurationStrategyImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,15 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import org.jasig.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.CommonUtils; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; /** - * Implementation of the {@link org.jasig.cas.client.configuration.ConfigurationStrategy} that first checks the {@link javax.servlet.FilterConfig} and + * Implementation of the {@link ConfigurationStrategy} that first checks the {@link javax.servlet.FilterConfig} and * then checks the {@link javax.servlet.ServletContext}, ultimately falling back to the defaultValue. * * @author Scott Battaglia @@ -34,9 +34,14 @@ public final class WebXmlConfigurationStrategyImpl extends BaseConfigurationStra private FilterConfig filterConfig; + @Override + public void init(final FilterConfig filterConfig, final Class clazz) { + this.filterConfig = filterConfig; + } + @Override protected String get(final ConfigurationKey configurationKey) { - final String value = this.filterConfig.getInitParameter(configurationKey.getName()); + final var value = this.filterConfig.getInitParameter(configurationKey.getName()); if (CommonUtils.isNotBlank(value)) { CommonUtils.assertFalse(ConfigurationKeys.RENEW.equals(configurationKey), "Renew MUST be specified via context parameter or JNDI environment to avoid misconfiguration."); @@ -44,19 +49,14 @@ protected String get(final ConfigurationKey configurationKey) { return value; } - final String value2 = filterConfig.getServletContext().getInitParameter(configurationKey.getName()); + final var value2 = filterConfig.getServletContext().getInitParameter(configurationKey.getName()); if (CommonUtils.isNotBlank(value2)) { logger.info("Property [{}] loaded from ServletContext.getInitParameter with value [{}]", configurationKey, - value2); + value2); return value2; } return null; } - - @Override - public void init(final FilterConfig filterConfig, final Class clazz) { - this.filterConfig = filterConfig; - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/AssertionPrincipal.java b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/AssertionPrincipal.java similarity index 87% rename from cas-client-core/src/main/java/org/jasig/cas/client/jaas/AssertionPrincipal.java rename to cas-client-core/src/main/java/org/apereo/cas/client/jaas/AssertionPrincipal.java index bf46e371e..ff27d6203 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/AssertionPrincipal.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/AssertionPrincipal.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.jaas; +package org.apereo.cas.client.jaas; + +import org.apereo.cas.client.authentication.SimplePrincipal; +import org.apereo.cas.client.validation.Assertion; +import java.io.Serial; import java.io.Serializable; -import org.jasig.cas.client.authentication.SimplePrincipal; -import org.jasig.cas.client.validation.Assertion; /** * Principal implementation that contains the CAS ticket validation assertion. @@ -33,6 +35,7 @@ public class AssertionPrincipal extends SimplePrincipal implements Serializable { /** AssertionPrincipal.java */ + @Serial private static final long serialVersionUID = 2288520214366461693L; /** CAS assertion describing authenticated state */ diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/CasLoginModule.java b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/CasLoginModule.java similarity index 72% rename from cas-client-core/src/main/java/org/jasig/cas/client/jaas/CasLoginModule.java rename to cas-client-core/src/main/java/org/apereo/cas/client/jaas/CasLoginModule.java index 6868e66a1..05b6b6eac 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/CasLoginModule.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/CasLoginModule.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,29 +16,38 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.jaas; +package org.apereo.cas.client.jaas; + +import org.apereo.cas.client.authentication.SimplePrincipal; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.ReflectUtils; +import org.apereo.cas.client.validation.Assertion; +import org.apereo.cas.client.validation.TicketValidator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; -import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.IOException; import java.security.Principal; -import java.security.acl.Group; -import java.util.*; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.concurrent.TimeUnit; -import javax.security.auth.Subject; -import javax.security.auth.callback.*; -import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; -import org.jasig.cas.client.authentication.SimpleGroup; -import org.jasig.cas.client.authentication.SimplePrincipal; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * JAAS login module that delegates to a CAS {@link TicketValidator} component @@ -46,7 +55,7 @@ * data including NetID and principal attributes. The module expects to be provided * with the CAS ticket (required) and service (optional) parameters via * {@link PasswordCallback} and {@link NameCallback}, respectively, by the - * {@link CallbackHandler} that is part of the JAAS framework in which the servlet + * {@link CallbackHandler} that is part of the JAAS framework in which the servlet * resides. * *

@@ -83,14 +92,13 @@ * Sample jaas.config file entry for this module: *

  * cas {
- *   org.jasig.cas.client.jaas.CasLoginModule required
- *     ticketValidatorClass="org.jasig.cas.client.validation.Saml11TicketValidator"
+ *   org.apereo.cas.client.jaas.CasLoginModule required
+ *     ticketValidatorClass="org.apereocas.client.validation.Saml11TicketValidator"
  *     casServerUrlPrefix="https://cas.example.com/cas"
  *     tolerance="20000"
  *     service="https://webapp.example.com/webapp"
  *     defaultRoles="admin,operator"
  *     roleAttributeNames="memberOf,eduPersonAffiliation"
- *     principalGroupName="CallerPrincipal"
  *     roleGroupName="Roles";
  * }
  * 
@@ -98,10 +106,11 @@ * @author Marvin S. Addison * @version $Revision$ $Date$ * @since 3.1.11 - * */ public class CasLoginModule implements LoginModule { - /** Constant for login name stored in shared state. */ + /** + * Constant for login name stored in shared state. + */ public static final String LOGIN_NAME = "javax.security.auth.login.name"; /** @@ -123,7 +132,9 @@ public class CasLoginModule implements LoginModule { */ public static final int DEFAULT_CACHE_TIMEOUT = 480; - /** Default assertion cache timeout unit is minutes. */ + /** + * Default assertion cache timeout unit is minutes. + */ public static final TimeUnit DEFAULT_CACHE_TIMEOUT_UNIT = TimeUnit.MINUTES; /** @@ -132,76 +143,131 @@ public class CasLoginModule implements LoginModule { * CAS tickets are one-time-use, a cached assertion must be provided on * re-authentication. */ - protected static final Map ASSERTION_CACHE = new HashMap(); + protected static final Map ASSERTION_CACHE = new HashMap<>(); - /** Logger instance */ + /** + * Logger instance + */ protected final Logger logger = LoggerFactory.getLogger(getClass()); - /** JAAS authentication subject */ + /** + * Names of attributes in the CAS assertion that should be used for role data + */ + protected final Collection roleAttributeNames = new HashSet<>(); + + /** + * JAAS authentication subject + */ protected Subject subject; - /** JAAS callback handler */ + /** + * JAAS callback handler + */ protected CallbackHandler callbackHandler; - /** CAS ticket validator */ + /** + * CAS ticket validator + */ protected TicketValidator ticketValidator; - /** CAS service parameter used if no service is provided via TextCallback on login */ + /** + * CAS service parameter used if no service is provided via TextCallback on login + */ protected String service; - /** CAS assertion */ + /** + * CAS assertion + */ protected Assertion assertion; - /** CAS ticket credential */ + /** + * CAS ticket credential + */ protected TicketCredential ticket; - /** Login module shared state */ + /** + * Login module shared state + */ protected Map sharedState; - /** Roles to be added to all authenticated principals by default */ + /** + * Roles to be added to all authenticated principals by default + */ protected String[] defaultRoles; - /** Names of attributes in the CAS assertion that should be used for role data */ - protected final Set roleAttributeNames = new HashSet(); - - /** Name of JAAS Group containing caller principal */ + /** + * Name of JAAS Group containing caller principal + */ protected String principalGroupName = DEFAULT_PRINCIPAL_GROUP_NAME; - /** Name of JAAS Group containing role data */ + /** + * Name of JAAS Group containing role data + */ protected String roleGroupName = DEFAULT_ROLE_GROUP_NAME; - /** Enables or disable assertion caching */ + /** + * Enables or disable assertion caching + */ protected boolean cacheAssertions; - /** Assertion cache timeout in minutes */ + /** + * Assertion cache timeout in minutes + */ protected int cacheTimeout = DEFAULT_CACHE_TIMEOUT; - /** Units of cache timeout. */ + /** + * Units of cache timeout. + */ protected TimeUnit cacheTimeoutUnit = DEFAULT_CACHE_TIMEOUT_UNIT; + /** + * Attempts to do simple type conversion from a string value to the type expected + * by the given property. + *

+ * Currently only conversion to int, long, and boolean are supported. + * + * @param pd Property descriptor of target property to set. + * @param value Property value as a string. + * @return Value converted to type expected by property if a conversion strategy exists. + */ + private static Object convertIfNecessary(final PropertyDescriptor pd, final String value) { + if (String.class.equals(pd.getPropertyType())) { + return value; + } else if (boolean.class.equals(pd.getPropertyType())) { + return Boolean.valueOf(value); + } else if (int.class.equals(pd.getPropertyType())) { + return new Integer(value); + } else if (long.class.equals(pd.getPropertyType())) { + return new Long(value); + } else { + throw new IllegalArgumentException("No conversion strategy exists for property " + pd.getName() + + " of type " + pd.getPropertyType()); + } + } + /** * Initializes the CAS login module. * * @param subject Authentication subject. * @param handler Callback handler. - * @param state Shared state map. + * @param state Shared state map. * @param options Login module options. The following are supported: - *

    - *
  • service - CAS service URL used for service ticket validation.
  • - *
  • ticketValidatorClass - fully-qualified class name of service ticket validator component.
  • - *
  • defaultRoles (optional) - comma-delimited list of roles to be added to all authenticated principals.
  • - *
  • roleAttributeNames (optional) - comma-delimited list of attributes in the CAS assertion that contain role data.
  • - *
  • principalGroupName (optional) - name of JAAS Group containing caller principal.
  • - *
  • roleGroupName (optional) - name of JAAS Group containing role data
  • - *
  • cacheAssertions (optional) - whether or not to cache assertions. - * Some JAAS providers attempt to reauthenticate users after an indeterminate - * period of time. Since the credential used for authentication is a CAS ticket, - * which by default are single use, reauthentication fails. Assertion caching addresses this - * behavior.
  • - *
  • cacheTimeout (optional) - assertion cache timeout in minutes.
  • - *
  • cacheTimeoutUnit (optional) - Assertion cache timeout unit. Must be one of {@link TimeUnit} enumeration - * names, e.g. DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS. Default unit is MINUTES.
  • - *
+ *
    + *
  • service - CAS service URL used for service ticket validation.
  • + *
  • ticketValidatorClass - fully-qualified class name of service ticket validator component.
  • + *
  • defaultRoles (optional) - comma-delimited list of roles to be added to all authenticated principals.
  • + *
  • roleAttributeNames (optional) - comma-delimited list of attributes in the CAS assertion that contain role data.
  • + *
  • principalGroupName (optional) - name of JAAS Group containing caller principal.
  • + *
  • roleGroupName (optional) - name of JAAS Group containing role data
  • + *
  • cacheAssertions (optional) - whether or not to cache assertions. + * Some JAAS providers attempt to reauthenticate users after an indeterminate + * period of time. Since the credential used for authentication is a CAS ticket, + * which by default are single use, reauthentication fails. Assertion caching addresses this + * behavior.
  • + *
  • cacheTimeout (optional) - assertion cache timeout in minutes.
  • + *
  • cacheTimeoutUnit (optional) - Assertion cache timeout unit. Must be one of {@link TimeUnit} enumeration + * names, e.g. DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS. Default unit is MINUTES.
  • + *
*/ @Override public final void initialize(final Subject subject, final CallbackHandler handler, final Map state, @@ -211,11 +277,11 @@ public final void initialize(final Subject subject, final CallbackHandler handle this.callbackHandler = handler; this.subject = subject; this.sharedState = (Map) state; - this.sharedState = new HashMap(state); + this.sharedState = new HashMap<>(state); String ticketValidatorClass = null; - for (final String key : options.keySet()) { + for (final var key : options.keySet()) { logger.trace("Processing option {}", key); if ("service".equals(key)) { this.service = (String) options.get(key); @@ -224,14 +290,14 @@ public final void initialize(final Subject subject, final CallbackHandler handle ticketValidatorClass = (String) options.get(key); logger.debug("Set ticketValidatorClass={}", ticketValidatorClass); } else if ("defaultRoles".equals(key)) { - final String roles = (String) options.get(key); + final var roles = (String) options.get(key); logger.trace("Got defaultRoles value {}", roles); this.defaultRoles = roles.split(",\\s*"); logger.debug("Set defaultRoles={}", Arrays.asList(this.defaultRoles)); } else if ("roleAttributeNames".equals(key)) { - final String attrNames = (String) options.get(key); + final var attrNames = (String) options.get(key); logger.trace("Got roleAttributeNames value {}", attrNames); - final String[] attributes = attrNames.split(",\\s*"); + final var attributes = attrNames.split(",\\s*"); this.roleAttributeNames.addAll(Arrays.asList(attributes)); logger.debug("Set roleAttributeNames={}", this.roleAttributeNames); } else if ("principalGroupName".equals(key)) { @@ -260,24 +326,6 @@ public final void initialize(final Subject subject, final CallbackHandler handle this.ticketValidator = createTicketValidator(ticketValidatorClass, options); } - /** - * Operations to perform before doing login. - * - * @return true if you'd like login to continue, false otherwise. - */ - protected boolean preLogin() { - return true; - } - - /** - * This occurs after logout is processed. - * - * @param result the result from the login attempt. - */ - protected void postLogin(final boolean result) { - // template method - } - @Override public final boolean login() throws LoginException { logger.debug("Performing login."); @@ -287,25 +335,25 @@ public final boolean login() throws LoginException { return false; } - final NameCallback serviceCallback = new NameCallback("service"); - final PasswordCallback ticketCallback = new PasswordCallback("ticket", false); - boolean result = false; + final var serviceCallback = new NameCallback("service"); + final var ticketCallback = new PasswordCallback("ticket", false); + var result = false; try { try { - this.callbackHandler.handle(new Callback[] { ticketCallback, serviceCallback }); + this.callbackHandler.handle(new Callback[]{ticketCallback, serviceCallback}); } catch (final IOException e) { logger.info("Login failed due to IO exception in callback handler", e); throw (LoginException) new LoginException("IO exception in callback handler: " + e).initCause(e); } catch (final UnsupportedCallbackException e) { logger.info("Login failed due to unsupported callback", e); throw (LoginException) new LoginException( - "Callback handler does not support PasswordCallback and TextInputCallback.").initCause(e); + "Callback handler does not support PasswordCallback and TextInputCallback.").initCause(e); } if (ticketCallback.getPassword() != null) { this.ticket = new TicketCredential(new String(ticketCallback.getPassword())); - final String service = CommonUtils.isNotBlank(serviceCallback.getName()) ? serviceCallback.getName() - : this.service; + final var service = CommonUtils.isNotBlank(serviceCallback.getName()) ? serviceCallback.getName() + : this.service; if (this.cacheAssertions) { this.assertion = ASSERTION_CACHE.get(ticket); @@ -319,11 +367,11 @@ public final boolean login() throws LoginException { if (CommonUtils.isBlank(service)) { logger.info("Login failed because required CAS service parameter not provided."); throw new LoginException( - "Neither login module nor callback handler provided required service parameter."); + "Neither login module nor callback handler provided required service parameter."); } try { logger.debug("Attempting ticket validation with service={} and ticket={}", service, - this.ticket); + this.ticket); this.assertion = this.ticketValidator.validate(this.ticket.getName(), service); } catch (final Exception e) { @@ -343,42 +391,13 @@ public final boolean login() throws LoginException { return result; } - @Override - public final boolean abort() throws LoginException { - if (this.ticket != null) { - this.ticket = null; - } - if (this.assertion != null) { - this.assertion = null; - } - return true; - } - - /** - * Operations to perform before doing commit. - * - * @return true if you'd like commit to continue, false otherwise. - */ - protected boolean preCommit() { - return true; - } - - /** - * This occurs after commit is processed. - * - * @param result the result from the login attempt. - */ - protected void postCommit(final boolean result) { - // template method - } - @Override public final boolean commit() throws LoginException { if (!preCommit()) { return false; } - boolean result = false; + var result = false; try { if (this.assertion != null) { if (this.ticket != null) { @@ -387,39 +406,10 @@ public final boolean commit() throws LoginException { throw new LoginException("Ticket credential not found."); } - final AssertionPrincipal casPrincipal = new AssertionPrincipal(this.assertion.getPrincipal().getName(), - this.assertion); + final Principal casPrincipal = new AssertionPrincipal(this.assertion.getPrincipal().getName(), + this.assertion); this.subject.getPrincipals().add(casPrincipal); - // Add group containing principal as sole member - // Supports JBoss JAAS use case - final Group principalGroup = new SimpleGroup(this.principalGroupName); - principalGroup.addMember(casPrincipal); - this.subject.getPrincipals().add(principalGroup); - - // Add group principal containing role data - final Group roleGroup = new SimpleGroup(this.roleGroupName); - - for (final String defaultRole : defaultRoles) { - roleGroup.addMember(new SimplePrincipal(defaultRole)); - } - - final Map attributes = this.assertion.getPrincipal().getAttributes(); - for (final String key : attributes.keySet()) { - if (this.roleAttributeNames.contains(key)) { - // Attribute value is Object if singular or Collection if plural - final Object value = attributes.get(key); - if (value instanceof Collection) { - for (final Object o : (Collection) value) { - roleGroup.addMember(new SimplePrincipal(o.toString())); - } - } else { - roleGroup.addMember(new SimplePrincipal(value.toString())); - } - } - } - this.subject.getPrincipals().add(roleGroup); - // Place principal name in shared state for downstream JAAS modules (module chaining use case) this.sharedState.put(LOGIN_NAME, assertion.getPrincipal().getName()); @@ -443,6 +433,17 @@ public final boolean commit() throws LoginException { return result; } + @Override + public final boolean abort() throws LoginException { + if (this.ticket != null) { + this.ticket = null; + } + if (this.assertion != null) { + this.assertion = null; + } + return true; + } + @Override public final boolean logout() throws LoginException { logger.debug("Performing logout."); @@ -453,7 +454,7 @@ public final boolean logout() throws LoginException { // Remove cache entry if assertion caching is enabled if (this.cacheAssertions) { - for (final TicketCredential ticket : this.subject.getPrivateCredentials(TicketCredential.class)) { + for (final var ticket : this.subject.getPrivateCredentials(TicketCredential.class)) { logger.debug("Removing cached assertion for {}", ticket); ASSERTION_CACHE.remove(ticket); } @@ -462,7 +463,6 @@ public final boolean logout() throws LoginException { // Remove all CAS principals removePrincipalsOfType(AssertionPrincipal.class); removePrincipalsOfType(SimplePrincipal.class); - removePrincipalsOfType(SimpleGroup.class); // Remove all CAS credentials removeCredentialsOfType(TicketCredential.class); @@ -473,12 +473,48 @@ public final boolean logout() throws LoginException { return true; } + /** + * Operations to perform before doing login. + * + * @return true if you'd like login to continue, false otherwise. + */ + protected static boolean preLogin() { + return true; + } + + /** + * This occurs after logout is processed. + * + * @param result the result from the login attempt. + */ + protected void postLogin(final boolean result) { + // template method + } + + /** + * Operations to perform before doing commit. + * + * @return true if you'd like commit to continue, false otherwise. + */ + protected static boolean preCommit() { + return true; + } + + /** + * This occurs after commit is processed. + * + * @param result the result from the login attempt. + */ + protected void postCommit(final boolean result) { + // template method + } + /** * Happens before logout occurs. * * @return true if we should continue, false otherwise. */ - protected boolean preLogout() { + protected static boolean preLogout() { return true; } @@ -491,26 +527,27 @@ protected void postLogout() { /** * Creates a {@link TicketValidator} instance from a class name and map of property name/value pairs. - * @param className Fully-qualified name of {@link TicketValidator} concrete class. + * + * @param className Fully-qualified name of {@link TicketValidator} concrete class. * @param propertyMap Map of property name/value pairs to set on validator instance. * @return Ticket validator with properties set. */ private TicketValidator createTicketValidator(final String className, final Map propertyMap) { CommonUtils.assertTrue(propertyMap.containsKey("casServerUrlPrefix"), - "Required property casServerUrlPrefix not found."); + "Required property casServerUrlPrefix not found."); final Class validatorClass = ReflectUtils.loadClass(className); - final TicketValidator validator = ReflectUtils.newInstance(validatorClass, - propertyMap.get("casServerUrlPrefix")); + final var validator = ReflectUtils.newInstance(validatorClass, + propertyMap.get("casServerUrlPrefix")); try { - final BeanInfo info = Introspector.getBeanInfo(validatorClass); + final var info = Introspector.getBeanInfo(validatorClass); - for (final String property : propertyMap.keySet()) { + for (final var property : propertyMap.keySet()) { if (!"casServerUrlPrefix".equals(property)) { logger.debug("Attempting to set TicketValidator property {}", property); - final String value = (String) propertyMap.get(property); - final PropertyDescriptor pd = ReflectUtils.getPropertyDescriptor(info, property); + final var value = (String) propertyMap.get(property); + final var pd = ReflectUtils.getPropertyDescriptor(info, property); if (pd != null) { ReflectUtils.setProperty(property, convertIfNecessary(pd, value), validator, info); logger.debug("Set {} = {}", property, value); @@ -526,33 +563,9 @@ private TicketValidator createTicketValidator(final String className, final Map< return validator; } - /** - * Attempts to do simple type conversion from a string value to the type expected - * by the given property. - * - * Currently only conversion to int, long, and boolean are supported. - * - * @param pd Property descriptor of target property to set. - * @param value Property value as a string. - * @return Value converted to type expected by property if a conversion strategy exists. - */ - private static Object convertIfNecessary(final PropertyDescriptor pd, final String value) { - if (String.class.equals(pd.getPropertyType())) { - return value; - } else if (boolean.class.equals(pd.getPropertyType())) { - return Boolean.valueOf(value); - } else if (int.class.equals(pd.getPropertyType())) { - return new Integer(value); - } else if (long.class.equals(pd.getPropertyType())) { - return new Long(value); - } else { - throw new IllegalArgumentException("No conversion strategy exists for property " + pd.getName() - + " of type " + pd.getPropertyType()); - } - } - /** * Removes all principals of the given type from the JAAS subject. + * * @param clazz Type of principal to remove. */ private void removePrincipalsOfType(final Class clazz) { @@ -561,6 +574,7 @@ private void removePrincipalsOfType(final Class clazz) { /** * Removes all credentials of the given type from the JAAS subject. + * * @param clazz Type of principal to remove. */ private void removeCredentialsOfType(final Class clazz) { @@ -572,12 +586,12 @@ private void removeCredentialsOfType(final Class clazz) { */ private void cleanCache() { logger.debug("Cleaning assertion cache of size {}", ASSERTION_CACHE.size()); - final Iterator> iter = ASSERTION_CACHE.entrySet().iterator(); - final Calendar cutoff = Calendar.getInstance(); + final var iter = ASSERTION_CACHE.entrySet().iterator(); + final var cutoff = Calendar.getInstance(); cutoff.setTimeInMillis(System.currentTimeMillis() - this.cacheTimeoutUnit.toMillis(this.cacheTimeout)); while (iter.hasNext()) { - final Assertion assertion = iter.next().getValue(); - final Calendar created = Calendar.getInstance(); + final var assertion = iter.next().getValue(); + final var created = Calendar.getInstance(); created.setTime(assertion.getValidFromDate()); if (created.before(cutoff)) { logger.debug("Removing expired assertion for principal {}", assertion.getPrincipal()); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/ServiceAndTicketCallbackHandler.java b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/ServiceAndTicketCallbackHandler.java similarity index 83% rename from cas-client-core/src/main/java/org/jasig/cas/client/jaas/ServiceAndTicketCallbackHandler.java rename to cas-client-core/src/main/java/org/apereo/cas/client/jaas/ServiceAndTicketCallbackHandler.java index 2f5f52eaf..429364e68 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/ServiceAndTicketCallbackHandler.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/ServiceAndTicketCallbackHandler.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.jaas; +package org.apereo.cas.client.jaas; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; -import javax.security.auth.callback.*; /** * Callback handler that provides the CAS service and ticket to a @@ -52,7 +56,7 @@ public ServiceAndTicketCallbackHandler(final String service, final String ticket @Override public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (final Callback callback : callbacks) { + for (final var callback : callbacks) { if (callback instanceof NameCallback) { ((NameCallback) callback).setName(this.service); } else if (callback instanceof PasswordCallback) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/Servlet3AuthenticationFilter.java similarity index 74% rename from cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/jaas/Servlet3AuthenticationFilter.java index dc06a9353..b1a961fc5 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/Servlet3AuthenticationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/Servlet3AuthenticationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,22 +16,21 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.jaas; +package org.apereo.cas.client.jaas; -import java.io.IOException; -import java.security.GeneralSecurityException; +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.util.AbstractCasFilter; +import org.apereo.cas.client.util.WebUtils; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.CommonUtils; +import java.io.IOException; +import java.security.GeneralSecurityException; /** * Servlet filter performs a programmatic JAAS login using the Servlet 3.0 HttpServletRequest#login() facility. @@ -39,14 +38,14 @@ *

* The filter executes when it receives a CAS ticket and expects the * {@link CasLoginModule} JAAS module to perform the CAS - * ticket validation in order to produce an {@link org.jasig.cas.client.jaas.AssertionPrincipal} from which + * ticket validation in order to produce an {@link AssertionPrincipal} from which * the CAS assertion is obtained and inserted into the session to enable SSO. *

* If a service init-param is specified for this filter, it supersedes * the service defined for the {@link CasLoginModule}. * - * @author Daniel Fisher - * @author Marvin S. Addison + * @author Daniel Fisher + * @author Marvin S. Addison * @since 3.3 */ public final class Servlet3AuthenticationFilter extends AbstractCasFilter { @@ -58,18 +57,18 @@ public Servlet3AuthenticationFilter() { @Override public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain chain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - final HttpSession session = request.getSession(); - final String ticket = CommonUtils.safeGetParameter(request, getProtocol().getArtifactParameterName()); + final var request = (HttpServletRequest) servletRequest; + final var response = (HttpServletResponse) servletResponse; + final var session = request.getSession(); + final var ticket = WebUtils.safeGetParameter(request, getProtocol().getArtifactParameterName()); if (session != null && session.getAttribute(CONST_CAS_ASSERTION) == null && ticket != null) { try { - final String service = constructServiceUrl(request, response); + final var service = constructServiceUrl(request, response); logger.debug("Attempting CAS ticket validation with service={} and ticket={}", service, ticket); request.login(service, ticket); if (request.getUserPrincipal() instanceof AssertionPrincipal) { - final AssertionPrincipal principal = (AssertionPrincipal) request.getUserPrincipal(); + final var principal = (AssertionPrincipal) request.getUserPrincipal(); logger.debug("Installing CAS assertion into session."); request.getSession().setAttribute(CONST_CAS_ASSERTION, principal.getAssertion()); } else { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/TicketCredential.java b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/TicketCredential.java similarity index 85% rename from cas-client-core/src/main/java/org/jasig/cas/client/jaas/TicketCredential.java rename to cas-client-core/src/main/java/org/apereo/cas/client/jaas/TicketCredential.java index 16814ee09..4d4039629 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/jaas/TicketCredential.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/jaas/TicketCredential.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.jaas; +package org.apereo.cas.client.jaas; import java.security.Principal; @@ -49,27 +49,30 @@ public String getName() { return this.ticket; } - public String toString() { - return this.ticket; + public int hashCode() { + var hash = HASHCODE_SEED; + hash = hash * 31 + (ticket == null ? 0 : ticket.hashCode()); + return hash; } public boolean equals(final Object o) { - if (this == o) + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; + } - final TicketCredential that = (TicketCredential) o; + final var that = (TicketCredential) o; - if (ticket != null ? !ticket.equals(that.ticket) : that.ticket != null) + if (ticket != null ? !ticket.equals(that.ticket) : that.ticket != null) { return false; + } return true; } - public int hashCode() { - int hash = HASHCODE_SEED; - hash = hash * 31 + (ticket == null ? 0 : ticket.hashCode()); - return hash; + public String toString() { + return this.ticket; } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java similarity index 91% rename from cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java index 9cfa69727..0d6536dab 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/AbstractEncryptedProxyGrantingTicketStorageImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,17 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; -import org.jasig.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESedeKeySpec; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; -import javax.crypto.Cipher; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.DESedeKeySpec; /** * Provides encryption capabilities. Not entirely safe to configure since we have no way of controlling the @@ -43,7 +43,7 @@ public abstract class AbstractEncryptedProxyGrantingTicketStorageImpl implements private String cipherAlgorithm = ConfigurationKeys.CIPHER_ALGORITHM.getDefaultValue(); public final void setSecretKey(final String key) throws NoSuchAlgorithmException, InvalidKeyException, - InvalidKeySpecException { + InvalidKeySpecException { this.key = SecretKeyFactory.getInstance(this.cipherAlgorithm).generateSecret(new DESedeKeySpec(key.getBytes())); } @@ -84,7 +84,7 @@ private String encrypt(final String value) { } try { - final Cipher cipher = Cipher.getInstance(this.cipherAlgorithm); + final var cipher = Cipher.getInstance(this.cipherAlgorithm); cipher.init(Cipher.ENCRYPT_MODE, this.key); return new String(cipher.doFinal(value.getBytes())); } catch (final Exception e) { @@ -102,7 +102,7 @@ private String decrypt(final String value) { } try { - final Cipher cipher = Cipher.getInstance(this.cipherAlgorithm); + final var cipher = Cipher.getInstance(this.cipherAlgorithm); cipher.init(Cipher.DECRYPT_MODE, this.key); return new String(cipher.doFinal(value.getBytes())); } catch (final Exception e) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/Cas20ProxyRetriever.java b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/Cas20ProxyRetriever.java similarity index 83% rename from cas-client-core/src/main/java/org/jasig/cas/client/proxy/Cas20ProxyRetriever.java rename to cas-client-core/src/main/java/org/apereo/cas/client/proxy/Cas20ProxyRetriever.java index 10d455149..6deec531a 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/Cas20ProxyRetriever.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/Cas20ProxyRetriever.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,16 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; + +import org.apereo.cas.client.ssl.HttpURLConnectionFactory; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.XmlUtils; -import java.net.URL; -import java.net.URLEncoder; -import org.jasig.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.XmlUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serial; +import java.net.URL; +import java.net.URLEncoder; + /** * Implementation of a ProxyRetriever that follows the CAS 2.0 specification. * For more information on the CAS 2.0 specification, please see the + * 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 @@ -16,7 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; + +import org.apereo.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter; import java.util.TimerTask; @@ -24,9 +26,9 @@ * A {@link TimerTask} implementation which performs the * actual 'cleaning' by calling {@link ProxyGrantingTicketStorage#cleanUp()}. *

- * By default, the {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter} configures - * a task that cleans up the {@link org.jasig.cas.client.proxy.ProxyGrantingTicketStorage} associated with it. - * + * By default, the {@link Cas20ProxyReceivingTicketValidationFilter} configures + * a task that cleans up the {@link ProxyGrantingTicketStorage} associated with it. + * * @author Brad Cupit (brad [at] lsu {dot} edu) * @version $Revision$ $Date$ * @since 3.1.6 diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorage.java b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorage.java similarity index 95% rename from cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorage.java rename to cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorage.java index 2094f4600..786557fbc 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorage.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorage.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; /** * Interface for the storage and retrieval of ProxyGrantingTicketIds by mapping diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorageImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorageImpl.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorageImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorageImpl.java index 1dadb4962..b5820bf5b 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorageImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorageImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,15 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; + +import org.apereo.cas.client.util.CommonUtils; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import org.jasig.cas.client.util.CommonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + /** * Implementation of {@link ProxyGrantingTicketStorage} that is backed by a * HashMap that keeps a ProxyGrantingTicket for a specified amount of time. @@ -38,22 +39,22 @@ */ public final class ProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage { - private final Logger logger = LoggerFactory.getLogger(getClass()); - /** * Default timeout in milliseconds. */ private static final long DEFAULT_TIMEOUT = 60000; + private final Logger logger = LoggerFactory.getLogger(getClass()); + /** * Map that stores the PGTIOU to PGT mappings. */ - private final ConcurrentMap cache = new ConcurrentHashMap(); + private final ConcurrentMap cache = new ConcurrentHashMap<>(); /** * time, in milliseconds, before a {@link ProxyGrantingTicketHolder} * is considered expired and ready for removal. - * + * * @see ProxyGrantingTicketStorageImpl#DEFAULT_TIMEOUT */ private final long timeout; @@ -75,6 +76,15 @@ public ProxyGrantingTicketStorageImpl(final long timeout) { this.timeout = timeout; } + @Override + public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { + final var holder = new ProxyGrantingTicketHolder(proxyGrantingTicket); + + logger.debug("Saving ProxyGrantingTicketIOU and ProxyGrantingTicket combo: [{}, {}]", proxyGrantingTicketIou, + proxyGrantingTicket); + this.cache.put(proxyGrantingTicketIou, holder); + } + /** * NOTE: you can only retrieve a ProxyGrantingTicket once with this method. * Its removed after retrieval. @@ -85,7 +95,7 @@ public String retrieve(final String proxyGrantingTicketIou) { return null; } - final ProxyGrantingTicketHolder holder = this.cache.get(proxyGrantingTicketIou); + final var holder = this.cache.get(proxyGrantingTicketIou); if (holder == null) { logger.info("No Proxy Ticket found for [{}].", proxyGrantingTicketIou); @@ -98,22 +108,13 @@ public String retrieve(final String proxyGrantingTicketIou) { return holder.getProxyGrantingTicket(); } - @Override - public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { - final ProxyGrantingTicketHolder holder = new ProxyGrantingTicketHolder(proxyGrantingTicket); - - logger.debug("Saving ProxyGrantingTicketIOU and ProxyGrantingTicket combo: [{}, {}]", proxyGrantingTicketIou, - proxyGrantingTicket); - this.cache.put(proxyGrantingTicketIou, holder); - } - /** * Cleans up old, expired proxy tickets. This method must be * called regularly via an external thread or timer. */ @Override public void cleanUp() { - for (final Map.Entry holder : this.cache.entrySet()) { + for (final var holder : this.cache.entrySet()) { if (holder.getValue().isExpired(this.timeout)) { this.cache.remove(holder.getKey()); } @@ -126,7 +127,7 @@ private static final class ProxyGrantingTicketHolder { private final long timeInserted; - protected ProxyGrantingTicketHolder(final String proxyGrantingTicket) { + private ProxyGrantingTicketHolder(final String proxyGrantingTicket) { this.proxyGrantingTicket = proxyGrantingTicket; this.timeInserted = System.currentTimeMillis(); } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyRetriever.java b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyRetriever.java similarity index 92% rename from cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyRetriever.java rename to cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyRetriever.java index 9b2de4616..aff767ff0 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/ProxyRetriever.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/ProxyRetriever.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; import java.io.Serializable; @@ -27,6 +27,7 @@ * @author Scott Battaglia * @since 3.0 */ +@FunctionalInterface public interface ProxyRetriever extends Serializable { /** diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/proxy/package.html b/cas-client-core/src/main/java/org/apereo/cas/client/proxy/package.html similarity index 100% rename from cas-client-core/src/main/java/org/jasig/cas/client/proxy/package.html rename to cas-client-core/src/main/java/org/apereo/cas/client/proxy/package.html diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/HashMapBackedSessionMappingStorage.java b/cas-client-core/src/main/java/org/apereo/cas/client/session/HashMapBackedSessionMappingStorage.java similarity index 85% rename from cas-client-core/src/main/java/org/jasig/cas/client/session/HashMapBackedSessionMappingStorage.java rename to cas-client-core/src/main/java/org/apereo/cas/client/session/HashMapBackedSessionMappingStorage.java index 5ff123b41..93577a3c5 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/HashMapBackedSessionMappingStorage.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/session/HashMapBackedSessionMappingStorage.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,17 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; +package org.apereo.cas.client.session; -import java.util.HashMap; -import java.util.Map; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.HashMap; +import java.util.Map; + /** * HashMap backed implementation of SessionMappingStorage. - * + * * @author Scott Battaglia * @version $Revision$ $Date$ * @since 3.1 @@ -37,27 +38,31 @@ public final class HashMapBackedSessionMappingStorage implements SessionMappingS /** * Maps the ID from the CAS server to the Session. */ - private final Map MANAGED_SESSIONS = new HashMap(); + private final Map MANAGED_SESSIONS = new HashMap<>(); /** * Maps the Session ID to the key from the CAS Server. */ - private final Map ID_TO_SESSION_KEY_MAPPING = new HashMap(); + private final Map ID_TO_SESSION_KEY_MAPPING = new HashMap<>(); private final Logger logger = LoggerFactory.getLogger(getClass()); @Override - public synchronized void addSessionById(final String mappingId, final HttpSession session) { - ID_TO_SESSION_KEY_MAPPING.put(session.getId(), mappingId); - MANAGED_SESSIONS.put(mappingId, session); + public synchronized HttpSession removeSessionByMappingId(final String mappingId) { + final var session = MANAGED_SESSIONS.get(mappingId); + + if (session != null) { + removeBySessionById(session.getId()); + } + return session; } @Override public synchronized void removeBySessionById(final String sessionId) { logger.debug("Attempting to remove Session=[{}]", sessionId); - final String key = ID_TO_SESSION_KEY_MAPPING.get(sessionId); + final var key = ID_TO_SESSION_KEY_MAPPING.get(sessionId); if (logger.isDebugEnabled()) { if (key != null) { @@ -71,13 +76,9 @@ public synchronized void removeBySessionById(final String sessionId) { } @Override - public synchronized HttpSession removeSessionByMappingId(final String mappingId) { - final HttpSession session = MANAGED_SESSIONS.get(mappingId); - - if (session != null) { - removeBySessionById(session.getId()); - } + public synchronized void addSessionById(final String mappingId, final HttpSession session) { + ID_TO_SESSION_KEY_MAPPING.put(session.getId(), mappingId); + MANAGED_SESSIONS.put(mappingId, session); - return session; } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SessionMappingStorage.java b/cas-client-core/src/main/java/org/apereo/cas/client/session/SessionMappingStorage.java similarity index 88% rename from cas-client-core/src/main/java/org/jasig/cas/client/session/SessionMappingStorage.java rename to cas-client-core/src/main/java/org/apereo/cas/client/session/SessionMappingStorage.java index 0a532051a..7eabab908 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SessionMappingStorage.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/session/SessionMappingStorage.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; +package org.apereo.cas.client.session; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; /** * Stores the mapping between sessions and keys to be retrieved later. - * + * * @author Scott Battaglia * @version $Revision$ $Date$ * @since 3.1 @@ -32,7 +32,7 @@ public interface SessionMappingStorage { /** * Remove the HttpSession based on the mappingId. - * + * * @param mappingId the id the session is keyed under. * @return the HttpSession if it exists. */ diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutFilter.java similarity index 73% rename from cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutFilter.java index 0884b2759..dc5d47710 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,17 +16,21 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; +package org.apereo.cas.client.session; -import java.io.IOException; -import java.util.concurrent.atomic.AtomicBoolean; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.util.AbstractConfigurationFilter; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.util.AbstractConfigurationFilter; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; /** * Implements the Single Sign Out protocol. It handles registering the session and destroying the session. @@ -41,6 +45,10 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter { private final AtomicBoolean handlerInitialized = new AtomicBoolean(false); + static SingleSignOutHandler getSingleSignOutHandler() { + return HANDLER; + } + @Override public void init(final FilterConfig filterConfig) throws ServletException { super.init(filterConfig); @@ -56,35 +64,35 @@ public void init(final FilterConfig filterConfig) throws ServletException { handlerInitialized.set(true); } - public void setArtifactParameterName(final String name) { + public static void setArtifactParameterName(final String name) { HANDLER.setArtifactParameterName(name); } - public void setLogoutParameterName(final String name) { + public static void setLogoutParameterName(final String name) { HANDLER.setLogoutParameterName(name); } - - public void setRelayStateParameterName(final String name) { + + public static void setRelayStateParameterName(final String name) { HANDLER.setRelayStateParameterName(name); } - public void setLogoutCallbackPath(final String logoutCallbackPath) { + public static void setLogoutCallbackPath(final String logoutCallbackPath) { HANDLER.setLogoutCallbackPath(logoutCallbackPath); } - public void setSessionMappingStorage(final SessionMappingStorage storage) { + public static void setSessionMappingStorage(final SessionMappingStorage storage) { HANDLER.setSessionMappingStorage(storage); } @Override public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; + final var request = (HttpServletRequest) servletRequest; + final var response = (HttpServletResponse) servletResponse; /** *

Workaround for now for the fact that Spring Security will fail since it doesn't call {@link #init(javax.servlet.FilterConfig)}.

- *

Ultimately we need to allow deployers to actually inject their fully-initialized {@link org.jasig.cas.client.session.SingleSignOutHandler}.

+ *

Ultimately we need to allow deployers to actually inject their fully-initialized {@link SingleSignOutHandler}.

*/ if (!this.handlerInitialized.getAndSet(true)) { HANDLER.init(); @@ -99,8 +107,4 @@ public void doFilter(final ServletRequest servletRequest, final ServletResponse public void destroy() { // nothing to do } - - protected static SingleSignOutHandler getSingleSignOutHandler() { - return HANDLER; - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java b/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHandler.java similarity index 76% rename from cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java rename to cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHandler.java index f5a325b96..0c706bdd1 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHandler.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHandler.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,26 +16,30 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; +package org.apereo.cas.client.session; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.zip.Inflater; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.util.JSONPObject; +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.WebUtils; +import org.apereo.cas.client.util.XmlUtils; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.xml.bind.DatatypeConverter; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.XmlUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.zip.Inflater; + /** * Performs CAS single sign-out operations in an API-agnostic fashion. * @@ -46,20 +50,29 @@ */ public final class SingleSignOutHandler { - private final static int DECOMPRESSION_FACTOR = 10; + private static final int DECOMPRESSION_FACTOR = 10; /** Logger instance */ private final Logger logger = LoggerFactory.getLogger(getClass()); + private final LogoutStrategy logoutStrategy = isServlet30() ? new Servlet30LogoutStrategy() : new Servlet25LogoutStrategy(); + + private final ObjectMapper mapper = new ObjectMapper(); + /** Mapping of token IDs and session IDs to HTTP sessions */ private SessionMappingStorage sessionMappingStorage = new HashMapBackedSessionMappingStorage(); /** The name of the artifact parameter. This is used to capture the session identifier. */ private String artifactParameterName = Protocol.CAS2.getArtifactParameterName(); + /** + * The name of the JSONP callback parameter for front-channel logout requests + */ + private String jsonpCallbackParameterName = ConfigurationKeys.JSONP_CALLBACK_PARAMETER_NAME.getDefaultValue(); + /** Parameter name that stores logout request for SLO */ private String logoutParameterName = ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue(); - + /** Parameter name that stores the state of the CAS server webflow for the callback */ private String relayStateParameterName = ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue(); @@ -72,10 +85,12 @@ public final class SingleSignOutHandler { private List safeParameters; - private final LogoutStrategy logoutStrategy = isServlet30() ? new Servlet30LogoutStrategy() : new Servlet25LogoutStrategy(); - - public void setSessionMappingStorage(final SessionMappingStorage storage) { - this.sessionMappingStorage = storage; + private static boolean isServlet30() { + try { + return HttpServletRequest.class.getMethod("logout") != null; + } catch (final NoSuchMethodException e) { + return false; + } } public void setArtifactParameterOverPost(final boolean artifactParameterOverPost) { @@ -86,6 +101,10 @@ public SessionMappingStorage getSessionMappingStorage() { return this.sessionMappingStorage; } + public void setSessionMappingStorage(final SessionMappingStorage storage) { + this.sessionMappingStorage = storage; + } + /** * @param name Name of the authentication token parameter. */ @@ -93,6 +112,13 @@ public void setArtifactParameterName(final String name) { this.artifactParameterName = name; } + /** + * @param name Name of the JSONP callback parameter for front-channel logout requests. + */ + public void setJsonpCallbackParameterName(final String name) { + this.jsonpCallbackParameterName = name; + } + /** * @param name Name of parameter containing CAS logout request message for SLO. */ @@ -136,6 +162,67 @@ public synchronized void init() { } } + /** + * Process a request regarding the SLO process: record the session or destroy it. + * + * @param request the incoming HTTP request. + * @param response the HTTP response. + * @return if the request should continue to be processed. + */ + public boolean process(final HttpServletRequest request, final HttpServletResponse response) { + if (isTokenRequest(request)) { + logger.trace("Received a token request"); + recordSession(request); + return true; + } + + if (isLogoutRequest(request)) { + logger.trace("Received a logout request"); + destroySession(request); + final var callback = WebUtils.safeGetParameter(request, this.jsonpCallbackParameterName, this.safeParameters); + if (callback != null) { + try { + response.setContentType("application/javascript"); + mapper.writeValue(response.getWriter(), new JSONPObject(callback, true)); + } catch (final Exception e) { + logger.debug("Error writing JSONP logout response.", e); + } + } + return false; + } + logger.trace("Ignoring URI for logout: {}", request.getRequestURI()); + return true; + } + + /** + * Abstracts the ways we can force logout with the Servlet spec. + */ + @FunctionalInterface + private interface LogoutStrategy { + + void logout(HttpServletRequest request); + } + + private static class Servlet25LogoutStrategy implements LogoutStrategy { + + @Override + public void logout(final HttpServletRequest request) { + // nothing additional to do here + } + } + + private class Servlet30LogoutStrategy implements LogoutStrategy { + + @Override + public void logout(final HttpServletRequest request) { + try { + request.logout(); + } catch (final ServletException e) { + logger.debug("Error performing request.logout."); + } + } + } + /** * Determines whether the given request contains an authentication token. * @@ -144,8 +231,8 @@ public synchronized void init() { * @return True if request contains authentication token, false otherwise. */ private boolean isTokenRequest(final HttpServletRequest request) { - return CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.artifactParameterName, - this.safeParameters)); + return CommonUtils.isNotBlank(WebUtils.safeGetParameter(request, this.artifactParameterName, + this.safeParameters)); } /** @@ -158,13 +245,13 @@ private boolean isTokenRequest(final HttpServletRequest request) { private boolean isLogoutRequest(final HttpServletRequest request) { if ("POST".equalsIgnoreCase(request.getMethod())) { return !isMultipartRequest(request) - && pathEligibleForLogout(request) - && CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName, - this.safeParameters)); + && pathEligibleForLogout(request) + && CommonUtils.isNotBlank(WebUtils.safeGetParameter(request, this.logoutParameterName, + this.safeParameters)); } - + if ("GET".equalsIgnoreCase(request.getMethod())) { - return CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters)); + return CommonUtils.isNotBlank(WebUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters)); } return false; } @@ -173,48 +260,25 @@ private boolean pathEligibleForLogout(final HttpServletRequest request) { return logoutCallbackPath == null || logoutCallbackPath.equals(getPath(request)); } - private String getPath(final HttpServletRequest request) { + private static String getPath(final HttpServletRequest request) { return request.getServletPath() + CommonUtils.nullToEmpty(request.getPathInfo()); } - /** - * Process a request regarding the SLO process: record the session or destroy it. - * - * @param request the incoming HTTP request. - * @param response the HTTP response. - * @return if the request should continue to be processed. - */ - public boolean process(final HttpServletRequest request, final HttpServletResponse response) { - if (isTokenRequest(request)) { - logger.trace("Received a token request"); - recordSession(request); - return true; - } - - if (isLogoutRequest(request)) { - logger.trace("Received a logout request"); - destroySession(request); - return false; - } - logger.trace("Ignoring URI for logout: {}", request.getRequestURI()); - return true; - } - /** * Associates a token request with the current HTTP session by recording the mapping * in the the configured {@link SessionMappingStorage} container. - * + * * @param request HTTP request containing an authentication token. */ private void recordSession(final HttpServletRequest request) { - final HttpSession session = request.getSession(this.eagerlyCreateSessions); + final var session = request.getSession(this.eagerlyCreateSessions); if (session == null) { logger.debug("No session currently exists (and none created). Cannot record session information for single sign out."); return; } - final String token = CommonUtils.safeGetParameter(request, this.artifactParameterName, this.safeParameters); + final var token = WebUtils.safeGetParameter(request, this.artifactParameterName, this.safeParameters); logger.debug("Recording session for token {}", token); try { @@ -227,21 +291,21 @@ private void recordSession(final HttpServletRequest request) { /** * Uncompress a logout message (base64 + deflate). - * + * * @param originalMessage the original logout message. * @return the uncompressed logout message. */ private String uncompressLogoutMessage(final String originalMessage) { - final byte[] binaryMessage = DatatypeConverter.parseBase64Binary(originalMessage); + final var binaryMessage = Base64.getDecoder().decode(originalMessage); Inflater decompresser = null; try { // decompress the bytes decompresser = new Inflater(); decompresser.setInput(binaryMessage); - final byte[] result = new byte[binaryMessage.length * DECOMPRESSION_FACTOR]; + final var result = new byte[binaryMessage.length * DECOMPRESSION_FACTOR]; - final int resultLength = decompresser.inflate(result); + final var resultLength = decompresser.inflate(result); // decode the bytes into a String return new String(result, 0, resultLength, "UTF-8"); @@ -261,23 +325,23 @@ private String uncompressLogoutMessage(final String originalMessage) { * @param request HTTP request containing a CAS logout message. */ private void destroySession(final HttpServletRequest request) { - String logoutMessage = CommonUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters); + var logoutMessage = WebUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters); if (CommonUtils.isBlank(logoutMessage)) { logger.error("Could not locate logout message of the request from {}", this.logoutParameterName); return; } - + if (!logoutMessage.contains("SessionIndex")) { logoutMessage = uncompressLogoutMessage(logoutMessage); } - + logger.trace("Logout request:\n{}", logoutMessage); - final String token = XmlUtils.getTextForElement(logoutMessage, "SessionIndex"); + final var token = XmlUtils.getTextForElement(logoutMessage, "SessionIndex"); if (CommonUtils.isNotBlank(token)) { - final HttpSession session = this.sessionMappingStorage.removeSessionByMappingId(token); + final var session = this.sessionMappingStorage.removeSessionByMappingId(token); if (session != null) { - final String sessionID = session.getId(); + final var sessionID = session.getId(); logger.debug("Invalidating session [{}] for token [{}]", sessionID, token); try { @@ -290,44 +354,7 @@ private void destroySession(final HttpServletRequest request) { } } - private boolean isMultipartRequest(final HttpServletRequest request) { + private static boolean isMultipartRequest(final ServletRequest request) { return request.getContentType() != null && request.getContentType().toLowerCase().startsWith("multipart"); } - - private static boolean isServlet30() { - try { - return HttpServletRequest.class.getMethod("logout") != null; - } catch (final NoSuchMethodException e) { - return false; - } - } - - - /** - * Abstracts the ways we can force logout with the Servlet spec. - */ - private interface LogoutStrategy { - - void logout(HttpServletRequest request); - } - - private class Servlet25LogoutStrategy implements LogoutStrategy { - - @Override - public void logout(final HttpServletRequest request) { - // nothing additional to do here - } - } - - private class Servlet30LogoutStrategy implements LogoutStrategy { - - @Override - public void logout(final HttpServletRequest request) { - try { - request.logout(); - } catch (final ServletException e) { - logger.debug("Error performing request.logout."); - } - } - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHttpSessionListener.java b/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHttpSessionListener.java similarity index 84% rename from cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHttpSessionListener.java rename to cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHttpSessionListener.java index b025a9b48..3455e6ab5 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutHttpSessionListener.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/session/SingleSignOutHttpSessionListener.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; +package org.apereo.cas.client.session; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; +import jakarta.servlet.http.HttpSessionEvent; +import jakarta.servlet.http.HttpSessionListener; /** * Listener to detect when an HTTP session is destroyed and remove it from the map of @@ -36,6 +35,16 @@ public final class SingleSignOutHttpSessionListener implements HttpSessionListen private SessionMappingStorage sessionMappingStorage; + /** + * Obtains a {@link SessionMappingStorage} object. Assumes this method will always return the same + * instance of the object. It assumes this because it generally lazily calls the method. + * + * @return the SessionMappingStorage + */ + private static SessionMappingStorage getSessionMappingStorage() { + return SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage(); + } + @Override public void sessionCreated(final HttpSessionEvent event) { // nothing to do at the moment @@ -46,17 +55,7 @@ public void sessionDestroyed(final HttpSessionEvent event) { if (sessionMappingStorage == null) { sessionMappingStorage = getSessionMappingStorage(); } - final HttpSession session = event.getSession(); + final var session = event.getSession(); sessionMappingStorage.removeBySessionById(session.getId()); } - - /** - * Obtains a {@link SessionMappingStorage} object. Assumes this method will always return the same - * instance of the object. It assumes this because it generally lazily calls the method. - * - * @return the SessionMappingStorage - */ - protected static SessionMappingStorage getSessionMappingStorage() { - return SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage(); - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/AnyHostnameVerifier.java b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/AnyHostnameVerifier.java similarity index 92% rename from cas-client-core/src/main/java/org/jasig/cas/client/ssl/AnyHostnameVerifier.java rename to cas-client-core/src/main/java/org/apereo/cas/client/ssl/AnyHostnameVerifier.java index 0f5833e4f..886d00701 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/AnyHostnameVerifier.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/AnyHostnameVerifier.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/HttpURLConnectionFactory.java b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/HttpURLConnectionFactory.java similarity index 88% rename from cas-client-core/src/main/java/org/jasig/cas/client/ssl/HttpURLConnectionFactory.java rename to cas-client-core/src/main/java/org/apereo/cas/client/ssl/HttpURLConnectionFactory.java index fe88eadf4..651da4497 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/HttpURLConnectionFactory.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/HttpURLConnectionFactory.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; import java.io.Serializable; import java.net.HttpURLConnection; @@ -24,11 +24,12 @@ import java.net.URLConnection; /** - * A factory to prepare and configure {@link java.net.URLConnection} instances. + * A factory to prepare and configure {@link URLConnection} instances. * * @author Misagh Moayyed * @since 3.3 */ +@FunctionalInterface public interface HttpURLConnectionFactory extends Serializable { /** @@ -36,10 +37,10 @@ public interface HttpURLConnectionFactory extends Serializable { * opening a connection to a remote resource. The received url connection is then * configured and prepared appropriately depending on its type and is then returned to the caller * to accommodate method chaining. - * + * * @param url The url connection that needs to be configured * @return The configured {@link HttpURLConnection} instance - * + * * @see {@link HttpsURLConnectionFactory} */ HttpURLConnection buildHttpURLConnection(final URLConnection url); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/HttpsURLConnectionFactory.java b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/HttpsURLConnectionFactory.java similarity index 89% rename from cas-client-core/src/main/java/org/jasig/cas/client/ssl/HttpsURLConnectionFactory.java rename to cas-client-core/src/main/java/org/apereo/cas/client/ssl/HttpsURLConnectionFactory.java index 0be712f9c..b5a3ee306 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/HttpsURLConnectionFactory.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/HttpsURLConnectionFactory.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,9 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; + +import org.apereo.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.CommonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,6 +35,7 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serial; import java.net.HttpURLConnection; import java.net.URLConnection; import java.security.KeyStore; @@ -53,6 +55,7 @@ */ public final class HttpsURLConnectionFactory implements HttpURLConnectionFactory { + @Serial private static final long serialVersionUID = 1L; private static final Logger LOGGER = LoggerFactory.getLogger(HttpsURLConnectionFactory.class); @@ -96,6 +99,13 @@ public HttpURLConnection buildHttpURLConnection(final URLConnection url) { return this.configureHttpsConnectionIfNeeded(url); } + @Override + public int hashCode() { + var result = hostnameVerifier.hashCode(); + result = 31 * result + sslConfiguration.hashCode(); + return result; + } + @Override public boolean equals(final Object o) { if (this == o) { @@ -105,7 +115,7 @@ public boolean equals(final Object o) { return false; } - final HttpsURLConnectionFactory that = (HttpsURLConnectionFactory) o; + final var that = (HttpsURLConnectionFactory) o; if (!hostnameVerifier.equals(that.hostnameVerifier)) { return false; @@ -117,13 +127,6 @@ public boolean equals(final Object o) { return true; } - @Override - public int hashCode() { - int result = hostnameVerifier.hashCode(); - result = 31 * result + sslConfiguration.hashCode(); - return result; - } - /** * Configures the connection with specific settings for secure http connections * If the connection instance is not a {@link HttpsURLConnection}, @@ -133,8 +136,8 @@ public int hashCode() { */ private HttpURLConnection configureHttpsConnectionIfNeeded(final URLConnection conn) { if (conn instanceof HttpsURLConnection) { - final HttpsURLConnection httpsConnection = (HttpsURLConnection) conn; - final SSLSocketFactory socketFactory = this.createSSLSocketFactory(); + final var httpsConnection = (HttpsURLConnection) conn; + final var socketFactory = this.createSSLSocketFactory(); if (socketFactory != null) { httpsConnection.setSSLSocketFactory(socketFactory); } @@ -169,29 +172,31 @@ private SSLSocketFactory createSSLSocketFactory() { InputStream keyStoreIS = null; try { - final SSLContext sslContext = SSLContext.getInstance(this.sslConfiguration.getProperty("protocol", "SSL")); + final var sslContext = SSLContext.getInstance(this.sslConfiguration.getProperty("protocol", "SSL")); if (isIgnoreSslFailures()) { - final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { - public X509Certificate[] getAcceptedIssuers() { - return null; - } + final var trustAllCerts = new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(final X509Certificate[] certs, final String authType) { } + public void checkServerTrusted(final X509Certificate[] certs, final String authType) { } + + public X509Certificate[] getAcceptedIssuers() { + return null; + } }}; sslContext.init(null, trustAllCerts, new SecureRandom()); return sslContext.getSocketFactory(); } if (this.sslConfiguration.getProperty("keyStoreType") != null) { - final KeyStore keyStore = KeyStore.getInstance(this.sslConfiguration.getProperty("keyStoreType")); + final var keyStore = KeyStore.getInstance(this.sslConfiguration.getProperty("keyStoreType")); if (this.sslConfiguration.getProperty("keyStorePath") != null) { keyStoreIS = new FileInputStream(this.sslConfiguration.getProperty("keyStorePath")); if (this.sslConfiguration.getProperty("keyStorePass") != null) { keyStore.load(keyStoreIS, this.sslConfiguration.getProperty("keyStorePass").toCharArray()); LOGGER.debug("Keystore has {} keys", keyStore.size()); - final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(this.sslConfiguration + final var keyManager = KeyManagerFactory.getInstance(this.sslConfiguration .getProperty("keyManagerType", "SunX509")); keyManager.init(keyStore, this.sslConfiguration.getProperty("certificatePassword").toCharArray()); sslContext.init(keyManager.getKeyManagers(), null, null); @@ -208,6 +213,7 @@ public void checkServerTrusted(final X509Certificate[] certs, final String authT return null; } + @Serial private void writeObject(final ObjectOutputStream out) throws IOException { if (this.hostnameVerifier == HttpsURLConnection.getDefaultHostnameVerifier()) { out.writeObject(null); @@ -219,8 +225,9 @@ private void writeObject(final ObjectOutputStream out) throws IOException { } + @Serial private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { - final Object internalHostNameVerifier = in.readObject(); + final var internalHostNameVerifier = in.readObject(); if (internalHostNameVerifier == null) { this.hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier(); } else { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/RegexHostnameVerifier.java b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/RegexHostnameVerifier.java similarity index 92% rename from cas-client-core/src/main/java/org/jasig/cas/client/ssl/RegexHostnameVerifier.java rename to cas-client-core/src/main/java/org/apereo/cas/client/ssl/RegexHostnameVerifier.java index 0b4378c81..a7cdec014 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/RegexHostnameVerifier.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/RegexHostnameVerifier.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,13 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; -import java.io.Serializable; -import java.util.regex.Pattern; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; +import java.io.Serial; +import java.io.Serializable; +import java.util.regex.Pattern; + /** * Validates an SSL peer's hostname using a regular expression that a candidate * host must match in order to be verified. @@ -34,6 +36,7 @@ */ public final class RegexHostnameVerifier implements HostnameVerifier, Serializable { + @Serial private static final long serialVersionUID = 1L; /** Allowed hostname pattern */ @@ -41,7 +44,7 @@ public final class RegexHostnameVerifier implements HostnameVerifier, Serializab /** * Creates a new instance using the given regular expression. - * + * * @param regex Regular expression describing allowed hosts. */ public RegexHostnameVerifier(final String regex) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/WhitelistHostnameVerifier.java b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/WhitelistHostnameVerifier.java similarity index 90% rename from cas-client-core/src/main/java/org/jasig/cas/client/ssl/WhitelistHostnameVerifier.java rename to cas-client-core/src/main/java/org/apereo/cas/client/ssl/WhitelistHostnameVerifier.java index 14c5fec0a..699431665 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/ssl/WhitelistHostnameVerifier.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/ssl/WhitelistHostnameVerifier.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; + +import java.io.Serial; import java.io.Serializable; /** @@ -32,6 +34,7 @@ */ public final class WhitelistHostnameVerifier implements HostnameVerifier, Serializable { + @Serial private static final long serialVersionUID = 1L; /** Allowed hosts */ @@ -39,7 +42,7 @@ public final class WhitelistHostnameVerifier implements HostnameVerifier, Serial /** * Creates a new instance using the given array of allowed hosts. - * + * * @param allowed Array of allowed hosts. */ public WhitelistHostnameVerifier(final String[] allowed) { @@ -48,7 +51,7 @@ public WhitelistHostnameVerifier(final String[] allowed) { /** * Creates a new instance using the given list of allowed hosts. - * + * * @param allowedList Comma-separated list of allowed hosts. */ public WhitelistHostnameVerifier(final String allowedList) { @@ -59,7 +62,7 @@ public WhitelistHostnameVerifier(final String allowedList) { @Override public boolean verify(final String hostname, final SSLSession session) { - for (final String allowedHost : this.allowedHosts) { + for (final var allowedHost : this.allowedHosts) { if (hostname.equalsIgnoreCase(allowedHost)) { return true; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/AbstractCasFilter.java similarity index 84% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/AbstractCasFilter.java index 83349a1cb..1f9a7a118 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractCasFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/AbstractCasFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,16 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Arrays; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.util.Collections; /** * Abstract filter that contains code that is common to all CAS filters. @@ -42,7 +43,7 @@ * @since 3.1 */ public abstract class AbstractCasFilter extends AbstractConfigurationFilter { - + /** Represents the constant for where the assertion will be located in memory. */ public static final String CONST_CAS_ASSERTION = "_const_cas_assertion_"; @@ -70,31 +71,21 @@ public final void init(final FilterConfig filterConfig) throws ServletException setServerName(getString(ConfigurationKeys.SERVER_NAME)); setService(getString(ConfigurationKeys.SERVICE)); setEncodeServiceUrl(getBoolean(ConfigurationKeys.ENCODE_SERVICE_URL)); - + initInternal(filterConfig); } init(); } - - /** Controls the ordering of filter initialization and checking by defining a method that runs before the init. - * @param filterConfig the original filter configuration. - * @throws ServletException if there is a problem. - * - */ - protected void initInternal(final FilterConfig filterConfig) throws ServletException { - // template method - } - /** * Initialization method. Called by Filter's init method or by Spring. Similar in concept to the InitializingBean interface's * afterPropertiesSet(); */ public void init() { CommonUtils.assertTrue(CommonUtils.isNotEmpty(this.serverName) || CommonUtils.isNotEmpty(this.service), - "serverName or service must be set."); + "serverName or service must be set."); CommonUtils.assertTrue(CommonUtils.isBlank(this.serverName) || CommonUtils.isBlank(this.service), - "serverName and service cannot both be set. You MUST ONLY set one."); + "serverName and service cannot both be set. You MUST ONLY set one."); } // empty implementation as most filters won't need this. @@ -103,12 +94,6 @@ public void destroy() { // nothing to do } - protected final String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response) { - return CommonUtils.constructServiceUrl(request, response, this.service, this.serverName, - this.protocol.getServiceParameterName(), - this.protocol.getArtifactParameterName(), this.encodeServiceUrl); - } - /** * Note that trailing slashes should not be used in the serverName. As a convenience for this common misconfiguration, we strip them from the provided * value. @@ -132,6 +117,21 @@ public final void setEncodeServiceUrl(final boolean encodeServiceUrl) { this.encodeServiceUrl = encodeServiceUrl; } + /** Controls the ordering of filter initialization and checking by defining a method that runs before the init. + * @param filterConfig the original filter configuration. + * @throws ServletException if there is a problem. + * + */ + protected void initInternal(final FilterConfig filterConfig) throws ServletException { + // template method + } + + protected final String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response) { + return WebUtils.constructServiceUrl(request, response, this.service, this.serverName, + this.protocol.getServiceParameterName(), + this.protocol.getArtifactParameterName(), this.encodeServiceUrl); + } + protected Protocol getProtocol() { return this.protocol; } @@ -143,7 +143,7 @@ protected Protocol getProtocol() { * @return the ticket if its found, null otherwise. */ protected String retrieveTicketFromRequest(final HttpServletRequest request) { - return CommonUtils.safeGetParameter(request, this.protocol.getArtifactParameterName(), - Arrays.asList(this.protocol.getArtifactParameterName())); + return WebUtils.safeGetParameter(request, this.protocol.getArtifactParameterName(), + Collections.singletonList(this.protocol.getArtifactParameterName())); } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/AbstractConfigurationFilter.java similarity index 83% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/AbstractConfigurationFilter.java index 750bf2ea5..eb52fbb04 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/AbstractConfigurationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,15 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; +import org.apereo.cas.client.configuration.ConfigurationKey; +import org.apereo.cas.client.configuration.ConfigurationStrategy; +import org.apereo.cas.client.configuration.ConfigurationStrategyName; -import org.jasig.cas.client.configuration.ConfigurationKey; -import org.jasig.cas.client.configuration.ConfigurationStrategy; -import org.jasig.cas.client.configuration.ConfigurationStrategyName; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +47,7 @@ public abstract class AbstractConfigurationFilter implements Filter { @Override public void init(final FilterConfig filterConfig) throws ServletException { - final String configurationStrategyName = filterConfig.getServletContext().getInitParameter(CONFIGURATION_STRATEGY_KEY); + final var configurationStrategyName = filterConfig.getServletContext().getInitParameter(CONFIGURATION_STRATEGY_KEY); this.configurationStrategy = ReflectUtils.newInstance(ConfigurationStrategyName.resolveToConfigurationStrategy(configurationStrategyName)); this.configurationStrategy.init(filterConfig, getClass()); } @@ -72,11 +72,11 @@ protected final Class getClass(final ConfigurationKey + * 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 @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; -import org.jasig.cas.client.validation.Assertion; +import org.apereo.cas.client.validation.Assertion; /** * Static holder that places Assertion in a ThreadLocal. @@ -31,7 +31,7 @@ public class AssertionHolder { /** * ThreadLocal to hold the Assertion for Threads to access. */ - private static final ThreadLocal threadLocal = new ThreadLocal(); + private static final ThreadLocal threadLocal = new ThreadLocal<>(); /** * Retrieve the assertion from the ThreadLocal. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/AssertionThreadLocalFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/AssertionThreadLocalFilter.java similarity index 68% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/AssertionThreadLocalFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/AssertionThreadLocalFilter.java index 1da42b213..d2378736b 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/AssertionThreadLocalFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/AssertionThreadLocalFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,13 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; + +import org.apereo.cas.client.validation.Assertion; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.validation.Assertion; /** * Places the assertion in a ThreadLocal such that other resources can access it that do not have access to the web tier session. @@ -40,11 +46,11 @@ public void init(final FilterConfig filterConfig) throws ServletException { @Override public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpSession session = request.getSession(false); - final Assertion assertion = (Assertion) (session == null ? request - .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session - .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)); + final var request = (HttpServletRequest) servletRequest; + final var session = request.getSession(false); + final var assertion = (Assertion) (session == null ? request + .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session + .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)); try { AssertionHolder.setAssertion(assertion); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/CommonUtils.java similarity index 59% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/CommonUtils.java index e75816190..8d9399884 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/CommonUtils.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,21 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; - -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.ssl.HttpsURLConnectionFactory; -import org.jasig.cas.client.validation.ProxyList; -import org.jasig.cas.client.validation.ProxyListEditor; +package org.apereo.cas.client.util; + +import org.apereo.cas.client.ssl.HttpURLConnectionFactory; +import org.apereo.cas.client.ssl.HttpsURLConnectionFactory; +import org.apereo.cas.client.validation.ProxyList; +import org.apereo.cas.client.validation.ProxyListEditor; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.SSLException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import java.io.Closeable; import java.io.IOException; import java.io.InputStreamReader; @@ -38,11 +34,7 @@ import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; -import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; /** * Common utilities so that we don't need to include Commons Lang. @@ -54,30 +46,8 @@ public final class CommonUtils { private static final Logger LOGGER = LoggerFactory.getLogger(CommonUtils.class); - /** - * Constant representing the ProxyGrantingTicket IOU Request Parameter. - */ - private static final String PARAM_PROXY_GRANTING_TICKET_IOU = "pgtIou"; - - /** - * Constant representing the ProxyGrantingTicket Request Parameter. - */ - private static final String PARAM_PROXY_GRANTING_TICKET = "pgtId"; - private static final HttpURLConnectionFactory DEFAULT_URL_CONNECTION_FACTORY = new HttpsURLConnectionFactory(); - private static final String SERVICE_PARAMETER_NAMES; - - static { - final Set serviceParameterSet = new HashSet(4); - for (final Protocol protocol : Protocol.values()) { - serviceParameterSet.add(protocol.getServiceParameterName()); - } - SERVICE_PARAMETER_NAMES = serviceParameterSet.toString() - .replaceAll("\\[|\\]", "") - .replaceAll("\\s", ""); - } - private CommonUtils() { // nothing to do } @@ -142,7 +112,7 @@ public static void assertFalse(final boolean cond, final String message) { * @param string the string to check * @return true if its null or length of 0, false otherwise. */ - public static boolean isEmpty(final String string) { + public static boolean isEmpty(final CharSequence string) { return string == null || string.isEmpty(); } @@ -193,8 +163,8 @@ public static boolean isNotBlank(final String string) { public static String constructRedirectUrl(final String casServerLoginUrl, final String serviceParameterName, final String serviceUrl, final boolean renew, final boolean gateway, final String method) { return casServerLoginUrl + (casServerLoginUrl.contains("?") ? "&" : "?") + serviceParameterName + "=" - + urlEncode(serviceUrl) + (renew ? "&renew=true" : "") + (gateway ? "&gateway=true" : "") - + (method != null ? "&method=" + method : ""); + + urlEncode(serviceUrl) + (renew ? "&renew=true" : "") + (gateway ? "&gateway=true" : "") + + (method != null ? "&method=" + method : ""); } /** @@ -226,186 +196,6 @@ public static String urlEncode(final String value) { } } - public static void readAndRespondToProxyReceptorRequest(final HttpServletRequest request, - final HttpServletResponse response, final ProxyGrantingTicketStorage proxyGrantingTicketStorage) - throws IOException { - final String proxyGrantingTicketIou = request.getParameter(PARAM_PROXY_GRANTING_TICKET_IOU); - - final String proxyGrantingTicket = request.getParameter(PARAM_PROXY_GRANTING_TICKET); - - if (CommonUtils.isBlank(proxyGrantingTicket) || CommonUtils.isBlank(proxyGrantingTicketIou)) { - response.getWriter().write(""); - return; - } - - LOGGER.debug("Received proxyGrantingTicketId [{}] for proxyGrantingTicketIou [{}]", proxyGrantingTicket, - proxyGrantingTicketIou); - - proxyGrantingTicketStorage.save(proxyGrantingTicketIou, proxyGrantingTicket); - - LOGGER.debug("Successfully saved proxyGrantingTicketId [{}] for proxyGrantingTicketIou [{}]", - proxyGrantingTicket, proxyGrantingTicketIou); - - response.getWriter().write(""); - response.getWriter().write(""); - } - - protected static String findMatchingServerName(final HttpServletRequest request, final String serverName) { - final String[] serverNames = serverName.split(" "); - - if (serverNames.length == 0 || serverNames.length == 1) { - return serverName; - } - - final String host = request.getHeader("Host"); - final String xHost = request.getHeader("X-Forwarded-Host"); - - final String comparisonHost; - comparisonHost = (xHost != null) ? xHost : host; - - if (comparisonHost == null) { - return serverName; - } - - for (final String server : serverNames) { - final String lowerCaseServer = server.toLowerCase(); - - if (lowerCaseServer.contains(comparisonHost)) { - return server; - } - } - - return serverNames[0]; - } - - private static boolean requestIsOnStandardPort(final HttpServletRequest request) { - final int serverPort = request.getServerPort(); - return serverPort == 80 || serverPort == 443; - } - - /** - * Constructs a service url from the HttpServletRequest or from the given - * serviceUrl. Prefers the serviceUrl provided if both a serviceUrl and a - * serviceName. Compiles a list of all service parameters for supported protocols - * and removes them all from the query string. - * - * @param request the HttpServletRequest - * @param response the HttpServletResponse - * @param service the configured service url (this will be used if not null) - * @param serverNames the server name to use to construct the service url if the service param is empty. Note, prior to CAS Client 3.3, this was a single value. - * As of 3.3, it can be a space-separated value. We keep it as a single value, but will convert it to an array internally to get the matching value. This keeps backward compatability with anything using this public - * method. - * @param artifactParameterName the artifact parameter name to remove (i.e. ticket) - * @param encode whether to encode the url or not (i.e. Jsession). - * @return the service url to use. - */ - @Deprecated - public static String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response, - final String service, final String serverNames, - final String artifactParameterName, final boolean encode) { - return constructServiceUrl(request, response, service, serverNames, SERVICE_PARAMETER_NAMES - , artifactParameterName, encode); - } - - /** - * Constructs a service url from the HttpServletRequest or from the given - * serviceUrl. Prefers the serviceUrl provided if both a serviceUrl and a - * serviceName. - * - * @param request the HttpServletRequest - * @param response the HttpServletResponse - * @param service the configured service url (this will be used if not null) - * @param serverNames the server name to use to construct the service url if the service param is empty. Note, prior to CAS Client 3.3, this was a single value. - * As of 3.3, it can be a space-separated value. We keep it as a single value, but will convert it to an array internally to get the matching value. This keeps backward compatability with anything using this public - * method. - * @param serviceParameterName the service parameter name to remove (i.e. service) - * @param artifactParameterName the artifact parameter name to remove (i.e. ticket) - * @param encode whether to encode the url or not (i.e. Jsession). - * @return the service url to use. - */ - public static String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response, - final String service, final String serverNames, final String serviceParameterName, - final String artifactParameterName, final boolean encode) { - if (CommonUtils.isNotBlank(service)) { - return encode ? response.encodeURL(service) : service; - } - - final String serverName = findMatchingServerName(request, serverNames); - final URIBuilder originalRequestUrl = new URIBuilder(request.getRequestURL().toString(), encode); - originalRequestUrl.setParameters(request.getQueryString()); - - final URIBuilder builder; - if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) { - final String scheme = request.isSecure() ? "https://" : "http://"; - builder = new URIBuilder(scheme + serverName, encode); - } else { - builder = new URIBuilder(serverName, encode); - } - - if (builder.getPort() == -1 && !requestIsOnStandardPort(request)) { - builder.setPort(request.getServerPort()); - } - - builder.setEncodedPath(builder.getEncodedPath() + request.getRequestURI()); - - final List serviceParameterNames = Arrays.asList(serviceParameterName.split(",")); - if (!serviceParameterNames.isEmpty() && !originalRequestUrl.getQueryParams().isEmpty()) { - for (final URIBuilder.BasicNameValuePair pair : originalRequestUrl.getQueryParams()) { - final String name = pair.getName(); - if (!name.equals(artifactParameterName) && !serviceParameterNames.contains(name)) { - if (name.contains("&") || name.contains("=")) { - final URIBuilder encodedParamBuilder = new URIBuilder(); - encodedParamBuilder.setParameters(name); - for (final URIBuilder.BasicNameValuePair pair2 : encodedParamBuilder.getQueryParams()) { - final String name2 = pair2.getName(); - if (!name2.equals(artifactParameterName) && !serviceParameterNames.contains(name2)) { - builder.addParameter(name2, pair2.getValue()); - } - } - } else { - builder.addParameter(name, pair.getValue()); - } - } - } - } - - final String result = builder.toString(); - final String returnValue = encode ? response.encodeURL(result) : result; - LOGGER.debug("serviceUrl generated: {}", returnValue); - return returnValue; - } - - /** - * Safe method for retrieving a parameter from the request without disrupting the reader UNLESS the parameter - * actually exists in the query string. - *

- * Note, this does not work for POST Requests for "logoutRequest". It works for all other CAS POST requests because the - * parameter is ALWAYS in the GET request. - *

- * If we see the "logoutRequest" parameter we MUST treat it as if calling the standard request.getParameter. - *

- * Note, that as of 3.3.0, we've made it more generic. - *

- * - * @param request the request to check. - * @param parameter the parameter to look for. - * @return the value of the parameter. - */ - public static String safeGetParameter(final HttpServletRequest request, final String parameter, - final List parameters) { - if ("POST".equals(request.getMethod()) && parameters.contains(parameter)) { - LOGGER.debug("safeGetParameter called on a POST HttpServletRequest for Restricted Parameters. Cannot complete check safely. Reverting to standard behavior for this Parameter"); - return request.getParameter(parameter); - } - return request.getQueryString() == null || !request.getQueryString().contains(parameter) ? null : request - .getParameter(parameter); - } - - public static String safeGetParameter(final HttpServletRequest request, final String parameter) { - return safeGetParameter(request, parameter, Arrays.asList("logoutRequest")); - } - - /** * Contacts the remote URL and returns the response. * @@ -449,7 +239,7 @@ public static String getResponseFromServer(final URL constructedUrl, final HttpU in = new InputStreamReader(conn.getInputStream(), encoding); } - final StringBuilder builder = new StringBuilder(255); + final var builder = new StringBuilder(255); int byteRead; while ((byteRead = in.read()) != -1) { builder.append((char) byteRead); @@ -478,28 +268,13 @@ public static ProxyList createProxyList(final String proxies) { return new ProxyList(); } - final ProxyListEditor editor = new ProxyListEditor(); + final var editor = new ProxyListEditor(); editor.setAsText(proxies); return (ProxyList) editor.getValue(); } /** - * Sends the redirect message and captures the exceptions that we can't possibly do anything with. - * - * @param response the HttpServletResponse. CANNOT be NULL. - * @param url the url to redirect to. - */ - public static void sendRedirect(final HttpServletResponse response, final String url) { - try { - response.sendRedirect(url); - } catch (final IOException e) { - LOGGER.warn(e.getMessage(), e); - } - - } - - /** - * Unconditionally close a {@link Closeable}. Equivalent to {@link java.io.Closeable#close()}close(), except any exceptions + * Unconditionally close a {@link Closeable}. Equivalent to {@link Closeable#close()}close(), except any exceptions * will be ignored. This is typically used in finally blocks. * @param resource the resource to close */ @@ -580,7 +355,7 @@ public static boolean toBoolean(final String str) { * @param str the String to check; upper and lower case are treated as the same * @return the Boolean value of the string, {@code null} if no match or {@code null} input */ - public static Boolean toBooleanObject(final String str) { + public static Boolean toBooleanObject(final CharSequence str) { // Previously used equalsIgnoreCase, which was fast for interned 'true'. // Non interned 'true' matched 15 times slower. // @@ -595,7 +370,7 @@ public static Boolean toBooleanObject(final String str) { } switch (str.length()) { case 1: { - final char ch0 = str.charAt(0); + final var ch0 = str.charAt(0); if (ch0 == 'y' || ch0 == 'Y' || ch0 == 't' || ch0 == 'T') { return Boolean.TRUE; @@ -607,8 +382,8 @@ public static Boolean toBooleanObject(final String str) { break; } case 2: { - final char ch0 = str.charAt(0); - final char ch1 = str.charAt(1); + final var ch0 = str.charAt(0); + final var ch1 = str.charAt(1); if ((ch0 == 'o' || ch0 == 'O') && (ch1 == 'n' || ch1 == 'N')) { return Boolean.TRUE; @@ -620,9 +395,9 @@ public static Boolean toBooleanObject(final String str) { break; } case 3: { - final char ch0 = str.charAt(0); - final char ch1 = str.charAt(1); - final char ch2 = str.charAt(2); + final var ch0 = str.charAt(0); + final var ch1 = str.charAt(1); + final var ch2 = str.charAt(2); if ((ch0 == 'y' || ch0 == 'Y') && (ch1 == 'e' || ch1 == 'E') && (ch2 == 's' || ch2 == 'S')) { @@ -636,10 +411,10 @@ public static Boolean toBooleanObject(final String str) { break; } case 4: { - final char ch0 = str.charAt(0); - final char ch1 = str.charAt(1); - final char ch2 = str.charAt(2); - final char ch3 = str.charAt(3); + final var ch0 = str.charAt(0); + final var ch1 = str.charAt(1); + final var ch2 = str.charAt(2); + final var ch3 = str.charAt(3); if ((ch0 == 't' || ch0 == 'T') && (ch1 == 'r' || ch1 == 'R') && (ch2 == 'u' || ch2 == 'U') && @@ -649,11 +424,11 @@ public static Boolean toBooleanObject(final String str) { break; } case 5: { - final char ch0 = str.charAt(0); - final char ch1 = str.charAt(1); - final char ch2 = str.charAt(2); - final char ch3 = str.charAt(3); - final char ch4 = str.charAt(4); + final var ch0 = str.charAt(0); + final var ch1 = str.charAt(1); + final var ch2 = str.charAt(2); + final var ch3 = str.charAt(3); + final var ch4 = str.charAt(4); if ((ch0 == 'f' || ch0 == 'F') && (ch1 == 'a' || ch1 == 'A') && (ch2 == 'l' || ch2 == 'L') && diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/DelegatingFilter.java similarity index 77% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/DelegatingFilter.java index 852cd3677..58184775b 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/DelegatingFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Map; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * A Delegating Filter looks up a parameter in the request object and matches @@ -62,12 +68,12 @@ public final class DelegatingFilter implements Filter { private final boolean exactMatch; public DelegatingFilter(final String requestParameterName, final Map delegators, - final boolean exactMatch) { + final boolean exactMatch) { this(requestParameterName, delegators, exactMatch, null); } public DelegatingFilter(final String requestParameterName, final Map delegators, - final boolean exactMatch, final Filter defaultFilter) { + final boolean exactMatch, final Filter defaultFilter) { CommonUtils.assertNotNull(requestParameterName, "requestParameterName cannot be null."); CommonUtils.assertTrue(!delegators.isEmpty(), "delegators cannot be empty."); @@ -78,22 +84,22 @@ public DelegatingFilter(final String requestParameterName, final Map + * 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 @@ -16,17 +16,22 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Enumeration; -import java.util.List; -import javax.servlet.*; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Filters that redirects to the supplied url based on an exception. Exceptions and the urls are configured via @@ -45,25 +50,37 @@ public final class ErrorRedirectFilter implements Filter { private final Logger logger = LoggerFactory.getLogger(getClass()); - private final List errors = new ArrayList(); + private final Collection errors = new ArrayList<>(); private String defaultErrorRedirectPage; @Override - public void destroy() { - // nothing to do here + public void init(final FilterConfig filterConfig) throws ServletException { + this.defaultErrorRedirectPage = filterConfig.getInitParameter("defaultErrorRedirectPage"); + + final Enumeration enumeration = filterConfig.getInitParameterNames(); + while (enumeration.hasMoreElements()) { + final var className = (String) enumeration.nextElement(); + try { + if (!className.equals("defaultErrorRedirectPage")) { + this.errors.add(new ErrorHolder(className, filterConfig.getInitParameter(className))); + } + } catch (final ClassNotFoundException e) { + logger.warn("Class [{}] cannot be found in ClassLoader. Ignoring.", className); + } + } } @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) - throws IOException, ServletException { - final HttpServletResponse httpResponse = (HttpServletResponse) response; + throws IOException, ServletException { + final var httpResponse = (HttpServletResponse) response; try { filterChain.doFilter(request, response); } catch (final Exception e) { - final Throwable t = extractErrorToCompare(e); + final var t = extractErrorToCompare(e); ErrorHolder currentMatch = null; - for (final ErrorHolder errorHolder : this.errors) { + for (final var errorHolder : this.errors) { if (errorHolder.exactMatch(t)) { currentMatch = errorHolder; break; @@ -80,37 +97,9 @@ public void doFilter(final ServletRequest request, final ServletResponse respons } } - /** - * Determine which error to use for comparison. If there is an {@link Throwable#getCause()} then that will be used. Otherwise, the original throwable is used. - * - * @param throwable the throwable to look for a root cause. - * @return the throwable to use for comparison. MUST NOT BE NULL. - */ - private Throwable extractErrorToCompare(final Throwable throwable) { - final Throwable cause = throwable.getCause(); - - if (cause != null) { - return cause; - } - - return throwable; - } - @Override - public void init(final FilterConfig filterConfig) throws ServletException { - this.defaultErrorRedirectPage = filterConfig.getInitParameter("defaultErrorRedirectPage"); - - final Enumeration enumeration = filterConfig.getInitParameterNames(); - while (enumeration.hasMoreElements()) { - final String className = (String) enumeration.nextElement(); - try { - if (!className.equals("defaultErrorRedirectPage")) { - this.errors.add(new ErrorHolder(className, filterConfig.getInitParameter(className))); - } - } catch (final ClassNotFoundException e) { - logger.warn("Class [{}] cannot be found in ClassLoader. Ignoring.", className); - } - } + public void destroy() { + // nothing to do here } protected final class ErrorHolder { @@ -119,7 +108,7 @@ protected final class ErrorHolder { private String url; - protected ErrorHolder(final String className, final String url) throws ClassNotFoundException { + private ErrorHolder(final String className, final String url) throws ClassNotFoundException { this.className = Class.forName(className); this.url = url; } @@ -136,4 +125,20 @@ public String getUrl() { return this.url; } } + + /** + * Determine which error to use for comparison. If there is an {@link Throwable#getCause()} then that will be used. Otherwise, the original throwable is used. + * + * @param throwable the throwable to look for a root cause. + * @return the throwable to use for comparison. MUST NOT BE NULL. + */ + private static Throwable extractErrorToCompare(final Throwable throwable) { + final var cause = throwable.getCause(); + + if (cause != null) { + return cause; + } + + return throwable; + } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/HttpServletRequestWrapperFilter.java similarity index 79% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/HttpServletRequestWrapperFilter.java index ff5e71396..eecf4f56a 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/HttpServletRequestWrapperFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,18 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; + +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.validation.Assertion; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import java.io.IOException; import java.security.Principal; import java.util.Collection; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.validation.Assertion; /** * Implementation of a filter that wraps the normal HttpServletRequest with a @@ -54,11 +59,6 @@ public final class HttpServletRequestWrapperFilter extends AbstractConfiguration /** Whether or not to ignore case in role membership queries */ private boolean ignoreCase; - @Override - public void destroy() { - // nothing to do - } - /** * Wraps the HttpServletRequest in a wrapper class that delegates * request.getRemoteUser to the underlying Assertion object @@ -67,20 +67,15 @@ public void destroy() { @Override public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { - final AttributePrincipal principal = retrievePrincipalFromSessionOrRequest(servletRequest); + final var principal = retrievePrincipalFromSessionOrRequest(servletRequest); filterChain.doFilter(new CasHttpServletRequestWrapper((HttpServletRequest) servletRequest, principal), - servletResponse); + servletResponse); } - protected AttributePrincipal retrievePrincipalFromSessionOrRequest(final ServletRequest servletRequest) { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpSession session = request.getSession(false); - final Assertion assertion = (Assertion) (session == null ? request - .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session - .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)); - - return assertion == null ? null : assertion.getPrincipal(); + @Override + public void destroy() { + // nothing to do } @Override @@ -90,6 +85,16 @@ public void init(final FilterConfig filterConfig) throws ServletException { this.ignoreCase = getBoolean(ConfigurationKeys.IGNORE_CASE); } + private static AttributePrincipal retrievePrincipalFromSessionOrRequest(final ServletRequest servletRequest) { + final var request = (HttpServletRequest) servletRequest; + final var session = request.getSession(false); + final var assertion = (Assertion) (session == null ? request + .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) : session + .getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)); + + return assertion == null ? null : assertion.getPrincipal(); + } + final class CasHttpServletRequestWrapper extends HttpServletRequestWrapper { private final AttributePrincipal principal; @@ -99,11 +104,6 @@ final class CasHttpServletRequestWrapper extends HttpServletRequestWrapper { this.principal = principal; } - @Override - public Principal getUserPrincipal() { - return this.principal; - } - @Override public String getRemoteUser() { return principal != null ? this.principal.getName() : null; @@ -126,7 +126,7 @@ public boolean isUserInRole(final String role) { return false; } - final Object value = this.principal.getAttributes().get(roleAttribute); + final var value = this.principal.getAttributes().get(roleAttribute); if (value instanceof Collection) { for (final Object o : (Collection) value) { @@ -137,11 +137,16 @@ public boolean isUserInRole(final String role) { } } - final boolean isMember = rolesEqual(role, value); + final var isMember = rolesEqual(role, value); logger.debug("User [{}] is in role [{}]: {}", getRemoteUser(), role, isMember); return isMember; } + @Override + public Principal getUserPrincipal() { + return this.principal; + } + /** * Determines whether the given role is equal to the candidate * role attribute taking into account case sensitivity. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/IOUtils.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/IOUtils.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/IOUtils.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/IOUtils.java index b8ece5325..b06cdec27 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/IOUtils.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/IOUtils.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,9 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; -import java.io.*; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.nio.CharBuffer; import java.nio.charset.Charset; @@ -34,7 +38,7 @@ public final class IOUtils { public static final Charset UTF8 = Charset.forName("UTF-8"); - private IOUtils() { /** Utility class pattern. */ } + private IOUtils() { /** Utility class pattern. */} /** * Reads all data from the given stream as UTF-8 character data and closes it on completion or errors. @@ -62,8 +66,8 @@ public static String readString(final InputStream in) throws IOException { */ public static String readString(final InputStream in, final Charset charset) throws IOException { final Reader reader = new InputStreamReader(in, charset); - final StringBuilder builder = new StringBuilder(); - final CharBuffer buffer = CharBuffer.allocate(2048); + final var builder = new StringBuilder(); + final var buffer = CharBuffer.allocate(2048); try { while (reader.read(buffer) > -1) { buffer.flip(); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/MapNamespaceContext.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/MapNamespaceContext.java similarity index 87% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/MapNamespaceContext.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/MapNamespaceContext.java index 5ad48ab2b..c9ead449d 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/MapNamespaceContext.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/MapNamespaceContext.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; import javax.xml.namespace.NamespaceContext; import java.util.Collections; @@ -39,12 +39,12 @@ public class MapNamespaceContext implements NamespaceContext { * * @param namespaceDeclarations An array of namespace declarations of the form prefix->uri. */ - public MapNamespaceContext(final String ... namespaceDeclarations) { - namespaceMap = new HashMap(); + public MapNamespaceContext(final String... namespaceDeclarations) { + namespaceMap = new HashMap<>(); int index; String key; String value; - for (final String decl : namespaceDeclarations) { + for (final var decl : namespaceDeclarations) { index = decl.indexOf('-'); key = decl.substring(0, index); value = decl.substring(index + 2); @@ -68,7 +68,7 @@ public String getNamespaceURI(final String prefix) { @Override public String getPrefix(final String namespaceURI) { - for (final Map.Entry entry : namespaceMap.entrySet()) { + for (final var entry : namespaceMap.entrySet()) { if (entry.getValue().equalsIgnoreCase(namespaceURI)) { return entry.getKey(); } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/PrivateKeyUtils.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/PrivateKeyUtils.java similarity index 62% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/PrivateKeyUtils.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/PrivateKeyUtils.java index a28afea32..a349c4c5f 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/PrivateKeyUtils.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/PrivateKeyUtils.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMKeyPair; @@ -25,11 +25,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.InputStreamReader; import java.security.KeyFactory; -import java.security.KeyPair; import java.security.PrivateKey; import java.security.Security; +import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; /** @@ -47,7 +51,7 @@ public class PrivateKeyUtils { } public static PrivateKey createKey(final String path, final String algorithm) { - final PrivateKey key = readPemPrivateKey(path); + final var key = readPemPrivateKey(path); if (key == null) { return readDERPrivateKey(path, algorithm); } else { @@ -57,52 +61,31 @@ public static PrivateKey createKey(final String path, final String algorithm) { private static PrivateKey readPemPrivateKey(final String path) { LOGGER.debug("Attempting to read as PEM [{}]", path); - final File file = new File(path); - InputStreamReader isr = null; - BufferedReader br = null; - try { - isr = new FileReader(file); - br = new BufferedReader(isr); - final PEMParser pp = new PEMParser(br); - final PEMKeyPair pemKeyPair = (PEMKeyPair) pp.readObject(); - final KeyPair kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair); + final var file = new File(path); + try (final InputStreamReader isr = new FileReader(file); final var br = new BufferedReader(isr)) { + final var pp = new PEMParser(br); + final var pemKeyPair = (PEMKeyPair) pp.readObject(); + final var kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair); return kp.getPrivate(); } catch (final Exception e) { LOGGER.error("Unable to read key", e); return null; - } finally { - try { - if (br != null) { - br.close(); - } - if (isr != null) { - isr.close(); - } - } catch (final IOException e) {} } } private static PrivateKey readDERPrivateKey(final String path, final String algorithm) { LOGGER.debug("Attempting to read key as DER [{}]", path); - final File file = new File(path); - FileInputStream fis = null; - try { - fis = new FileInputStream(file); - final long byteLength = file.length(); - final byte[] bytes = new byte[(int) byteLength]; + final var file = new File(path); + try (final var fis = new FileInputStream(file)) { + final var byteLength = file.length(); + final var bytes = new byte[(int) byteLength]; fis.read(bytes, 0, (int) byteLength); - final PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(bytes); - final KeyFactory factory = KeyFactory.getInstance(algorithm); + final KeySpec privSpec = new PKCS8EncodedKeySpec(bytes); + final var factory = KeyFactory.getInstance(algorithm); return factory.generatePrivate(privSpec); } catch (final Exception e) { LOGGER.error("Unable to read key", e); return null; - } finally { - try { - if (fis != null) { - fis.close(); - } - } catch (final IOException e) {} } } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/ReflectUtils.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/ReflectUtils.java similarity index 92% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/ReflectUtils.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/ReflectUtils.java index 00f6c5f0d..43540d367 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/ReflectUtils.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/ReflectUtils.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; import java.beans.BeanInfo; import java.beans.IntrospectionException; @@ -62,7 +62,7 @@ public static Class loadClass(final String className) throws IllegalArgum * @return New instance of given class. */ public static T newInstance(final String className, final Object... args) { - return newInstance(ReflectUtils. loadClass(className), args); + return newInstance(ReflectUtils.loadClass(className), args); } /** @@ -74,7 +74,7 @@ public static T newInstance(final String className, final Object... args) { */ public static T newInstance(final Class clazz, final Object... args) { final Class[] argClasses = new Class[args.length]; - for (int i = 0; i < args.length; i++) { + for (var i = 0; i < args.length; i++) { argClasses[i] = args[i].getClass(); } try { @@ -108,8 +108,8 @@ public static PropertyDescriptor getPropertyDescriptor(final Class clazz, fin * name exists. */ public static PropertyDescriptor getPropertyDescriptor(final BeanInfo info, final String propertyName) { - for (int i = 0; i < info.getPropertyDescriptors().length; i++) { - final PropertyDescriptor pd = info.getPropertyDescriptors()[i]; + for (var i = 0; i < info.getPropertyDescriptors().length; i++) { + final var pd = info.getPropertyDescriptors()[i]; if (pd.getName().equals(propertyName)) { return pd; } @@ -139,9 +139,9 @@ public static void setProperty(final String propertyName, final Object value, fi * @param info BeanInfo describing the target JavaBean. */ public static void setProperty(final String propertyName, final Object value, final Object target, - final BeanInfo info) { + final BeanInfo info) { try { - final PropertyDescriptor pd = getPropertyDescriptor(info, propertyName); + final var pd = getPropertyDescriptor(info, propertyName); pd.getWriteMethod().invoke(target, value); } catch (final InvocationTargetException e) { throw new RuntimeException("Error setting property " + propertyName, e.getCause()); @@ -159,7 +159,7 @@ public static void setProperty(final String propertyName, final Object value, fi * @return Field value. */ public static Object getField(final String fieldName, final Object target) { - Class clazz = target.getClass(); + var clazz = target.getClass(); Field field = null; do { try { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/ThreadLocalXPathExpression.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/ThreadLocalXPathExpression.java similarity index 91% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/ThreadLocalXPathExpression.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/ThreadLocalXPathExpression.java index 4b2e29a1d..73a254709 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/ThreadLocalXPathExpression.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/ThreadLocalXPathExpression.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; -import javax.xml.xpath.*; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; /** * Thread local XPath expression. @@ -99,7 +102,7 @@ public NodeList evaluateAsNodeList(final Object o) throws XPathExpressionExcepti @Override protected XPathExpression initialValue() { try { - final XPath xPath = XPathFactory.newInstance().newXPath(); + final var xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(context); return xPath.compile(expression); } catch (final XPathExpressionException e) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/URIBuilder.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/URIBuilder.java similarity index 77% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/URIBuilder.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/URIBuilder.java index 86c1eb9c4..693524e88 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/URIBuilder.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/URIBuilder.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Serial; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -28,7 +29,7 @@ import java.net.URLDecoder; import java.nio.charset.Charset; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Collection; import java.util.List; import java.util.regex.Pattern; @@ -40,22 +41,37 @@ */ public final class URIBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(URIBuilder.class); + private static final Pattern IPV6_STD_PATTERN = Pattern.compile("^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}$"); private String scheme; + private String encodedSchemeSpecificPart; + private String encodedAuthority; + private String userInfo; + private String encodedUserInfo; + private String host; + private int port; + private String path; + private String encodedPath; + private String encodedQuery; + private List queryParams; + private String query; + private boolean encode; + private String fragment; + private String encodedFragment; /** @@ -107,40 +123,25 @@ public URIBuilder(final URI uri) { digestURI(uri); } - private List parseQuery(final String query) { - - try { - final Charset utf8 = Charset.forName("UTF-8"); - if (query != null && !query.isEmpty()) { - final List list = new ArrayList(); - final String[] parametersArray = query.split("&"); - - for (final String parameter : parametersArray) { - final int firstIndex = parameter.indexOf("="); - if (firstIndex != -1) { - final String paramName = parameter.substring(0, firstIndex); - final String decodedParamName = URLDecoder.decode(paramName, utf8.name()); - - final String paramVal = parameter.substring(firstIndex + 1); - final String decodedParamVal = URLDecoder.decode(paramVal, utf8.name()); + private static boolean isIPv6Address(final CharSequence input) { + return IPV6_STD_PATTERN.matcher(input).matches(); + } - list.add(new BasicNameValuePair(decodedParamName, decodedParamVal)); - } else { - // Either we do not have a query parameter, or it might be encoded; take it verbaitm - final String[] parameterCombo = parameter.split("="); - if (parameterCombo.length >= 1) { - final String key = URLDecoder.decode(parameterCombo[0], utf8.name()); - final String val = parameterCombo.length == 2 ? URLDecoder.decode(parameterCombo[1], utf8.name()) : ""; - list.add(new BasicNameValuePair(key, val)); - } - } - } - return list; + private static String normalizePath(final String path) { + var s = path; + if (s == null) { + return null; + } + var n = 0; + for (; n < s.length(); n++) { + if (s.charAt(n) != '/') { + break; } - } catch (final UnsupportedEncodingException e) { - LOGGER.error(e.getMessage(), e); } - return new ArrayList(); + if (n > 1) { + s = s.substring(n - 1); + } + return s; } /** @@ -154,57 +155,6 @@ public URI build() { } } - private static boolean isIPv6Address(final String input) { - return IPV6_STD_PATTERN.matcher(input).matches(); - } - - private String buildString() { - final StringBuilder sb = new StringBuilder(); - if (this.scheme != null) { - sb.append(this.scheme).append(':'); - } - if (this.encodedSchemeSpecificPart != null) { - sb.append(this.encodedSchemeSpecificPart); - } else { - if (this.encodedAuthority != null) { - sb.append("//").append(this.encodedAuthority); - } else if (this.host != null) { - sb.append("//"); - if (this.encodedUserInfo != null) { - sb.append(this.encodedUserInfo).append("@"); - } else if (this.userInfo != null) { - sb.append(encodeUserInfo(this.userInfo)).append("@"); - } - if (isIPv6Address(this.host)) { - sb.append("[").append(this.host).append("]"); - } else { - sb.append(this.host); - } - if (this.port >= 0) { - sb.append(":").append(this.port); - } - } - if (this.encodedPath != null) { - sb.append(normalizePath(this.encodedPath)); - } else if (this.path != null) { - sb.append(encodePath(normalizePath(this.path))); - } - if (this.encodedQuery != null) { - sb.append("?").append(this.encodedQuery); - } else if (this.queryParams != null && !this.queryParams.isEmpty()) { - sb.append("?").append(encodeUrlForm(this.queryParams)); - } else if (this.query != null) { - sb.append("?").append(encodeUric(this.query)); - } - } - if (this.encodedFragment != null) { - sb.append("#").append(this.encodedFragment); - } else if (this.fragment != null) { - sb.append("#").append(encodeUric(this.fragment)); - } - return sb.toString(); - } - public URIBuilder digestURI(final URI uri) { this.scheme = uri.getScheme(); this.encodedSchemeSpecificPart = uri.getRawSchemeSpecificPart(); @@ -222,61 +172,11 @@ public URIBuilder digestURI(final URI uri) { return this; } - private String encodeUserInfo(final String userInfo) { - return this.encode ? CommonUtils.urlEncode(userInfo) : userInfo; - } - - private String encodePath(final String path) { - return this.encode ? CommonUtils.urlEncode(path) : path; - } - - private String encodeUrlForm(final List params) { - final StringBuilder result = new StringBuilder(); - for (final BasicNameValuePair parameter : params) { - final String encodedName = this.encode ? CommonUtils.urlEncode(parameter.getName()) : parameter.getName(); - final String encodedValue = this.encode ? CommonUtils.urlEncode(parameter.getValue()) : parameter.getValue(); - - if (result.length() > 0) { - result.append("&"); - } - result.append(encodedName); - if (encodedValue != null) { - result.append("="); - result.append(encodedValue); - } - } - return result.toString(); - } - - private String encodeUric(final String fragment) { - return this.encode ? CommonUtils.urlEncode(fragment) : fragment; - } - public URIBuilder setEncode(final boolean encode) { this.encode = encode; return this; } - /** - * Sets URI scheme. - */ - public URIBuilder setScheme(final String scheme) { - this.scheme = scheme; - return this; - } - - /** - * Sets URI user info. The value is expected to be unescaped and may contain non ASCII - * characters. - */ - public URIBuilder setUserInfo(final String userInfo) { - this.userInfo = userInfo; - this.encodedSchemeSpecificPart = null; - this.encodedAuthority = null; - this.encodedUserInfo = null; - return this; - } - /** * Sets URI user info as a combination of username and password. These values are expected to * be unescaped and may contain non ASCII characters. @@ -285,42 +185,6 @@ public URIBuilder setUserInfo(final String username, final String password) { return setUserInfo(username + ':' + password); } - /** - * Sets URI host. - */ - public URIBuilder setHost(final String host) { - this.host = host; - this.encodedSchemeSpecificPart = null; - this.encodedAuthority = null; - return this; - } - - /** - * Sets URI port. - */ - public URIBuilder setPort(final int port) { - this.port = port < 0 ? -1 : port; - this.encodedSchemeSpecificPart = null; - this.encodedAuthority = null; - return this; - } - - /** - * Sets URI path. The value is expected to be unescaped and may contain non ASCII characters. - */ - public URIBuilder setPath(final String path) { - this.path = path; - this.encodedSchemeSpecificPart = null; - this.encodedPath = null; - return this; - } - - public URIBuilder setEncodedPath(final String path) { - this.encodedPath = path; - this.encodedSchemeSpecificPart = null; - return this; - } - /** * Removes URI query. */ @@ -340,8 +204,8 @@ public URIBuilder removeQuery() { * will remove custom query if present. *

*/ - public URIBuilder setParameters(final List nvps) { - this.queryParams = new ArrayList(); + public URIBuilder setParameters(final Collection nvps) { + this.queryParams = new ArrayList<>(); this.queryParams.addAll(nvps); this.encodedQuery = null; this.encodedSchemeSpecificPart = null; @@ -350,7 +214,7 @@ public URIBuilder setParameters(final List nvps) { } public URIBuilder setParameters(final String queryParameters) { - this.queryParams = new ArrayList(); + this.queryParams = new ArrayList<>(); this.queryParams.addAll(parseQuery(queryParameters)); this.encodedQuery = null; this.encodedSchemeSpecificPart = null; @@ -358,7 +222,6 @@ public URIBuilder setParameters(final String queryParameters) { return this; } - /** * Adds URI query parameters. The parameter name / values are expected to be unescaped * and may contain non ASCII characters. @@ -367,9 +230,9 @@ public URIBuilder setParameters(final String queryParameters) { * will remove custom query if present. *

*/ - public URIBuilder addParameters(final List nvps) { + public URIBuilder addParameters(final Collection nvps) { if (this.queryParams == null || this.queryParams.isEmpty()) { - this.queryParams = new ArrayList(); + this.queryParams = new ArrayList<>(); } this.queryParams.addAll(nvps); this.encodedQuery = null; @@ -388,11 +251,11 @@ public URIBuilder addParameters(final List nvps) { */ public URIBuilder setParameters(final BasicNameValuePair... nvps) { if (this.queryParams == null) { - this.queryParams = new ArrayList(); + this.queryParams = new ArrayList<>(); } else { this.queryParams.clear(); } - for (final BasicNameValuePair nvp : nvps) { + for (final var nvp : nvps) { this.queryParams.add(nvp); } this.encodedQuery = null; @@ -411,7 +274,7 @@ public URIBuilder setParameters(final BasicNameValuePair... nvps) { */ public URIBuilder addParameter(final String param, final String value) { if (this.queryParams == null) { - this.queryParams = new ArrayList(); + this.queryParams = new ArrayList<>(); } this.queryParams.add(new BasicNameValuePair(param, value)); this.encodedQuery = null; @@ -430,12 +293,12 @@ public URIBuilder addParameter(final String param, final String value) { */ public URIBuilder setParameter(final String param, final String value) { if (this.queryParams == null) { - this.queryParams = new ArrayList(); + this.queryParams = new ArrayList<>(); } if (!this.queryParams.isEmpty()) { - for (final Iterator it = this.queryParams.iterator(); it.hasNext(); ) { - final BasicNameValuePair nvp = it.next(); - if (nvp.getName().equals(param)) { + for (final var it = this.queryParams.iterator(); it.hasNext(); ) { + final var nvp = it.next(); + if (nvp.name().equals(param)) { it.remove(); } } @@ -473,16 +336,6 @@ public URIBuilder setCustomQuery(final String query) { return this; } - /** - * Sets URI fragment. The value is expected to be unescaped and may contain non ASCII - * characters. - */ - public URIBuilder setFragment(final String fragment) { - this.fragment = fragment; - this.encodedFragment = null; - return this; - } - public URIBuilder setEncodedFragment(final String fragment) { this.fragment = null; this.encodedFragment = fragment; @@ -507,31 +360,87 @@ public String getScheme() { return this.scheme; } + /** + * Sets URI scheme. + */ + public URIBuilder setScheme(final String scheme) { + this.scheme = scheme; + return this; + } + public String getUserInfo() { return this.userInfo; } + /** + * Sets URI user info. The value is expected to be unescaped and may contain non ASCII + * characters. + */ + public URIBuilder setUserInfo(final String userInfo) { + this.userInfo = userInfo; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + this.encodedUserInfo = null; + return this; + } + public String getHost() { return this.host; } + /** + * Sets URI host. + */ + public URIBuilder setHost(final String host) { + this.host = host; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + return this; + } + public int getPort() { return this.port; } + /** + * Sets URI port. + */ + public URIBuilder setPort(final int port) { + this.port = port < 0 ? -1 : port; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + return this; + } + public String getPath() { return this.path; } + /** + * Sets URI path. The value is expected to be unescaped and may contain non ASCII characters. + */ + public URIBuilder setPath(final String path) { + this.path = path; + this.encodedSchemeSpecificPart = null; + this.encodedPath = null; + return this; + } + public String getEncodedPath() { return this.encodedPath; } + public URIBuilder setEncodedPath(final String path) { + this.encodedPath = path; + this.encodedSchemeSpecificPart = null; + return this; + } + public List getQueryParams() { if (this.queryParams != null) { - return new ArrayList(this.queryParams); + return new ArrayList<>(this.queryParams); } - return new ArrayList(); + return new ArrayList<>(); } @@ -539,59 +448,19 @@ public String getFragment() { return this.fragment; } - @Override - public String toString() { - return buildString(); - } - - private static String normalizePath(final String path) { - String s = path; - if (s == null) { - return null; - } - int n = 0; - for (; n < s.length(); n++) { - if (s.charAt(n) != '/') { - break; - } - } - if (n > 1) { - s = s.substring(n - 1); - } - return s; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final URIBuilder that = (URIBuilder) o; - - if (port != that.port) return false; - if (encode != that.encode) return false; - if (scheme != null ? !scheme.equals(that.scheme) : that.scheme != null) return false; - if (encodedSchemeSpecificPart != null ? !encodedSchemeSpecificPart.equals(that.encodedSchemeSpecificPart) : that.encodedSchemeSpecificPart != null) - return false; - if (encodedAuthority != null ? !encodedAuthority.equals(that.encodedAuthority) : that.encodedAuthority != null) - return false; - if (userInfo != null ? !userInfo.equals(that.userInfo) : that.userInfo != null) return false; - if (encodedUserInfo != null ? !encodedUserInfo.equals(that.encodedUserInfo) : that.encodedUserInfo != null) - return false; - if (host != null ? !host.equals(that.host) : that.host != null) return false; - if (path != null ? !path.equals(that.path) : that.path != null) return false; - if (encodedPath != null ? !encodedPath.equals(that.encodedPath) : that.encodedPath != null) return false; - if (encodedQuery != null ? !encodedQuery.equals(that.encodedQuery) : that.encodedQuery != null) return false; - if (queryParams != null ? !queryParams.equals(that.queryParams) : that.queryParams != null) return false; - if (query != null ? !query.equals(that.query) : that.query != null) return false; - if (fragment != null ? !fragment.equals(that.fragment) : that.fragment != null) return false; - return !(encodedFragment != null ? !encodedFragment.equals(that.encodedFragment) : that.encodedFragment != null); - + /** + * Sets URI fragment. The value is expected to be unescaped and may contain non ASCII + * characters. + */ + public URIBuilder setFragment(final String fragment) { + this.fragment = fragment; + this.encodedFragment = null; + return this; } @Override public int hashCode() { - int result = scheme != null ? scheme.hashCode() : 0; + var result = scheme != null ? scheme.hashCode() : 0; result = 31 * result + (encodedSchemeSpecificPart != null ? encodedSchemeSpecificPart.hashCode() : 0); result = 31 * result + (encodedAuthority != null ? encodedAuthority.hashCode() : 0); result = 31 * result + (userInfo != null ? userInfo.hashCode() : 0); @@ -609,11 +478,71 @@ public int hashCode() { return result; } - public static class BasicNameValuePair implements Cloneable, Serializable { - private static final long serialVersionUID = -6437800749411518984L; + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } - private final String name; - private final String value; + final var that = (URIBuilder) o; + + if (port != that.port) { + return false; + } + if (encode != that.encode) { + return false; + } + if (scheme != null ? !scheme.equals(that.scheme) : that.scheme != null) { + return false; + } + if (encodedSchemeSpecificPart != null ? !encodedSchemeSpecificPart.equals(that.encodedSchemeSpecificPart) : that.encodedSchemeSpecificPart != null) { + return false; + } + if (encodedAuthority != null ? !encodedAuthority.equals(that.encodedAuthority) : that.encodedAuthority != null) { + return false; + } + if (userInfo != null ? !userInfo.equals(that.userInfo) : that.userInfo != null) { + return false; + } + if (encodedUserInfo != null ? !encodedUserInfo.equals(that.encodedUserInfo) : that.encodedUserInfo != null) { + return false; + } + if (host != null ? !host.equals(that.host) : that.host != null) { + return false; + } + if (path != null ? !path.equals(that.path) : that.path != null) { + return false; + } + if (encodedPath != null ? !encodedPath.equals(that.encodedPath) : that.encodedPath != null) { + return false; + } + if (encodedQuery != null ? !encodedQuery.equals(that.encodedQuery) : that.encodedQuery != null) { + return false; + } + if (queryParams != null ? !queryParams.equals(that.queryParams) : that.queryParams != null) { + return false; + } + if (query != null ? !query.equals(that.query) : that.query != null) { + return false; + } + if (fragment != null ? !fragment.equals(that.fragment) : that.fragment != null) { + return false; + } + return !(encodedFragment != null ? !encodedFragment.equals(that.encodedFragment) : that.encodedFragment != null); + + } + + @Override + public String toString() { + return buildString(); + } + + public record BasicNameValuePair(String name, String value) implements Cloneable, Serializable { + @Serial + private static final long serialVersionUID = -6437800749411518984L; /** * Default Constructor taking a name and a value. The value may be null. @@ -621,62 +550,159 @@ public static class BasicNameValuePair implements Cloneable, Serializable { * @param name The name. * @param value The value. */ - public BasicNameValuePair(final String name, final String value) { - super(); - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public String getValue() { - return this.value; + public BasicNameValuePair { } @Override - public String toString() { - // don't call complex default formatting for a simple toString + public boolean equals(final Object object) { + if (this == object) { + return true; + } + + if (object == null) { + return false; + } - if (this.value == null) { - return name; + if (object instanceof BasicNameValuePair) { + final var that = (BasicNameValuePair) object; + return this.name.equals(that.name) + && this.value.equals(that.value); + } + return false; } - final int len = this.name.length() + 1 + this.value.length(); - final StringBuilder buffer = new StringBuilder(len); - buffer.append(this.name); - buffer.append("="); - buffer.append(this.value); - return buffer.toString(); - } - @Override - public boolean equals(final Object object) { - if (this == object) { - return true; + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); } - if (object == null) { - return false; + @Override + public String toString() { + // don't call complex default formatting for a simple toString + + if (this.value == null) { + return name; + } + final var len = this.name.length() + 1 + this.value.length(); + final var buffer = new StringBuilder(len); + buffer.append(this.name); + buffer.append("="); + buffer.append(this.value); + return buffer.toString(); } - if (object instanceof BasicNameValuePair) { - final BasicNameValuePair that = (BasicNameValuePair) object; - return this.name.equals(that.name) - && this.value.equals(that.value); + } + + private static List parseQuery(final String query) { + + try { + final var utf8 = Charset.forName("UTF-8"); + if (query != null && !query.isEmpty()) { + final List list = new ArrayList<>(); + final var parametersArray = query.split("&"); + + for (final var parameter : parametersArray) { + final var firstIndex = parameter.indexOf("="); + if (firstIndex != -1) { + final var paramName = parameter.substring(0, firstIndex); + final var decodedParamName = URLDecoder.decode(paramName, utf8.name()); + + final var paramVal = parameter.substring(firstIndex + 1); + final var decodedParamVal = URLDecoder.decode(paramVal, utf8.name()); + + list.add(new BasicNameValuePair(decodedParamName, decodedParamVal)); + } else { + // Either we do not have a query parameter, or it might be encoded; take it verbaitm + final var parameterCombo = parameter.split("="); + if (parameterCombo.length >= 1) { + final var key = URLDecoder.decode(parameterCombo[0], utf8.name()); + final var val = parameterCombo.length == 2 ? URLDecoder.decode(parameterCombo[1], utf8.name()) : ""; + list.add(new BasicNameValuePair(key, val)); + } + } + } + return list; } - return false; + } catch (final UnsupportedEncodingException e) { + LOGGER.error(e.getMessage(), e); } + return new ArrayList<>(); + } - @Override - public int hashCode() { - return 133 * this.name.hashCode() * this.value.hashCode(); + private String buildString() { + final var sb = new StringBuilder(); + if (this.scheme != null) { + sb.append(this.scheme).append(':'); + } + if (this.encodedSchemeSpecificPart != null) { + sb.append(this.encodedSchemeSpecificPart); + } else { + if (this.encodedAuthority != null) { + sb.append("//").append(this.encodedAuthority); + } else if (this.host != null) { + sb.append("//"); + if (this.encodedUserInfo != null) { + sb.append(this.encodedUserInfo).append("@"); + } else if (this.userInfo != null) { + sb.append(encodeUserInfo(this.userInfo)).append("@"); + } + if (isIPv6Address(this.host)) { + sb.append("[").append(this.host).append("]"); + } else { + sb.append(this.host); + } + if (this.port >= 0) { + sb.append(":").append(this.port); + } + } + if (this.encodedPath != null) { + sb.append(normalizePath(this.encodedPath)); + } else if (this.path != null) { + sb.append(encodePath(normalizePath(this.path))); + } + if (this.encodedQuery != null) { + sb.append("?").append(this.encodedQuery); + } else if (this.queryParams != null && !this.queryParams.isEmpty()) { + sb.append("?").append(encodeUrlForm(this.queryParams)); + } else if (this.query != null) { + sb.append("?").append(encodeUric(this.query)); + } } + if (this.encodedFragment != null) { + sb.append("#").append(this.encodedFragment); + } else if (this.fragment != null) { + sb.append("#").append(encodeUric(this.fragment)); + } + return sb.toString(); + } - @Override - public Object clone() throws CloneNotSupportedException { - return super.clone(); + private String encodeUserInfo(final String userInfo) { + return this.encode ? CommonUtils.urlEncode(userInfo) : userInfo; + } + + private String encodePath(final String path) { + return this.encode ? CommonUtils.urlEncode(path) : path; + } + + private String encodeUrlForm(final Iterable params) { + final var result = new StringBuilder(); + for (final var parameter : params) { + final var encodedName = this.encode ? CommonUtils.urlEncode(parameter.name()) : parameter.name(); + final var encodedValue = this.encode ? CommonUtils.urlEncode(parameter.value()) : parameter.value(); + + if (result.length() > 0) { + result.append("&"); + } + result.append(encodedName); + if (encodedValue != null) { + result.append("="); + result.append(encodedValue); + } } + return result.toString(); + } + private String encodeUric(final String fragment) { + return this.encode ? CommonUtils.urlEncode(fragment) : fragment; } } diff --git a/cas-client-core/src/main/java/org/apereo/cas/client/util/WebUtils.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/WebUtils.java new file mode 100644 index 000000000..f1a37972c --- /dev/null +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/WebUtils.java @@ -0,0 +1,264 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client.util; + +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; + +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +/** + * Commons utilities related to the web (Jakarta) request/response. + * + * @author Jerome LELEU + * @since 4.0.3 + */ +public final class WebUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(WebUtils.class); + + /** + * Constant representing the ProxyGrantingTicket IOU Request Parameter. + */ + private static final String PARAM_PROXY_GRANTING_TICKET_IOU = "pgtIou"; + + /** + * Constant representing the ProxyGrantingTicket Request Parameter. + */ + private static final String PARAM_PROXY_GRANTING_TICKET = "pgtId"; + + private static final String SERVICE_PARAMETER_NAMES; + + static { + final Collection serviceParameterSet = new HashSet<>(4); + for (final var protocol : Protocol.values()) { + serviceParameterSet.add(protocol.getServiceParameterName()); + } + SERVICE_PARAMETER_NAMES = serviceParameterSet.toString() + .replaceAll("\\[|\\]", "") + .replaceAll("\\s", ""); + } + + private WebUtils() { + } + + public static void readAndRespondToProxyReceptorRequest(final ServletRequest request, + final ServletResponse response, final ProxyGrantingTicketStorage proxyGrantingTicketStorage) + throws IOException { + final var proxyGrantingTicketIou = request.getParameter(PARAM_PROXY_GRANTING_TICKET_IOU); + + final var proxyGrantingTicket = request.getParameter(PARAM_PROXY_GRANTING_TICKET); + + if (CommonUtils.isBlank(proxyGrantingTicket) || CommonUtils.isBlank(proxyGrantingTicketIou)) { + response.getWriter().write(""); + return; + } + + LOGGER.debug("Received proxyGrantingTicketId [{}] for proxyGrantingTicketIou [{}]", proxyGrantingTicket, + proxyGrantingTicketIou); + + proxyGrantingTicketStorage.save(proxyGrantingTicketIou, proxyGrantingTicket); + + LOGGER.debug("Successfully saved proxyGrantingTicketId [{}] for proxyGrantingTicketIou [{}]", + proxyGrantingTicket, proxyGrantingTicketIou); + + response.getWriter().write(""); + response.getWriter().write(""); + } + + private static String findMatchingServerName(final HttpServletRequest request, final String serverName) { + final var serverNames = serverName.split(" "); + + if (serverNames.length == 0 || serverNames.length == 1) { + return serverName; + } + + final var host = request.getHeader("Host"); + final var xHost = request.getHeader("X-Forwarded-Host"); + + final String comparisonHost; + comparisonHost = (xHost != null) ? xHost : host; + + if (comparisonHost == null) { + return serverName; + } + + for (final var server : serverNames) { + final var lowerCaseServer = server.toLowerCase(); + + if (lowerCaseServer.contains(comparisonHost)) { + return server; + } + } + + return serverNames[0]; + } + + private static boolean requestIsOnStandardPort(final ServletRequest request) { + final var serverPort = request.getServerPort(); + return serverPort == 80 || serverPort == 443; + } + + /** + * Constructs a service url from the HttpServletRequest or from the given + * serviceUrl. Prefers the serviceUrl provided if both a serviceUrl and a + * serviceName. Compiles a list of all service parameters for supported protocols + * and removes them all from the query string. + * + * @param request the HttpServletRequest + * @param response the HttpServletResponse + * @param service the configured service url (this will be used if not null) + * @param serverNames the server name to use to construct the service url if the service param is empty. Note, prior to CAS Client 3.3, this was a single value. + * As of 3.3, it can be a space-separated value. We keep it as a single value, but will convert it to an array internally to get the matching value. This keeps backward compatability with anything using this public + * method. + * @param artifactParameterName the artifact parameter name to remove (i.e. ticket) + * @param encode whether to encode the url or not (i.e. Jsession). + * @return the service url to use. + */ + @Deprecated + public static String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response, + final String service, final String serverNames, + final String artifactParameterName, final boolean encode) { + return constructServiceUrl(request, response, service, serverNames, SERVICE_PARAMETER_NAMES + , artifactParameterName, encode); + } + + /** + * Constructs a service url from the HttpServletRequest or from the given + * serviceUrl. Prefers the serviceUrl provided if both a serviceUrl and a + * serviceName. + * + * @param request the HttpServletRequest + * @param response the HttpServletResponse + * @param service the configured service url (this will be used if not null) + * @param serverNames the server name to use to construct the service url if the service param is empty. Note, prior to CAS Client 3.3, this was a single value. + * As of 3.3, it can be a space-separated value. We keep it as a single value, but will convert it to an array internally to get the matching value. This keeps backward compatability with anything using this public + * method. + * @param serviceParameterName the service parameter name to remove (i.e. service) + * @param artifactParameterName the artifact parameter name to remove (i.e. ticket) + * @param encode whether to encode the url or not (i.e. Jsession). + * @return the service url to use. + */ + public static String constructServiceUrl(final HttpServletRequest request, final HttpServletResponse response, + final String service, final String serverNames, final String serviceParameterName, + final String artifactParameterName, final boolean encode) { + if (CommonUtils.isNotBlank(service)) { + return encode ? response.encodeURL(service) : service; + } + + final var serverName = findMatchingServerName(request, serverNames); + final var originalRequestUrl = new URIBuilder(request.getRequestURL().toString(), encode); + originalRequestUrl.setParameters(request.getQueryString()); + + final URIBuilder builder; + if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) { + final var scheme = request.isSecure() ? "https://" : "http://"; + builder = new URIBuilder(scheme + serverName, encode); + } else { + builder = new URIBuilder(serverName, encode); + } + + if (builder.getPort() == -1 && !requestIsOnStandardPort(request)) { + builder.setPort(request.getServerPort()); + } + + builder.setEncodedPath(builder.getEncodedPath() + request.getRequestURI()); + + final var serviceParameterNames = Arrays.asList(serviceParameterName.split(",")); + if (!serviceParameterNames.isEmpty() && !originalRequestUrl.getQueryParams().isEmpty()) { + for (final var pair : originalRequestUrl.getQueryParams()) { + final var name = pair.name(); + if (!name.equals(artifactParameterName) && !serviceParameterNames.contains(name)) { + if (name.contains("&") || name.contains("=")) { + final var encodedParamBuilder = new URIBuilder(); + encodedParamBuilder.setParameters(name); + for (final var pair2 : encodedParamBuilder.getQueryParams()) { + final var name2 = pair2.name(); + if (!name2.equals(artifactParameterName) && !serviceParameterNames.contains(name2)) { + builder.addParameter(name2, pair2.value()); + } + } + } else { + builder.addParameter(name, pair.value()); + } + } + } + } + + final var result = builder.toString(); + final var returnValue = encode ? response.encodeURL(result) : result; + LOGGER.debug("serviceUrl generated: {}", returnValue); + return returnValue; + } + + /** + * Safe method for retrieving a parameter from the request without disrupting the reader UNLESS the parameter + * actually exists in the query string. + *

+ * Note, this does not work for POST Requests for "logoutRequest". It works for all other CAS POST requests because the + * parameter is ALWAYS in the GET request. + *

+ * If we see the "logoutRequest" parameter we MUST treat it as if calling the standard request.getParameter. + *

+ * Note, that as of 3.3.0, we've made it more generic. + *

+ * + * @param request the request to check. + * @param parameter the parameter to look for. + * @return the value of the parameter. + */ + public static String safeGetParameter(final HttpServletRequest request, final String parameter, + final Collection parameters) { + if ("POST".equals(request.getMethod()) && parameters.contains(parameter)) { + LOGGER.debug("safeGetParameter called on a POST HttpServletRequest for Restricted Parameters. Cannot complete check safely. Reverting to standard behavior for this Parameter"); + return request.getParameter(parameter); + } + return request.getQueryString() == null || !request.getQueryString().contains(parameter) ? null : request + .getParameter(parameter); + } + + public static String safeGetParameter(final HttpServletRequest request, final String parameter) { + return safeGetParameter(request, parameter, List.of("logoutRequest")); + } + + /** + * Sends the redirect message and captures the exceptions that we can't possibly do anything with. + * + * @param response the HttpServletResponse. CANNOT be NULL. + * @param url the url to redirect to. + */ + public static void sendRedirect(final HttpServletResponse response, final String url) { + try { + response.sendRedirect(url); + } catch (final IOException e) { + LOGGER.warn(e.getMessage(), e); + } + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/XmlUtils.java b/cas-client-core/src/main/java/org/apereo/cas/client/util/XmlUtils.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/XmlUtils.java rename to cas-client-core/src/main/java/org/apereo/cas/client/util/XmlUtils.java index 87bb99565..2f6a66f1a 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/util/XmlUtils.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/util/XmlUtils.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; - -import java.io.StringReader; -import java.util.*; +package org.apereo.cas.client.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,6 +31,11 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Common utilities for easily parsing XML without duplicating logic. @@ -46,7 +48,7 @@ public final class XmlUtils { /** * Static instance of Commons Logging. */ - private final static Logger LOGGER = LoggerFactory.getLogger(XmlUtils.class); + private static final Logger LOGGER = LoggerFactory.getLogger(XmlUtils.class); /** @@ -57,16 +59,16 @@ public final class XmlUtils { * @return DOM document. */ public static Document newDocument(final String xml) { - final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - final Map features = new HashMap(); + final var factory = DocumentBuilderFactory.newInstance(); + final Map features = new HashMap<>(); features.put(XMLConstants.FEATURE_SECURE_PROCESSING, true); features.put("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); features.put("http://apache.org/xml/features/disallow-doctype-decl", true); - for (final Map.Entry entry : features.entrySet()) { + for (final var entry : features.entrySet()) { try { factory.setFeature(entry.getKey(), entry.getValue()); } catch (final ParserConfigurationException e) { - LOGGER.warn("Failed setting XML feature {}: {}", entry.getKey(), e); + LOGGER.warn("Failed setting XML feature {}", entry.getKey(), e); } } factory.setExpandEntityReferences(false); @@ -85,7 +87,7 @@ public static Document newDocument(final String xml) { */ public static XMLReader getXmlReader() { try { - final SAXParserFactory factory = SAXParserFactory.newInstance(); + final var factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); @@ -109,10 +111,10 @@ public static XMLReader getXmlReader() { * @return the list of text from the elements. */ public static List getTextForElements(final String xmlAsString, final String element) { - final List elements = new ArrayList(2); - final XMLReader reader = getXmlReader(); + final List elements = new ArrayList<>(2); + final var reader = getXmlReader(); - final DefaultHandler handler = new DefaultHandler() { + final var handler = new DefaultHandler() { private boolean foundElement = false; @@ -127,7 +129,7 @@ public void startElement(final String uri, final String localName, final String } @Override - public void endElement(final String uri, final String localName, final String qName) throws SAXException { + public void endElement(final String uri, final String localName, final String qName) { if (localName.equals(element)) { this.foundElement = false; elements.add(this.buffer.toString()); @@ -136,7 +138,7 @@ public void endElement(final String uri, final String localName, final String qN } @Override - public void characters(final char[] ch, final int start, final int length) throws SAXException { + public void characters(final char[] ch, final int start, final int length) { if (this.foundElement) { this.buffer.append(ch, start, length); } @@ -165,10 +167,10 @@ public void characters(final char[] ch, final int start, final int length) throw * @return the text value of the element. */ public static String getTextForElement(final String xmlAsString, final String element) { - final XMLReader reader = getXmlReader(); - final StringBuilder builder = new StringBuilder(); + final var reader = getXmlReader(); + final var builder = new StringBuilder(); - final DefaultHandler handler = new DefaultHandler() { + final var handler = new DefaultHandler() { private boolean foundElement = false; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/package.html b/cas-client-core/src/main/java/org/apereo/cas/client/util/package.html similarity index 100% rename from cas-client-core/src/main/java/org/jasig/cas/client/util/package.html rename to cas-client-core/src/main/java/org/apereo/cas/client/util/package.html diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractCasProtocolUrlBasedTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractCasProtocolUrlBasedTicketValidator.java similarity index 90% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractCasProtocolUrlBasedTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractCasProtocolUrlBasedTicketValidator.java index 7a6fb1fbb..6a97d6c18 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractCasProtocolUrlBasedTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractCasProtocolUrlBasedTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.util.CommonUtils; import java.net.URL; -import org.jasig.cas.client.util.CommonUtils; /** * Abstract class that knows the protocol for validating a CAS ticket. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractTicketValidationFilter.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractTicketValidationFilter.java index 9c8161325..0313da82e 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractTicketValidationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,21 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.util.AbstractCasFilter; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.ReflectUtils; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import javax.net.ssl.HostnameVerifier; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; -import javax.net.ssl.HostnameVerifier; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; /** * The filter that handles all the work of validating ticket requests. @@ -75,6 +80,95 @@ protected AbstractTicketValidationFilter(final Protocol protocol) { super(protocol); } + @Override + public void init() { + super.init(); + CommonUtils.assertNotNull(this.ticketValidator, "ticketValidator cannot be null."); + } + + @Override + protected void initInternal(final FilterConfig filterConfig) throws ServletException { + setExceptionOnValidationFailure(getBoolean(ConfigurationKeys.EXCEPTION_ON_VALIDATION_FAILURE)); + setRedirectAfterValidation(getBoolean(ConfigurationKeys.REDIRECT_AFTER_VALIDATION)); + setUseSession(getBoolean(ConfigurationKeys.USE_SESSION)); + + if (!this.useSession && this.redirectAfterValidation) { + logger.warn("redirectAfterValidation parameter may not be true when useSession parameter is false. Resetting it to false in order to prevent infinite redirects."); + setRedirectAfterValidation(false); + } + + setTicketValidator(getTicketValidator(filterConfig)); + super.initInternal(filterConfig); + } + + @Override + public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, + final FilterChain filterChain) throws IOException, ServletException { + + if (!preFilter(servletRequest, servletResponse, filterChain)) { + return; + } + + final var request = (HttpServletRequest) servletRequest; + final var response = (HttpServletResponse) servletResponse; + final var ticket = retrieveTicketFromRequest(request); + + if (CommonUtils.isNotBlank(ticket)) { + logger.debug("Attempting to validate ticket: {}", ticket); + + try { + final var assertion = this.ticketValidator.validate(ticket, + constructServiceUrl(request, response)); + + logger.debug("Successfully authenticated user: {}", assertion.getPrincipal().getName()); + + request.setAttribute(CONST_CAS_ASSERTION, assertion); + + if (this.useSession) { + request.getSession().setAttribute(CONST_CAS_ASSERTION, assertion); + } + onSuccessfulValidation(request, response, assertion); + + if (this.redirectAfterValidation) { + logger.debug("Redirecting after successful ticket validation."); + response.sendRedirect(constructServiceUrl(request, response)); + return; + } + } catch (final TicketValidationException e) { + logger.debug(e.getMessage(), e); + + onFailedValidation(request, response); + + if (this.exceptionOnValidationFailure) { + throw new ServletException(e); + } + + response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); + + return; + } + } + + filterChain.doFilter(request, response); + + } + + public final void setTicketValidator(final TicketValidator ticketValidator) { + this.ticketValidator = ticketValidator; + } + + public final void setRedirectAfterValidation(final boolean redirectAfterValidation) { + this.redirectAfterValidation = redirectAfterValidation; + } + + public final void setExceptionOnValidationFailure(final boolean exceptionOnValidationFailure) { + this.exceptionOnValidationFailure = exceptionOnValidationFailure; + } + + public final void setUseSession(final boolean useSession) { + this.useSession = useSession; + } + /** * Template method to return the appropriate validator. * @@ -91,8 +185,8 @@ protected TicketValidator getTicketValidator(final FilterConfig filterConfig) { * @return Properties that can contains key/trust info for Client Side Certificates */ protected Properties getSSLConfig() { - final Properties properties = new Properties(); - final String fileName = getString(ConfigurationKeys.SSL_CONFIG_FILE); + final var properties = new Properties(); + final var fileName = getString(ConfigurationKeys.SSL_CONFIG_FILE); if (fileName != null) { FileInputStream fis = null; @@ -115,8 +209,8 @@ protected Properties getSSLConfig() { * @return Instance of specified host name verifier or null if none specified. */ protected HostnameVerifier getHostnameVerifier() { - final Class className = getClass(ConfigurationKeys.HOSTNAME_VERIFIER); - final String config = getString(ConfigurationKeys.HOSTNAME_VERIFIER_CONFIG); + final var className = getClass(ConfigurationKeys.HOSTNAME_VERIFIER); + final var config = getString(ConfigurationKeys.HOSTNAME_VERIFIER_CONFIG); if (className != null) { if (config != null) { return ReflectUtils.newInstance(className, config); @@ -127,27 +221,6 @@ protected HostnameVerifier getHostnameVerifier() { return null; } - @Override - protected void initInternal(final FilterConfig filterConfig) throws ServletException { - setExceptionOnValidationFailure(getBoolean(ConfigurationKeys.EXCEPTION_ON_VALIDATION_FAILURE)); - setRedirectAfterValidation(getBoolean(ConfigurationKeys.REDIRECT_AFTER_VALIDATION)); - setUseSession(getBoolean(ConfigurationKeys.USE_SESSION)); - - if (!this.useSession && this.redirectAfterValidation) { - logger.warn("redirectAfterValidation parameter may not be true when useSession parameter is false. Resetting it to false in order to prevent infinite redirects."); - setRedirectAfterValidation(false); - } - - setTicketValidator(getTicketValidator(filterConfig)); - super.initInternal(filterConfig); - } - - @Override - public void init() { - super.init(); - CommonUtils.assertNotNull(this.ticketValidator, "ticketValidator cannot be null."); - } - /** * Pre-process the request before the normal filter process starts. This could be useful for pre-empting code. * @@ -159,7 +232,7 @@ public void init() { * @throws ServletException if there is a servlet problem. */ protected boolean preFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, - final FilterChain filterChain) throws IOException, ServletException { + final FilterChain filterChain) throws IOException, ServletException { return true; } @@ -173,7 +246,7 @@ protected boolean preFilter(final ServletRequest servletRequest, final ServletRe * @param assertion the successful Assertion from the server. */ protected void onSuccessfulValidation(final HttpServletRequest request, final HttpServletResponse response, - final Assertion assertion) { + final Assertion assertion) { // nothing to do here. } @@ -187,72 +260,4 @@ protected void onSuccessfulValidation(final HttpServletRequest request, final Ht protected void onFailedValidation(final HttpServletRequest request, final HttpServletResponse response) { // nothing to do here. } - - @Override - public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, - final FilterChain filterChain) throws IOException, ServletException { - - if (!preFilter(servletRequest, servletResponse, filterChain)) { - return; - } - - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - final String ticket = retrieveTicketFromRequest(request); - - if (CommonUtils.isNotBlank(ticket)) { - logger.debug("Attempting to validate ticket: {}", ticket); - - try { - final Assertion assertion = this.ticketValidator.validate(ticket, - constructServiceUrl(request, response)); - - logger.debug("Successfully authenticated user: {}", assertion.getPrincipal().getName()); - - request.setAttribute(CONST_CAS_ASSERTION, assertion); - - if (this.useSession) { - request.getSession().setAttribute(CONST_CAS_ASSERTION, assertion); - } - onSuccessfulValidation(request, response, assertion); - - if (this.redirectAfterValidation) { - logger.debug("Redirecting after successful ticket validation."); - response.sendRedirect(constructServiceUrl(request, response)); - return; - } - } catch (final TicketValidationException e) { - logger.debug(e.getMessage(), e); - - onFailedValidation(request, response); - - if (this.exceptionOnValidationFailure) { - throw new ServletException(e); - } - - response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); - - return; - } - } - - filterChain.doFilter(request, response); - - } - - public final void setTicketValidator(final TicketValidator ticketValidator) { - this.ticketValidator = ticketValidator; - } - - public final void setRedirectAfterValidation(final boolean redirectAfterValidation) { - this.redirectAfterValidation = redirectAfterValidation; - } - - public final void setExceptionOnValidationFailure(final boolean exceptionOnValidationFailure) { - this.exceptionOnValidationFailure = exceptionOnValidationFailure; - } - - public final void setUseSession(final boolean useSession) { - this.useSession = useSession; - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractUrlBasedTicketValidator.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractUrlBasedTicketValidator.java index e67de2dfa..e515e62ea 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractUrlBasedTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AbstractUrlBasedTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.ssl.HttpURLConnectionFactory; +import org.apereo.cas.client.ssl.HttpsURLConnectionFactory; +import org.apereo.cas.client.util.CommonUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; @@ -24,11 +31,6 @@ import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; -import org.jasig.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.ssl.HttpsURLConnectionFactory; -import org.jasig.cas.client.util.CommonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Abstract validator implementation for tickets that must be validated against a server. @@ -40,12 +42,6 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator protected final Logger logger = LoggerFactory.getLogger(getClass()); - /** - * URLConnection factory instance to use when making validation requests to the CAS server. - * Defaults to {@link HttpsURLConnectionFactory} - */ - private HttpURLConnectionFactory urlConnectionFactory = new HttpsURLConnectionFactory(); - /** * Prefix for the CAS server. Should be everything up to the url endpoint, including the /. * @@ -53,6 +49,12 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator */ private final String casServerUrlPrefix; + /** + * URLConnection factory instance to use when making validation requests to the CAS server. + * Defaults to {@link HttpsURLConnectionFactory} + */ + private HttpURLConnectionFactory urlConnectionFactory = new HttpsURLConnectionFactory(); + /** * Whether the request include a renew or not. */ @@ -75,6 +77,27 @@ protected AbstractUrlBasedTicketValidator(final String casServerUrlPrefix) { this.casServerUrlPrefix = CommonUtils.addTrailingSlash(casServerUrlPrefix); } + @Override + public final Assertion validate(final String ticket, final String service) throws TicketValidationException { + final var validationUrl = constructValidationUrl(ticket, service); + logger.debug("Constructing validation url: {}", validationUrl); + + try { + logger.debug("Retrieving response from server."); + final var serverResponse = retrieveResponseFromServer(new URL(validationUrl), ticket); + + if (serverResponse == null) { + throw new TicketValidationException("The CAS server returned no response."); + } + + logger.debug("Server response: {}", serverResponse); + + return parseResponseFromServer(serverResponse); + } catch (final MalformedURLException e) { + throw new TicketValidationException(e); + } + } + /** * Template method for ticket validators that need to provide additional parameters to the validation url. * @@ -90,7 +113,6 @@ protected void populateUrlAttributeMap(final Map urlParameters) */ protected abstract String getUrlSuffix(); - /** * Constructs the URL to send the validation request to. * @@ -99,7 +121,7 @@ protected void populateUrlAttributeMap(final Map urlParameters) * @return the fully constructed URL. */ protected final String constructValidationUrl(final String ticket, final String serviceUrl) { - final Map urlParameters = new HashMap(); + final Map urlParameters = new HashMap<>(); logger.debug("Placing URL parameters in map."); urlParameters.put("ticket", ticket); @@ -117,24 +139,24 @@ protected final String constructValidationUrl(final String ticket, final String urlParameters.putAll(this.customParameters); } - final String suffix = getUrlSuffix(); - final StringBuilder buffer = new StringBuilder(urlParameters.size() * 10 + this.casServerUrlPrefix.length() - + suffix.length() + 1); + final var suffix = getUrlSuffix(); + final var buffer = new StringBuilder(urlParameters.size() * 10 + this.casServerUrlPrefix.length() + + suffix.length() + 1); - int i = 0; + var i = 0; buffer.append(this.casServerUrlPrefix); buffer.append(suffix); - for (final Map.Entry entry : urlParameters.entrySet()) { - final String key = entry.getKey(); - final String value = entry.getValue(); + for (final var entry : urlParameters.entrySet()) { + final var key = entry.getKey(); + final var value = entry.getValue(); if (value != null) { buffer.append(i++ == 0 ? "?" : "&"); buffer.append(key); buffer.append("="); - final String encodedValue = encodeUrl(value); + final var encodedValue = encodeUrl(value); buffer.append(encodedValue); } } @@ -147,9 +169,9 @@ protected final String constructValidationUrl(final String ticket, final String * Encodes a URL using the URLEncoder format. * * @param url the url to encode. - * @return the encoded url, or the original url if "UTF-8" character encoding could not be found. + * @return the encoded url, or the original url if "UTF-8" character encoding could not be found. */ - protected final String encodeUrl(final String url) { + protected static String encodeUrl(final String url) { if (url == null) { return null; } @@ -181,47 +203,22 @@ protected final String encodeUrl(final String url) { protected abstract String retrieveResponseFromServer(URL validationUrl, String ticket); - @Override - public final Assertion validate(final String ticket, final String service) throws TicketValidationException { - final String validationUrl = constructValidationUrl(ticket, service); - logger.debug("Constructing validation url: {}", validationUrl); - - try { - logger.debug("Retrieving response from server."); - final String serverResponse = retrieveResponseFromServer(new URL(validationUrl), ticket); - - if (serverResponse == null) { - throw new TicketValidationException("The CAS server returned no response."); - } - - logger.debug("Server response: {}", serverResponse); - - return parseResponseFromServer(serverResponse); - } catch (final MalformedURLException e) { - throw new TicketValidationException(e); - } - } - - public final void setRenew(final boolean renew) { - this.renew = renew; - } - - public final void setCustomParameters(final Map customParameters) { - this.customParameters = customParameters; + protected final String getEncoding() { + return this.encoding; } public final void setEncoding(final String encoding) { this.encoding = encoding; } - protected final String getEncoding() { - return this.encoding; - } - protected final boolean isRenew() { return this.renew; } + public final void setRenew(final boolean renew) { + this.renew = renew; + } + protected final String getCasServerUrlPrefix() { return this.casServerUrlPrefix; } @@ -230,6 +227,10 @@ protected final Map getCustomParameters() { return this.customParameters; } + public final void setCustomParameters(final Map customParameters) { + this.customParameters = customParameters; + } + protected HttpURLConnectionFactory getURLConnectionFactory() { return this.urlConnectionFactory; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Assertion.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Assertion.java similarity index 85% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Assertion.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Assertion.java index 7c7c9982c..5fb583cf9 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Assertion.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Assertion.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,12 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.authentication.AttributePrincipal; import java.io.Serializable; import java.util.Date; import java.util.Map; -import org.jasig.cas.client.authentication.AttributePrincipal; /** * Represents a response to a validation request. @@ -61,6 +62,13 @@ public interface Assertion extends Serializable { */ Map getAttributes(); + /** + * Metadata associated with this assertion, not strictly classified + * as an authentication or principal attribute. + * @return map + */ + Map getContext(); + /** * The principal for which this assertion is valid. * @@ -75,4 +83,6 @@ public interface Assertion extends Serializable { * @since 3.3.0 (though in 3.3.0, no one actually calls this) */ boolean isValid(); + + } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AssertionImpl.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AssertionImpl.java similarity index 73% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/AssertionImpl.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/AssertionImpl.java index 9d92e1c33..0fdc6fc77 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AssertionImpl.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/AssertionImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.util.CommonUtils; +import java.io.Serial; +import java.io.Serializable; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.Map; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.util.CommonUtils; /** * Concrete Implementation of the {@link Assertion}. @@ -31,11 +35,12 @@ * @author Scott Battaglia * @version $Revision$ $Date$ * @since 3.1 - * + * */ public final class AssertionImpl implements Assertion { /** Unique Id for serialization. */ + @Serial private static final long serialVersionUID = -7767943925833639221L; /** The date from which the assertion is valid. */ @@ -49,6 +54,8 @@ public final class AssertionImpl implements Assertion { /** Map of key/value pairs associated with this assertion. I.e. authentication type. */ private final Map attributes; + private final Map context; + /** The principal for which this assertion is valid for. */ private final AttributePrincipal principal; @@ -67,7 +74,7 @@ public AssertionImpl(final String name) { * @param principal the Principal to associate with the Assertion. */ public AssertionImpl(final AttributePrincipal principal) { - this(principal, Collections. emptyMap()); + this(principal, Collections.emptyMap()); } /** @@ -77,9 +84,19 @@ public AssertionImpl(final AttributePrincipal principal) { * @param attributes the key/value pairs for this attribute. */ public AssertionImpl(final AttributePrincipal principal, final Map attributes) { - this(principal, new Date(), null, new Date(), attributes); + this(principal, attributes, new HashMap<>()); } + public AssertionImpl(final AttributePrincipal principal, final Map attributes, + final Map context) { + this(principal, new Date(), null, new Date(), attributes, context); + } + + public AssertionImpl(final AttributePrincipal principal, final Date validFromDate, final Date validUntilDate, + final Date authenticationDate, final Map attributes) { + this(principal, validFromDate, validUntilDate, authenticationDate, attributes, new HashMap<>()); + } + /** * Creates a new Assertion with the supplied principal, Assertion attributes, and start and valid until dates. * @@ -89,23 +106,20 @@ public AssertionImpl(final AttributePrincipal principal, final Map attributes) { + final Date authenticationDate, final Map attributes, + final Map context) { this.principal = principal; this.validFromDate = validFromDate; this.validUntilDate = validUntilDate; this.attributes = attributes; this.authenticationDate = authenticationDate; + this.context = context; CommonUtils.assertNotNull(this.principal, "principal cannot be null."); CommonUtils.assertNotNull(this.validFromDate, "validFromDate cannot be null."); CommonUtils.assertNotNull(this.attributes, "attributes cannot be null."); } - @Override - public Date getAuthenticationDate() { - return this.authenticationDate; - } - @Override public Date getValidFromDate() { return this.validFromDate; @@ -116,6 +130,11 @@ public Date getValidUntilDate() { return this.validUntilDate; } + @Override + public Date getAuthenticationDate() { + return this.authenticationDate; + } + @Override public Map getAttributes() { return this.attributes; @@ -126,14 +145,19 @@ public AttributePrincipal getPrincipal() { return this.principal; } + @Override + public Map getContext() { + return Map.copyOf(this.context); + } + @Override public boolean isValid() { if (this.validFromDate == null) { return true; } - final Date now = new Date(); - return (this.validFromDate.before(now) || this.validFromDate.equals(now)) - && (this.validUntilDate == null || this.validUntilDate.after(now) || this.validUntilDate.equals(now)); + final var now = new Date(); + return (this.validFromDate.before(now) || this.validFromDate.equals(now)) + && (this.validUntilDate == null || this.validUntilDate.after(now) || this.validUntilDate.equals(now)); } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas10TicketValidationFilter.java similarity index 74% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas10TicketValidationFilter.java index 70e9fc069..759acf568 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas10TicketValidationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import javax.servlet.FilterConfig; +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.ssl.HttpURLConnectionFactory; +import org.apereo.cas.client.ssl.HttpsURLConnectionFactory; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.ssl.HttpsURLConnectionFactory; +import jakarta.servlet.FilterConfig; /** * Implementation of AbstractTicketValidatorFilter that creates a Cas10TicketValidator. @@ -42,12 +42,12 @@ public Cas10TicketValidationFilter() { @Override protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) { - final String casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX); - final Cas10TicketValidator validator = new Cas10TicketValidator(casServerUrlPrefix); + final var casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX); + final var validator = new Cas10TicketValidator(casServerUrlPrefix); validator.setRenew(getBoolean(ConfigurationKeys.RENEW)); final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(), - getSSLConfig()); + getSSLConfig()); validator.setURLConnectionFactory(factory); validator.setEncoding(getString(ConfigurationKeys.ENCODING)); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas10TicketValidator.java similarity index 88% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas10TicketValidator.java index 28331e902..1a19dd5a0 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas10TicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas10TicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; import java.io.BufferedReader; import java.io.IOException; @@ -47,9 +47,9 @@ protected Assertion parseResponseFromServer(final String response) throws Ticket } try { - final BufferedReader reader = new BufferedReader(new StringReader(response)); + final var reader = new BufferedReader(new StringReader(response)); reader.readLine(); - final String name = reader.readLine(); + final var name = reader.readLine(); return new AssertionImpl(name); } catch (final IOException e) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java similarity index 58% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java index e7f0c557b..5cf9a483d 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,32 +16,45 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.proxy.AbstractEncryptedProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.proxy.Cas20ProxyRetriever; +import org.apereo.cas.client.proxy.CleanUpTimerTask; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.ssl.HttpURLConnectionFactory; +import org.apereo.cas.client.ssl.HttpsURLConnectionFactory; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.WebUtils; +import org.apereo.cas.client.util.PrivateKeyUtils; +import org.apereo.cas.client.util.ReflectUtils; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.security.PrivateKey; -import java.util.*; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.proxy.*; -import org.jasig.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.ssl.HttpsURLConnectionFactory; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.PrivateKeyUtils; -import org.jasig.cas.client.util.ReflectUtils; - -import static org.jasig.cas.client.configuration.ConfigurationKeys.*; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; /** * Creates either a CAS20ProxyTicketValidator or a CAS20ServiceTicketValidator depending on whether any of the * proxy parameters are set. *

* This filter can also pass additional parameters to the ticket validator. Any init parameter not included in the - * reserved list {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter#RESERVED_INIT_PARAMS}. + * reserved list {@link Cas20ProxyReceivingTicketValidationFilter#RESERVED_INIT_PARAMS}. * * @author Scott Battaglia * @author Brad Cupit (brad [at] lsu {dot} edu) @@ -50,14 +63,26 @@ */ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketValidationFilter { - private static final String[] RESERVED_INIT_PARAMS = new String[]{ARTIFACT_PARAMETER_NAME.getName(), SERVER_NAME.getName(), SERVICE.getName(), RENEW.getName(), LOGOUT_PARAMETER_NAME.getName(), - ARTIFACT_PARAMETER_OVER_POST.getName(), EAGERLY_CREATE_SESSIONS.getName(), ENCODE_SERVICE_URL.getName(), SSL_CONFIG_FILE.getName(), ROLE_ATTRIBUTE.getName(), IGNORE_CASE.getName(), - CAS_SERVER_LOGIN_URL.getName(), GATEWAY.getName(), AUTHENTICATION_REDIRECT_STRATEGY_CLASS.getName(), GATEWAY_STORAGE_CLASS.getName(), CAS_SERVER_URL_PREFIX.getName(), ENCODING.getName(), - TOLERANCE.getName(), IGNORE_PATTERN.getName(), IGNORE_URL_PATTERN_TYPE.getName(), HOSTNAME_VERIFIER.getName(), HOSTNAME_VERIFIER_CONFIG.getName(), - EXCEPTION_ON_VALIDATION_FAILURE.getName(), REDIRECT_AFTER_VALIDATION.getName(), USE_SESSION.getName(), SECRET_KEY.getName(), CIPHER_ALGORITHM.getName(), PROXY_RECEPTOR_URL.getName(), - PROXY_GRANTING_TICKET_STORAGE_CLASS.getName(), MILLIS_BETWEEN_CLEAN_UPS.getName(), ACCEPT_ANY_PROXY.getName(), ALLOWED_PROXY_CHAINS.getName(), TICKET_VALIDATOR_CLASS.getName(), - PROXY_CALLBACK_URL.getName(), RELAY_STATE_PARAMETER_NAME.getName(), METHOD.getName(), PRIVATE_KEY_PATH.getName(), PRIVATE_KEY_ALGORITHM.getName() - }; + private static final String[] RESERVED_INIT_PARAMS = + new String[]{ConfigurationKeys.ARTIFACT_PARAMETER_NAME.getName(), ConfigurationKeys.SERVER_NAME.getName(), ConfigurationKeys.SERVICE.getName(), ConfigurationKeys.RENEW.getName(), + ConfigurationKeys.LOGOUT_PARAMETER_NAME.getName(), + ConfigurationKeys.ARTIFACT_PARAMETER_OVER_POST.getName(), ConfigurationKeys.EAGERLY_CREATE_SESSIONS.getName(), ConfigurationKeys.ENCODE_SERVICE_URL.getName(), + ConfigurationKeys.SSL_CONFIG_FILE.getName(), ConfigurationKeys.ROLE_ATTRIBUTE.getName(), ConfigurationKeys.IGNORE_CASE.getName(), + ConfigurationKeys.CAS_SERVER_LOGIN_URL.getName(), ConfigurationKeys.GATEWAY.getName(), ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS.getName(), + ConfigurationKeys.GATEWAY_STORAGE_CLASS.getName(), ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName(), ConfigurationKeys.ENCODING.getName(), + ConfigurationKeys.TOLERANCE.getName(), ConfigurationKeys.IGNORE_PATTERN.getName(), ConfigurationKeys.IGNORE_URL_PATTERN_TYPE.getName(), + ConfigurationKeys.HOSTNAME_VERIFIER.getName(), ConfigurationKeys.HOSTNAME_VERIFIER_CONFIG.getName(), + ConfigurationKeys.EXCEPTION_ON_VALIDATION_FAILURE.getName(), ConfigurationKeys.REDIRECT_AFTER_VALIDATION.getName(), ConfigurationKeys.USE_SESSION.getName(), + ConfigurationKeys.SECRET_KEY.getName(), ConfigurationKeys.CIPHER_ALGORITHM.getName(), ConfigurationKeys.PROXY_RECEPTOR_URL.getName(), + ConfigurationKeys.PROXY_GRANTING_TICKET_STORAGE_CLASS.getName(), ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS.getName(), ConfigurationKeys.ACCEPT_ANY_PROXY.getName(), + ConfigurationKeys.ALLOWED_PROXY_CHAINS.getName(), ConfigurationKeys.TICKET_VALIDATOR_CLASS.getName(), + ConfigurationKeys.PROXY_CALLBACK_URL.getName(), ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getName(), ConfigurationKeys.METHOD.getName(), + ConfigurationKeys.PRIVATE_KEY_PATH.getName(), ConfigurationKeys.PRIVATE_KEY_ALGORITHM.getName() + }; + + protected Class defaultServiceTicketValidatorClass; + + protected Class defaultProxyTicketValidatorClass; /** * The URL to send to the CAS server as the URL that will process proxying requests on the CAS client. @@ -70,10 +95,6 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal private int millisBetweenCleanUps; - protected Class defaultServiceTicketValidatorClass; - - protected Class defaultProxyTicketValidatorClass; - private PrivateKey privateKey; /** @@ -91,19 +112,41 @@ protected Cas20ProxyReceivingTicketValidationFilter(final Protocol protocol) { super(protocol); } + public static PrivateKey buildPrivateKey(final String keyPath, final String keyAlgorithm) { + if (keyPath != null) { + return PrivateKeyUtils.createKey(keyPath, keyAlgorithm); + } + return null; + } + + @Override + public void init() { + super.init(); + CommonUtils.assertNotNull(this.proxyGrantingTicketStorage, "proxyGrantingTicketStorage cannot be null."); + + if (this.timer == null) { + this.timer = new Timer(true); + } + + if (this.timerTask == null) { + this.timerTask = new CleanUpTimerTask(this.proxyGrantingTicketStorage); + } + this.timer.schedule(this.timerTask, this.millisBetweenCleanUps, this.millisBetweenCleanUps); + } + @Override protected void initInternal(final FilterConfig filterConfig) throws ServletException { setProxyReceptorUrl(getString(ConfigurationKeys.PROXY_RECEPTOR_URL)); - final Class proxyGrantingTicketStorageClass = getClass(ConfigurationKeys.PROXY_GRANTING_TICKET_STORAGE_CLASS); + final var proxyGrantingTicketStorageClass = getClass(ConfigurationKeys.PROXY_GRANTING_TICKET_STORAGE_CLASS); if (proxyGrantingTicketStorageClass != null) { this.proxyGrantingTicketStorage = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); if (this.proxyGrantingTicketStorage instanceof AbstractEncryptedProxyGrantingTicketStorageImpl) { - final AbstractEncryptedProxyGrantingTicketStorageImpl p = (AbstractEncryptedProxyGrantingTicketStorageImpl) this.proxyGrantingTicketStorage; - final String cipherAlgorithm = getString(ConfigurationKeys.CIPHER_ALGORITHM); - final String secretKey = getString(ConfigurationKeys.SECRET_KEY); + final var p = (AbstractEncryptedProxyGrantingTicketStorageImpl) this.proxyGrantingTicketStorage; + final var cipherAlgorithm = getString(ConfigurationKeys.CIPHER_ALGORITHM); + final var secretKey = getString(ConfigurationKeys.SECRET_KEY); p.setCipherAlgorithm(cipherAlgorithm); @@ -119,41 +162,10 @@ protected void initInternal(final FilterConfig filterConfig) throws ServletExcep this.millisBetweenCleanUps = getInt(ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS); - this.privateKey = buildPrivateKey(getString(PRIVATE_KEY_PATH), getString(PRIVATE_KEY_ALGORITHM)); + this.privateKey = buildPrivateKey(getString(ConfigurationKeys.PRIVATE_KEY_PATH), getString(ConfigurationKeys.PRIVATE_KEY_ALGORITHM)); super.initInternal(filterConfig); } - @Override - public void init() { - super.init(); - CommonUtils.assertNotNull(this.proxyGrantingTicketStorage, "proxyGrantingTicketStorage cannot be null."); - - if (this.timer == null) { - this.timer = new Timer(true); - } - - if (this.timerTask == null) { - this.timerTask = new CleanUpTimerTask(this.proxyGrantingTicketStorage); - } - this.timer.schedule(this.timerTask, this.millisBetweenCleanUps, this.millisBetweenCleanUps); - } - - private T createNewTicketValidator(final Class ticketValidatorClass, final String casServerUrlPrefix, - final Class clazz) { - if (ticketValidatorClass == null) { - return ReflectUtils.newInstance(clazz, casServerUrlPrefix); - } - - return (T) ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix); - } - - public static PrivateKey buildPrivateKey(final String keyPath, final String keyAlgorithm) { - if (keyPath != null) { - return PrivateKeyUtils.createKey(keyPath, keyAlgorithm); - } - return null; - } - /** * Constructs a Cas20ServiceTicketValidator or a Cas20ProxyTicketValidator based on supplied parameters. * @@ -162,38 +174,38 @@ public static PrivateKey buildPrivateKey(final String keyPath, final String keyA */ @Override protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) { - final boolean allowAnyProxy = getBoolean(ConfigurationKeys.ACCEPT_ANY_PROXY); - final String allowedProxyChains = getString(ConfigurationKeys.ALLOWED_PROXY_CHAINS); - final String casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX); - final Class ticketValidatorClass = getClass(ConfigurationKeys.TICKET_VALIDATOR_CLASS); + final var allowAnyProxy = getBoolean(ConfigurationKeys.ACCEPT_ANY_PROXY); + final var allowedProxyChains = getString(ConfigurationKeys.ALLOWED_PROXY_CHAINS); + final var casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX); + final var ticketValidatorClass = getClass(ConfigurationKeys.TICKET_VALIDATOR_CLASS); final Cas20ServiceTicketValidator validator; if (allowAnyProxy || CommonUtils.isNotBlank(allowedProxyChains)) { - final Cas20ProxyTicketValidator v = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix, - this.defaultProxyTicketValidatorClass); + final var v = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix, + this.defaultProxyTicketValidatorClass); v.setAcceptAnyProxy(allowAnyProxy); v.setAllowedProxyChains(CommonUtils.createProxyList(allowedProxyChains)); validator = v; } else { validator = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix, - this.defaultServiceTicketValidatorClass); + this.defaultServiceTicketValidatorClass); } validator.setProxyCallbackUrl(getString(ConfigurationKeys.PROXY_CALLBACK_URL)); validator.setProxyGrantingTicketStorage(this.proxyGrantingTicketStorage); final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(), - getSSLConfig()); + getSSLConfig()); validator.setURLConnectionFactory(factory); validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getString(ConfigurationKeys.ENCODING), factory)); validator.setRenew(getBoolean(ConfigurationKeys.RENEW)); validator.setEncoding(getString(ConfigurationKeys.ENCODING)); - final Map additionalParameters = new HashMap(); - final List params = Arrays.asList(RESERVED_INIT_PARAMS); + final Map additionalParameters = new HashMap<>(); + final var params = Arrays.asList(RESERVED_INIT_PARAMS); for (final Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) { - final String s = (String) e.nextElement(); + final var s = (String) e.nextElement(); if (!params.contains(s)) { additionalParameters.put(s, filterConfig.getInitParameter(s)); @@ -206,28 +218,22 @@ protected final TicketValidator getTicketValidator(final FilterConfig filterConf return validator; } - @Override - public void destroy() { - super.destroy(); - this.timer.cancel(); - } - /** * This processes the ProxyReceptor request before the ticket validation code executes. */ @Override protected final boolean preFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - final String requestUri = request.getRequestURI(); + final var request = (HttpServletRequest) servletRequest; + final var response = (HttpServletResponse) servletResponse; + final var requestUri = request.getRequestURI(); if (CommonUtils.isEmpty(this.proxyReceptorUrl) || !requestUri.endsWith(this.proxyReceptorUrl)) { return true; } try { - CommonUtils.readAndRespondToProxyReceptorRequest(request, response, this.proxyGrantingTicketStorage); + WebUtils.readAndRespondToProxyReceptorRequest(request, response, this.proxyGrantingTicketStorage); } catch (final RuntimeException e) { logger.error(e.getMessage(), e); throw e; @@ -236,6 +242,12 @@ protected final boolean preFilter(final ServletRequest servletRequest, final Ser return false; } + @Override + public void destroy() { + super.destroy(); + this.timer.cancel(); + } + public final void setProxyReceptorUrl(final String proxyReceptorUrl) { this.proxyReceptorUrl = proxyReceptorUrl; } @@ -255,4 +267,13 @@ public void setTimerTask(final TimerTask timerTask) { public void setMillisBetweenCleanUps(final int millisBetweenCleanUps) { this.millisBetweenCleanUps = millisBetweenCleanUps; } + + private static T createNewTicketValidator(final Class ticketValidatorClass, final String casServerUrlPrefix, + final Class clazz) { + if (ticketValidatorClass == null) { + return ReflectUtils.newInstance(clazz, casServerUrlPrefix); + } + + return (T) ReflectUtils.newInstance(ticketValidatorClass, casServerUrlPrefix); + } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ProxyTicketValidator.java similarity index 79% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ProxyTicketValidator.java index 2b6934d04..e989ad8a7 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ProxyTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.util.XmlUtils; import java.util.Arrays; import java.util.List; -import org.jasig.cas.client.util.XmlUtils; /** * Extension to the traditional Service Ticket validation that will validate service tickets and proxy tickets. @@ -46,6 +47,10 @@ protected final ProxyList getAllowedProxyChains() { return this.allowedProxyChains; } + public final void setAllowedProxyChains(final ProxyList allowedProxyChains) { + this.allowedProxyChains = allowedProxyChains; + } + @Override protected String getUrlSuffix() { return "proxyValidate"; @@ -53,13 +58,13 @@ protected String getUrlSuffix() { @Override protected void customParseResponse(final String response, final Assertion assertion) - throws TicketValidationException { - final List proxies = parseProxiesFromResponse(response); + throws TicketValidationException { + final var proxies = parseProxiesFromResponse(response); if (proxies == null) { throw new InvalidProxyChainTicketValidationException( - "Invalid proxy chain: No proxy could be retrieved from response. " - + "This indicates a problem with CAS validation. Review logs/configuration to find the root cause." + "Invalid proxy chain: No proxy could be retrieved from response. " + + "This indicates a problem with CAS validation. Review logs/configuration to find the root cause." ); } // this means there was nothing in the proxy chain, which is okay @@ -70,19 +75,19 @@ protected void customParseResponse(final String response, final Assertion assert if (this.acceptAnyProxy) { logger.debug("Client configuration accepts any proxy. " - + "It is generally dangerous to use a non-proxied CAS filter " - + "specially for protecting resources that require proxy access."); + + "It is generally dangerous to use a non-proxied CAS filter " + + "specially for protecting resources that require proxy access."); return; } - final String[] proxiedList = proxies.toArray(new String[proxies.size()]); + final var proxiedList = proxies.toArray(new String[proxies.size()]); if (this.allowedProxyChains.contains(proxiedList)) { return; } logger.warn("Proxies received from the CAS validation response are {}. " - + "However, none are allowed by allowed proxy chain of the client which is {}", - Arrays.toString(proxiedList), this.allowedProxyChains); + + "However, none are allowed by allowed proxy chain of the client which is {}", + Arrays.toString(proxiedList), this.allowedProxyChains); throw new InvalidProxyChainTicketValidationException("Invalid proxy chain: " + proxies.toString()); } @@ -91,18 +96,14 @@ protected List parseProxiesFromResponse(final String response) { return XmlUtils.getTextForElements(response, "proxy"); } - public final void setAcceptAnyProxy(final boolean acceptAnyProxy) { - this.acceptAnyProxy = acceptAnyProxy; - } - - public final void setAllowedProxyChains(final ProxyList allowedProxyChains) { - this.allowedProxyChains = allowedProxyChains; - } - protected final boolean isAcceptAnyProxy() { return this.acceptAnyProxy; } + public final void setAcceptAnyProxy(final boolean acceptAnyProxy) { + this.acceptAnyProxy = acceptAnyProxy; + } + protected final boolean isAllowEmptyProxyChain() { return this.allowEmptyProxyChain; } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ServiceTicketValidator.java similarity index 81% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ServiceTicketValidator.java index 92f821312..ce3caf978 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas20ServiceTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,30 +16,32 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import java.io.StringReader; -import java.security.PrivateKey; -import java.util.*; - -import javax.crypto.Cipher; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.proxy.Cas20ProxyRetriever; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyRetriever; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.XmlUtils; import org.apache.commons.codec.binary.Base64; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.proxy.Cas20ProxyRetriever; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyRetriever; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.XmlUtils; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; +import javax.crypto.Cipher; +import javax.xml.parsers.SAXParserFactory; +import java.io.StringReader; +import java.security.PrivateKey; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + /** * Implementation of the TicketValidator that will validate Service Tickets in compliance with the CAS 2. * @@ -49,6 +51,7 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTicketValidator { public static final String PGT_ATTRIBUTE = "proxyGrantingTicket"; + private static final String PGTIOU_PREFIX = "PGTIOU-"; /** The CAS 2.0 protocol proxy callback url. */ @@ -74,6 +77,14 @@ public Cas20ServiceTicketValidator(final String casServerUrlPrefix) { this.proxyRetriever = new Cas20ProxyRetriever(casServerUrlPrefix, getEncoding(), getURLConnectionFactory()); } + public PrivateKey getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(final PrivateKey privateKey) { + this.privateKey = privateKey; + } + /** * Adds the pgtUrl to the list of parameters to pass to the CAS server. * @@ -91,25 +102,25 @@ protected String getUrlSuffix() { @Override protected Assertion parseResponseFromServer(final String response) throws TicketValidationException { - final String error = parseAuthenticationFailureFromResponse(response); + final var error = parseAuthenticationFailureFromResponse(response); if (CommonUtils.isNotBlank(error)) { throw new TicketValidationException(error); } - final String principal = parsePrincipalFromResponse(response); - final String proxyGrantingTicket = retrieveProxyGrantingTicket(response); + final var principal = parsePrincipalFromResponse(response); + final var proxyGrantingTicket = retrieveProxyGrantingTicket(response); if (CommonUtils.isEmpty(principal)) { throw new TicketValidationException("No principal was found in the response from the CAS server."); } final Assertion assertion; - final Map attributes = extractCustomAttributes(response); + final var attributes = extractCustomAttributes(response); if (CommonUtils.isNotBlank(proxyGrantingTicket)) { attributes.remove(PGT_ATTRIBUTE); final AttributePrincipal attributePrincipal = new AttributePrincipalImpl(principal, attributes, - proxyGrantingTicket, this.proxyRetriever); + proxyGrantingTicket, this.proxyRetriever); assertion = new AssertionImpl(attributePrincipal); } else { assertion = new AssertionImpl(new AttributePrincipalImpl(principal, attributes)); @@ -121,8 +132,8 @@ protected Assertion parseResponseFromServer(final String response) throws Ticket } protected String retrieveProxyGrantingTicket(final String response) { - final List values = XmlUtils.getTextForElements(response, PGT_ATTRIBUTE); - for (final String value : values) { + final var values = XmlUtils.getTextForElements(response, PGT_ATTRIBUTE); + for (final var value : values) { if (value != null) { if (value.startsWith(PGTIOU_PREFIX)) { return retrieveProxyGrantingTicketFromStorage(value); @@ -144,11 +155,11 @@ protected String retrieveProxyGrantingTicketFromStorage(final String pgtIou) { protected String retrieveProxyGrantingTicketViaEncryption(final String encryptedPgt) { if (this.privateKey != null) { try { - final Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); - final byte[] cred64 = new Base64().decode(encryptedPgt); + final var cipher = Cipher.getInstance(privateKey.getAlgorithm()); + final var cred64 = new Base64().decode(encryptedPgt); cipher.init(Cipher.DECRYPT_MODE, privateKey); - final byte[] cipherData = cipher.doFinal(cred64); - final String pgt = new String(cipherData); + final var cipherData = cipher.doFinal(cred64); + final var pgt = new String(cipherData); logger.debug("Decrypted PGT: {}", pgt); return pgt; } catch (final Exception e) { @@ -158,11 +169,11 @@ protected String retrieveProxyGrantingTicketViaEncryption(final String encrypted return null; } - protected String parsePrincipalFromResponse(final String response) { + protected static String parsePrincipalFromResponse(final String response) { return XmlUtils.getTextForElement(response, "user"); } - protected String parseAuthenticationFailureFromResponse(final String response) { + protected static String parseAuthenticationFailureFromResponse(final String response) { return XmlUtils.getTextForElement(response, "authenticationFailure"); } @@ -185,13 +196,13 @@ protected String parseAuthenticationFailureFromResponse(final String response) { * @return the map of attributes. */ protected Map extractCustomAttributes(final String xml) { - final SAXParserFactory spf = SAXParserFactory.newInstance(); + final var spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(false); try { - final SAXParser saxParser = spf.newSAXParser(); - final XMLReader xmlReader = saxParser.getXMLReader(); - final CustomAttributeHandler handler = new CustomAttributeHandler(); + final var saxParser = spf.newSAXParser(); + final var xmlReader = saxParser.getXMLReader(); + final var handler = new CustomAttributeHandler(); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(xml))); return handler.getAttributes(); @@ -209,34 +220,34 @@ protected Map extractCustomAttributes(final String xml) { * @throws TicketValidationException if there is a problem constructing the Assertion. */ protected void customParseResponse(final String response, final Assertion assertion) - throws TicketValidationException { + throws TicketValidationException { // nothing to do } - public final void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - public final void setProxyGrantingTicketStorage(final ProxyGrantingTicketStorage proxyGrantingTicketStorage) { - this.proxyGrantingTicketStorage = proxyGrantingTicketStorage; - } - - public final void setProxyRetriever(final ProxyRetriever proxyRetriever) { - this.proxyRetriever = proxyRetriever; - } - protected final String getProxyCallbackUrl() { return this.proxyCallbackUrl; } + public final void setProxyCallbackUrl(final String proxyCallbackUrl) { + this.proxyCallbackUrl = proxyCallbackUrl; + } + protected final ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { return this.proxyGrantingTicketStorage; } + public final void setProxyGrantingTicketStorage(final ProxyGrantingTicketStorage proxyGrantingTicketStorage) { + this.proxyGrantingTicketStorage = proxyGrantingTicketStorage; + } + protected final ProxyRetriever getProxyRetriever() { return this.proxyRetriever; } + public final void setProxyRetriever(final ProxyRetriever proxyRetriever) { + this.proxyRetriever = proxyRetriever; + } + private class CustomAttributeHandler extends DefaultHandler { private Map attributes; @@ -249,12 +260,12 @@ private class CustomAttributeHandler extends DefaultHandler { @Override public void startDocument() throws SAXException { - this.attributes = new HashMap(); + this.attributes = new HashMap<>(); } @Override public void startElement(final String namespaceURI, final String localName, final String qName, - final Attributes attributes) throws SAXException { + final Attributes attributes) throws SAXException { if ("attributes".equals(localName)) { this.foundAttributes = true; } else if (this.foundAttributes) { @@ -263,21 +274,14 @@ public void startElement(final String namespaceURI, final String localName, fina } } - @Override - public void characters(final char[] chars, final int start, final int length) throws SAXException { - if (this.currentAttribute != null) { - value.append(chars, start, length); - } - } - @Override public void endElement(final String namespaceURI, final String localName, final String qName) - throws SAXException { + throws SAXException { if ("attributes".equals(localName)) { this.foundAttributes = false; this.currentAttribute = null; } else if (this.foundAttributes) { - final Object o = this.attributes.get(this.currentAttribute); + final var o = this.attributes.get(this.currentAttribute); if (o == null) { this.attributes.put(this.currentAttribute, this.value.toString()); @@ -286,7 +290,7 @@ public void endElement(final String namespaceURI, final String localName, final if (o instanceof List) { items = (List) o; } else { - items = new LinkedList(); + items = new LinkedList<>(); items.add(o); this.attributes.put(this.currentAttribute, items); } @@ -295,16 +299,15 @@ public void endElement(final String namespaceURI, final String localName, final } } + @Override + public void characters(final char[] chars, final int start, final int length) throws SAXException { + if (this.currentAttribute != null) { + value.append(chars, start, length); + } + } + public Map getAttributes() { return this.attributes; } } - - public PrivateKey getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(final PrivateKey privateKey) { - this.privateKey = privateKey; - } } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ProxyReceivingTicketValidationFilter.java similarity index 81% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ProxyReceivingTicketValidationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ProxyReceivingTicketValidationFilter.java index ee6cb0d18..fc888b5de 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ProxyReceivingTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ProxyReceivingTicketValidationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,16 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import org.jasig.cas.client.Protocol; +import org.apereo.cas.client.Protocol; /** * Creates either a Cas30ProxyTicketValidator or a Cas30ServiceTicketValidator depending on whether any of the * proxy parameters are set. *

- * This filter can also pass additional parameters to the ticket validator. Any init parameter not included in the - * reserved list {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter#RESERVED_INIT_PARAMS}. + * This filter can also pass additional parameters to the ticket validator. * * @author Jerome Leleu * @since 3.4.0 diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ProxyTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ProxyTicketValidator.java similarity index 91% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ProxyTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ProxyTicketValidator.java index b95afdf6e..996a5257f 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ProxyTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ProxyTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; /** * Service and proxy tickets validation service for the CAS protocol v3. @@ -29,7 +29,7 @@ public class Cas30ProxyTicketValidator extends Cas20ProxyTicketValidator { public Cas30ProxyTicketValidator(final String casServerUrlPrefix) { super(casServerUrlPrefix); } - + @Override protected String getUrlSuffix() { return "p3/proxyValidate"; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ServiceTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ServiceTicketValidator.java similarity index 69% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ServiceTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ServiceTicketValidator.java index 0981c1820..eb18284dc 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas30ServiceTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/Cas30ServiceTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import org.jasig.cas.client.util.XmlUtils; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; +import org.apereo.cas.client.util.XmlUtils; +import java.util.Deque; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -55,27 +52,27 @@ protected String getUrlSuffix() { */ @Override protected Map extractCustomAttributes(final String xml) { - final Document document = XmlUtils.newDocument(xml); + final var document = XmlUtils.newDocument(xml); // Check if attributes are inlined. If not return default super method results - final NodeList attributeList = document.getElementsByTagName("cas:attribute"); + final var attributeList = document.getElementsByTagName("cas:attribute"); if (attributeList.getLength() == 0) { return super.extractCustomAttributes(xml); } - final HashMap attributes = new HashMap(); + final Map attributes = new HashMap<>(); - for (int i = 0; i < attributeList.getLength(); i++) { - final Node casAttributeNode = attributeList.item(i); - final NamedNodeMap nodeAttributes = casAttributeNode.getAttributes(); - final String name = nodeAttributes.getNamedItem("name").getNodeValue(); - final String value = nodeAttributes.getNamedItem("value").getTextContent(); - final Object mapValue = attributes.get(name); + for (var i = 0; i < attributeList.getLength(); i++) { + final var casAttributeNode = attributeList.item(i); + final var nodeAttributes = casAttributeNode.getAttributes(); + final var name = nodeAttributes.getNamedItem("name").getNodeValue(); + final var value = nodeAttributes.getNamedItem("value").getTextContent(); + final var mapValue = attributes.get(name); if (mapValue != null) { if (mapValue instanceof List) { ((List) mapValue).add(value); } else { - final LinkedList list = new LinkedList(); + final Deque list = new LinkedList<>(); list.add(mapValue); list.add(value); attributes.put(name, list); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/InvalidProxyChainTicketValidationException.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/InvalidProxyChainTicketValidationException.java similarity index 93% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/InvalidProxyChainTicketValidationException.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/InvalidProxyChainTicketValidationException.java index c291d35f4..452d047cf 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/InvalidProxyChainTicketValidationException.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/InvalidProxyChainTicketValidationException.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import java.io.Serial; /** * Exception denotes that an invalid proxy chain was sent from the CAS server to the local application. @@ -30,6 +32,7 @@ public final class InvalidProxyChainTicketValidationException extends TicketVali /** * Unique Id for Serialization */ + @Serial private static final long serialVersionUID = -7736653266370691534L; /** diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/ProxyList.java similarity index 76% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/ProxyList.java index 5d0cdd984..3f77349fb 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/ProxyList.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,17 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.authentication.ExactUrlPatternMatcherStrategy; +import org.apereo.cas.client.authentication.RegexUrlPatternMatcherStrategy; +import org.apereo.cas.client.authentication.UrlPatternMatcherStrategy; +import org.apereo.cas.client.util.CommonUtils; -import java.util.ArrayList; -import java.util.List; -import org.jasig.cas.client.authentication.ExactUrlPatternMatcherStrategy; -import org.jasig.cas.client.authentication.RegexUrlPatternMatcherStrategy; -import org.jasig.cas.client.authentication.UrlPatternMatcherStrategy; -import org.jasig.cas.client.util.CommonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.List; + /** * Holding class for the proxy list to make Spring configuration easier. * @@ -37,18 +39,18 @@ public final class ProxyList { private final Logger logger = LoggerFactory.getLogger(getClass()); - + private final List> proxyChains; - public ProxyList(final List proxyChains) { + public ProxyList(final Iterable proxyChains) { CommonUtils.assertNotNull(proxyChains, "List of proxy chains cannot be null."); - this.proxyChains = new ArrayList>(); + this.proxyChains = new ArrayList<>(); - for (final String[] list : proxyChains) { - final List chain = new ArrayList(); + for (final var list : proxyChains) { + final List chain = new ArrayList<>(); - for (final String item : list) { + for (final var item : list) { if (item.startsWith("^")) { chain.add(new RegexUrlPatternMatcherStrategy(item)); } else { @@ -61,18 +63,18 @@ public ProxyList(final List proxyChains) { } public ProxyList() { - this(new ArrayList()); + this(new ArrayList<>()); } public boolean contains(final String[] proxiedList) { StringBuilder loggingOutput; - for (final List proxyChain : this.proxyChains) { + for (final var proxyChain : this.proxyChains) { loggingOutput = new StringBuilder(); if (proxyChain.size() == proxiedList.length) { - for (int linkIndex = 0; linkIndex < proxyChain.size(); linkIndex++) { - final String linkToTest = proxiedList[linkIndex]; + for (var linkIndex = 0; linkIndex < proxyChain.size(); linkIndex++) { + final var linkToTest = proxiedList[linkIndex]; loggingOutput.append(linkToTest); if (proxyChain.get(linkIndex).matches(linkToTest)) { diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyListEditor.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/ProxyListEditor.java similarity index 85% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyListEditor.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/ProxyListEditor.java index a372bc8da..95510e72b 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyListEditor.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/ProxyListEditor.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.util.CommonUtils; import java.beans.PropertyEditorSupport; import java.io.BufferedReader; @@ -24,22 +26,21 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.List; -import org.jasig.cas.client.util.CommonUtils; /** * Convert a String-formatted list of acceptable proxies to an array. - * + * * @author Scott Battaglia * @version $Revision$ $Date$ * @since 3.1 - * + * */ public final class ProxyListEditor extends PropertyEditorSupport { @Override public void setAsText(final String text) throws IllegalArgumentException { - final BufferedReader reader = new BufferedReader(new StringReader(text)); - final List proxyChains = new ArrayList(); + final var reader = new BufferedReader(new StringReader(text)); + final List proxyChains = new ArrayList<>(); try { String line; diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/TicketValidationException.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/TicketValidationException.java similarity index 93% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/TicketValidationException.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/TicketValidationException.java index 467b3d5bd..ad7dc7dec 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/TicketValidationException.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/TicketValidationException.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import java.io.Serial; /** * Generic exception to be thrown when ticket validation fails. @@ -30,6 +32,7 @@ public class TicketValidationException extends Exception { /** * Unique Id for Serialization */ + @Serial private static final long serialVersionUID = -7036248720402711806L; /** diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/TicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/TicketValidator.java similarity index 92% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/TicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/TicketValidator.java index ee6a905da..273e1dd87 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/TicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/TicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; /** * Contract for a validator that will confirm the validity of a supplied ticket. @@ -27,6 +27,7 @@ * @version $Revision$ $Date$ * @since 3.1 */ +@FunctionalInterface public interface TicketValidator { /** diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonProxyReceivingTicketValidationFilter.java similarity index 86% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonProxyReceivingTicketValidationFilter.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonProxyReceivingTicketValidationFilter.java index 83f1e7033..e2b5ee869 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonProxyReceivingTicketValidationFilter.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonProxyReceivingTicketValidationFilter.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation.json; +package org.apereo.cas.client.validation.json; -import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter; +import org.apereo.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter; /** * Creates either a Cas30JsonServiceTicketValidator to validate tickets. diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonProxyTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonProxyTicketValidator.java similarity index 77% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonProxyTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonProxyTicketValidator.java index 10e8a7e76..2ce8718fc 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonProxyTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonProxyTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation.json; +package org.apereo.cas.client.validation.json; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.Cas30ProxyTicketValidator; -import org.jasig.cas.client.validation.TicketValidationException; +import org.apereo.cas.client.validation.Assertion; +import org.apereo.cas.client.validation.Cas30ProxyTicketValidator; +import org.apereo.cas.client.validation.TicketValidationException; import java.util.Collections; import java.util.List; @@ -40,7 +40,7 @@ public Cas30JsonProxyTicketValidator(final String casServerUrlPrefix) { @Override protected Assertion parseResponseFromServer(final String response) throws TicketValidationException { try { - final TicketValidationJsonResponse json = new JsonValidationResponseParser().parse(response); + final var json = new JsonValidationResponseParser().parse(response); return json.getAssertion(getProxyGrantingTicketStorage(), getProxyRetriever()); } catch (final Exception e) { logger.warn("Unable parse the JSON response"); @@ -51,8 +51,8 @@ protected Assertion parseResponseFromServer(final String response) throws Ticket @Override protected List parseProxiesFromResponse(final String response) { try { - final TicketValidationJsonResponse json = new JsonValidationResponseParser().parse(response); - return json.getServiceResponse().getAuthenticationSuccess().getProxies(); + final var json = new JsonValidationResponseParser().parse(response); + return json.serviceResponse().authenticationSuccess().getProxies(); } catch (final Exception e) { logger.warn("Unable to locate proxies from the JSON response", e); return super.parseProxiesFromResponse(response); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonServiceTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonServiceTicketValidator.java similarity index 85% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonServiceTicketValidator.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonServiceTicketValidator.java index 822dfd3e8..5034f2806 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/Cas30JsonServiceTicketValidator.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/Cas30JsonServiceTicketValidator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,12 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation.json; +package org.apereo.cas.client.validation.json; + +import org.apereo.cas.client.validation.Assertion; +import org.apereo.cas.client.validation.Cas30ServiceTicketValidator; +import org.apereo.cas.client.validation.TicketValidationException; import com.fasterxml.jackson.core.JsonProcessingException; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.Cas30ServiceTicketValidator; -import org.jasig.cas.client.validation.TicketValidationException; import java.io.IOException; import java.util.Collections; @@ -45,7 +46,7 @@ public Cas30JsonServiceTicketValidator(final String casServerUrlPrefix) { @Override protected Assertion parseResponseFromServer(final String response) throws TicketValidationException { try { - final TicketValidationJsonResponse json = new JsonValidationResponseParser().parse(response); + final var json = new JsonValidationResponseParser().parse(response); return json.getAssertion(getProxyGrantingTicketStorage(), getProxyRetriever()); } catch (final JsonProcessingException e) { logger.warn("Unable parse the JSON response. Falling back to XML", e); diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/JsonValidationResponseParser.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/JsonValidationResponseParser.java similarity index 62% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/json/JsonValidationResponseParser.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/json/JsonValidationResponseParser.java index 53797c235..210205843 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/JsonValidationResponseParser.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/JsonValidationResponseParser.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation.json; +package org.apereo.cas.client.validation.json; + +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.validation.TicketValidationException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.TicketValidationException; import java.io.IOException; @@ -42,22 +43,22 @@ public TicketValidationJsonResponse parse(final String response) throws TicketVa throw new TicketValidationException("Invalid JSON response; The response is empty"); } - final TicketValidationJsonResponse json = this.objectMapper.readValue(response, TicketValidationJsonResponse.class); + final var json = this.objectMapper.readValue(response, TicketValidationJsonResponse.class); - final TicketValidationJsonResponse.CasServiceResponseAuthentication serviceResponse = json.getServiceResponse(); - if (serviceResponse.getAuthenticationFailure() != null - && serviceResponse.getAuthenticationSuccess() != null) { + final var serviceResponse = json.serviceResponse(); + if (serviceResponse.authenticationFailure() != null + && serviceResponse.authenticationSuccess() != null) { throw new TicketValidationException("Invalid JSON response; It indicates both a success " - + "and a failure event, which is indicative of a server error. The actual response is " + response); + + "and a failure event, which is indicative of a server error. The actual response is " + response); } - if (serviceResponse.getAuthenticationFailure() != null) { - final String error = json.getServiceResponse().getAuthenticationFailure().getCode() - + " - " + serviceResponse.getAuthenticationFailure().getDescription(); + if (serviceResponse.authenticationFailure() != null) { + final var error = json.serviceResponse().authenticationFailure().getCode() + + " - " + serviceResponse.authenticationFailure().getDescription(); throw new TicketValidationException(error); } - final String principal = json.getServiceResponse().getAuthenticationSuccess().getUser(); + final var principal = json.serviceResponse().authenticationSuccess().getUser(); if (CommonUtils.isEmpty(principal)) { throw new TicketValidationException("No principal was found in the response from the CAS server."); } diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/TicketValidationJsonResponse.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/TicketValidationJsonResponse.java similarity index 62% rename from cas-client-core/src/main/java/org/jasig/cas/client/validation/json/TicketValidationJsonResponse.java rename to cas-client-core/src/main/java/org/apereo/cas/client/validation/json/TicketValidationJsonResponse.java index d9fc6af5d..3b28c2139 100644 --- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/json/TicketValidationJsonResponse.java +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/json/TicketValidationJsonResponse.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,17 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation.json; +package org.apereo.cas.client.validation.json; + +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyRetriever; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.validation.Assertion; +import org.apereo.cas.client.validation.AssertionImpl; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyRetriever; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.AssertionImpl; import java.util.List; import java.util.Map; @@ -36,68 +37,34 @@ * * @author Misagh Moayyed */ -final class TicketValidationJsonResponse { - private final CasServiceResponseAuthentication serviceResponse; - +record TicketValidationJsonResponse(TicketValidationJsonResponse.CasServiceResponseAuthentication serviceResponse) { @JsonCreator - public TicketValidationJsonResponse(@JsonProperty("serviceResponse") - final CasServiceResponseAuthentication serviceResponse) { + TicketValidationJsonResponse( + @JsonProperty("serviceResponse") + final CasServiceResponseAuthentication serviceResponse) { this.serviceResponse = serviceResponse; } - public CasServiceResponseAuthentication getServiceResponse() { - return serviceResponse; - } - - Assertion getAssertion(final ProxyGrantingTicketStorage proxyGrantingTicketStorage, - final ProxyRetriever proxyRetriever) { - final String proxyGrantingTicketIou = getServiceResponse().getAuthenticationSuccess().getProxyGrantingTicket(); - final String proxyGrantingTicket; - if (CommonUtils.isBlank(proxyGrantingTicketIou) || proxyGrantingTicketStorage == null) { - proxyGrantingTicket = null; - } else { - proxyGrantingTicket = proxyGrantingTicketStorage.retrieve(proxyGrantingTicketIou); - } - - final Assertion assertion; - final Map attributes = getServiceResponse().getAuthenticationSuccess().getAttributes(); - final String principal = getServiceResponse().getAuthenticationSuccess().getUser(); - if (CommonUtils.isNotBlank(proxyGrantingTicket)) { - final AttributePrincipal attributePrincipal = new AttributePrincipalImpl(principal, attributes, - proxyGrantingTicket, proxyRetriever); - assertion = new AssertionImpl(attributePrincipal); - } else { - assertion = new AssertionImpl(new AttributePrincipalImpl(principal, attributes)); - } - return assertion; - } - - static class CasServiceResponseAuthentication { - private final CasServiceResponseAuthenticationFailure authenticationFailure; - private final CasServiceResponseAuthenticationSuccess authenticationSuccess; - + record CasServiceResponseAuthentication(CasServiceResponseAuthenticationFailure authenticationFailure, + CasServiceResponseAuthenticationSuccess authenticationSuccess) { @JsonCreator - public CasServiceResponseAuthentication(@JsonProperty("authenticationFailure") - final CasServiceResponseAuthenticationFailure authenticationFailure, - @JsonProperty("authenticationSuccess") - final CasServiceResponseAuthenticationSuccess authenticationSuccess) { + CasServiceResponseAuthentication( + @JsonProperty("authenticationFailure") + final CasServiceResponseAuthenticationFailure authenticationFailure, + @JsonProperty("authenticationSuccess") + final CasServiceResponseAuthenticationSuccess authenticationSuccess) { this.authenticationFailure = authenticationFailure; this.authenticationSuccess = authenticationSuccess; } - - public CasServiceResponseAuthenticationFailure getAuthenticationFailure() { - return this.authenticationFailure; - } - - public CasServiceResponseAuthenticationSuccess getAuthenticationSuccess() { - return this.authenticationSuccess; - } } static class CasServiceResponseAuthenticationSuccess { private String user; + private String proxyGrantingTicket; + private List proxies; + private Map attributes; public String getUser() { @@ -135,6 +102,7 @@ public void setAttributes(final Map attributes) { static class CasServiceResponseAuthenticationFailure { private String code; + private String description; public String getCode() { @@ -153,6 +121,29 @@ public void setDescription(final String description) { this.description = description; } } + + Assertion getAssertion(final ProxyGrantingTicketStorage proxyGrantingTicketStorage, + final ProxyRetriever proxyRetriever) { + final var proxyGrantingTicketIou = serviceResponse().authenticationSuccess().getProxyGrantingTicket(); + final String proxyGrantingTicket; + if (CommonUtils.isBlank(proxyGrantingTicketIou) || proxyGrantingTicketStorage == null) { + proxyGrantingTicket = null; + } else { + proxyGrantingTicket = proxyGrantingTicketStorage.retrieve(proxyGrantingTicketIou); + } + + final Assertion assertion; + final Map attributes = serviceResponse().authenticationSuccess().getAttributes(); + final var principal = serviceResponse().authenticationSuccess().getUser(); + if (CommonUtils.isNotBlank(proxyGrantingTicket)) { + final AttributePrincipal attributePrincipal = new AttributePrincipalImpl(principal, attributes, + proxyGrantingTicket, proxyRetriever); + assertion = new AssertionImpl(attributePrincipal); + } else { + assertion = new AssertionImpl(new AttributePrincipalImpl(principal, attributes)); + } + return assertion; + } } diff --git a/cas-client-core/src/main/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidationFilter.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidationFilter.java new file mode 100644 index 000000000..e17351df9 --- /dev/null +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidationFilter.java @@ -0,0 +1,31 @@ +package org.apereo.cas.client.validation.jwt; + +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKey; +import org.apereo.cas.client.validation.AbstractTicketValidationFilter; +import org.apereo.cas.client.validation.TicketValidator; + +import jakarta.servlet.FilterConfig; + +public class CasJWTTicketValidationFilter extends AbstractTicketValidationFilter { + protected CasJWTTicketValidationFilter() { + super(Protocol.CAS3); + } + + @Override + protected TicketValidator getTicketValidator(final FilterConfig filterConfig) { + final var validator = new CasJWTTicketValidator(); + validator.setEncryptionKey(getString(new ConfigurationKey<>("encryptionKey"))); + validator.setSigningKey(getString(new ConfigurationKey<>("signingKey"))); + validator.setExpectedIssuer(getString(new ConfigurationKey<>("expectedIssuer"))); + validator.setExpectedAudience(getString(new ConfigurationKey<>("expectedAudience"))); + validator.setEncryptionKeyAlgorithm(getString(new ConfigurationKey<>("encryptionKeyAlgorithm", "AES"))); + validator.setSigningKeyAlgorithm(getString(new ConfigurationKey<>("signingKeyAlgorithm", "AES"))); + validator.setRequiredClaims(getString(new ConfigurationKey<>("requiredClaims", "sub,aud,iat,jti,exp,iss"))); + validator.setBase64EncryptionKey(getBoolean(new ConfigurationKey<>("base64EncryptionKey", true))); + validator.setBase64SigningKey(getBoolean(new ConfigurationKey<>("base64SigningKey", true))); + validator.setMaxClockSkew(getInt(new ConfigurationKey<>("maxClockSkew", 60))); + validator.initialize(); + return validator; + } +} diff --git a/cas-client-core/src/main/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidator.java b/cas-client-core/src/main/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidator.java new file mode 100644 index 000000000..d21f9645b --- /dev/null +++ b/cas-client-core/src/main/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidator.java @@ -0,0 +1,313 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client.validation.jwt; + +import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWEAlgorithm; +import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.jwk.source.ImmutableSecret; +import com.nimbusds.jose.proc.BadJOSEException; +import com.nimbusds.jose.proc.BadJWEException; +import com.nimbusds.jose.proc.BadJWSException; +import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier; +import com.nimbusds.jose.proc.JWEDecryptionKeySelector; +import com.nimbusds.jose.proc.JWSVerificationKeySelector; +import com.nimbusds.jose.proc.SecurityContext; +import com.nimbusds.jwt.EncryptedJWT; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.JWTParser; +import com.nimbusds.jwt.SignedJWT; +import com.nimbusds.jwt.proc.BadJWTException; +import com.nimbusds.jwt.proc.ConfigurableJWTProcessor; +import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier; +import com.nimbusds.jwt.proc.DefaultJWTProcessor; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.validation.Assertion; +import org.apereo.cas.client.validation.AssertionImpl; +import org.apereo.cas.client.validation.TicketValidationException; +import org.apereo.cas.client.validation.TicketValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.text.ParseException; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +/** + * This is {@link CasJWTTicketValidator} that attempts to parse the CAS service ticket + * as a JWT. + * + * @author Misagh Moayyed + */ +public class CasJWTTicketValidator implements TicketValidator { + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + private String signingKey; + + private String encryptionKey; + + private String expectedIssuer; + + private String expectedAudience; + + private String encryptionKeyAlgorithm = "AES"; + + private String signingKeyAlgorithm = "AES"; + + private String requiredClaims = "sub,aud,iat,jti,exp,iss"; + + private boolean base64EncryptionKey = true; + + private boolean base64SigningKey; + + private int maxClockSkew = 60; + + private ConfigurableJWTProcessor jwtProcessor; + + @Override + public Assertion validate(final String ticket, final String service) throws TicketValidationException { + try { + if (jwtProcessor == null) { + initialize(); + } + + final var claimsSet = this.jwtProcessor.process(ticket, null); + logger.debug("Validated claims are {}", claimsSet); + + return new AssertionImpl( + new AttributePrincipalImpl(claimsSet.getSubject(), claimsSet.getClaims()), + claimsSet.getIssueTime(), claimsSet.getExpirationTime(), + claimsSet.getIssueTime(), new HashMap<>()); + } catch (final Exception e) { + throw new TicketValidationException(e); + } + } + + public void initialize() { + logger.debug("Initializing JWT processor..."); + this.jwtProcessor = new CasJWTProcessor(); + jwtProcessor.setJWSTypeVerifier(new DefaultJOSEObjectTypeVerifier<>(JOSEObjectType.JWT)); + + final var jweKeySource = new ImmutableSecret<>(new SecretKeySpec( + base64EncryptionKey ? Base64.getDecoder().decode(encryptionKey) : encryptionKey.getBytes(StandardCharsets.UTF_8), encryptionKeyAlgorithm)); + final var jwsKeySource = new ImmutableSecret<>(new SecretKeySpec( + base64SigningKey ? Base64.getDecoder().decode(signingKey) : signingKey.getBytes(StandardCharsets.UTF_8), signingKeyAlgorithm)); + + configureKeySelectors(jwtProcessor, jweKeySource, jwsKeySource); + + final var requiredClaimsSet = Set.of(requiredClaims.split(",")); + final var exactMatchClaims = new JWTClaimsSet.Builder() + .issuer(expectedIssuer) + .audience(expectedAudience) + .build(); + final var jwtClaimsSetVerifier = new DefaultJWTClaimsVerifier<>(exactMatchClaims, requiredClaimsSet); + jwtClaimsSetVerifier.setMaxClockSkew(this.maxClockSkew); + jwtProcessor.setJWTClaimsSetVerifier(jwtClaimsSetVerifier); + } + + private static void configureKeySelectors(final ConfigurableJWTProcessor jwtProcessor, + final ImmutableSecret jweKeySource, + final ImmutableSecret jwsKeySource) { + final var jwsKeySelector = new JWSVerificationKeySelector<>(JWSAlgorithm.RS256, jwsKeySource) { + @Override + public List selectJWSKeys(final JWSHeader jwsHeader, final SecurityContext context) { + return List.of(jwsKeySource.getSecretKey()); + } + }; + final var jweKeySelector = new JWEDecryptionKeySelector<>(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256, jweKeySource) { + @Override + public List selectJWEKeys(final JWEHeader jweHeader, final SecurityContext context) { + return List.of(jweKeySource.getSecretKey()); + } + }; + jwtProcessor.setJWSKeySelector(jwsKeySelector); + jwtProcessor.setJWEKeySelector(jweKeySelector); + } + + public void setBase64EncryptionKey(final boolean base64EncryptionKey) { + this.base64EncryptionKey = base64EncryptionKey; + } + + public void setBase64SigningKey(final boolean base64SigningKey) { + this.base64SigningKey = base64SigningKey; + } + + public void setRequiredClaims(final String requiredClaims) { + this.requiredClaims = requiredClaims; + } + + public void setEncryptionKeyAlgorithm(final String encryptionKeyAlgorithm) { + this.encryptionKeyAlgorithm = encryptionKeyAlgorithm; + } + + public void setSigningKeyAlgorithm(final String signingKeyAlgorithm) { + this.signingKeyAlgorithm = signingKeyAlgorithm; + } + + public void setExpectedAudience(final String expectedAudience) { + this.expectedAudience = expectedAudience; + } + + public void setExpectedIssuer(final String expectedIssuer) { + this.expectedIssuer = expectedIssuer; + } + + public void setSigningKey(final String signingKey) { + this.signingKey = signingKey; + } + + public void setEncryptionKey(final String encryptionKey) { + this.encryptionKey = encryptionKey; + } + + public void setMaxClockSkew(final int maxClockSkew) { + this.maxClockSkew = maxClockSkew; + } + + private static class CasJWTProcessor extends DefaultJWTProcessor { + @Override + public JWTClaimsSet process(final SignedJWT signedJWT, final SecurityContext context) throws BadJOSEException, JOSEException { + getJWETypeVerifier().verify(signedJWT.getHeader().getType(), context); + final var keyCandidates = getJWSKeySelector().selectJWSKeys(signedJWT.getHeader(), context); + if (keyCandidates == null || keyCandidates.isEmpty()) { + throw new BadJOSEException("Signed JWT rejected: Another algorithm expected, or no matching key(s) found"); + } + var it = keyCandidates.listIterator(); + while (it.hasNext()) { + final var verifier = getJWSVerifierFactory().createJWSVerifier(signedJWT.getHeader(), it.next()); + if (verifier == null) { + continue; + } + var validSignature = signedJWT.verify(verifier); + if (validSignature) { + try { + if (signedJWT.getPayload() != null && signedJWT.getPayload().toJSONObject() == null) { + try { + var innerJwt = JWTParser.parse(signedJWT.getPayload().toString()); + if (innerJwt instanceof EncryptedJWT encryptedJWT) { + return decryptNestedJwt(encryptedJWT, context); + } + } catch (final ParseException e) { + throw new BadJWSException("Unable to parse inner JWT", e); + } + } + var claimsSet = signedJWT.getJWTClaimsSet(); + if (getJWTClaimsSetVerifier() != null) { + getJWTClaimsSetVerifier().verify(claimsSet, context); + } + return claimsSet; + } catch (final ParseException e) { + throw new BadJWSException("Unable to parse JWT", e); + } + } + if (!it.hasNext()) { + throw new BadJWSException("Signed JWT rejected: Invalid signature"); + } + } + throw new BadJOSEException("JWS object rejected: No matching verifier(s) found"); + } + + @Override + public JWTClaimsSet process(final EncryptedJWT encryptedJWT, final SecurityContext context) throws BadJOSEException, JOSEException { + getJWETypeVerifier().verify(encryptedJWT.getHeader().getType(), context); + var keyCandidates = getJWEKeySelector().selectJWEKeys(encryptedJWT.getHeader(), context); + if (keyCandidates == null || keyCandidates.isEmpty()) { + throw new BadJOSEException("Encrypted JWT rejected: Another algorithm expected, or no matching key(s) found"); + } + + var it = keyCandidates.listIterator(); + while (it.hasNext()) { + var decrypter = getJWEDecrypterFactory().createJWEDecrypter(encryptedJWT.getHeader(), it.next()); + if (decrypter == null) { + continue; + } + + try { + encryptedJWT.decrypt(decrypter); + } catch (JOSEException e) { + if (it.hasNext()) { + continue; + } + throw new BadJWEException("Encrypted JWT rejected: " + e.getMessage(), e); + } + + if ("JWT".equalsIgnoreCase(encryptedJWT.getHeader().getContentType())) { + var signedJWTPayload = encryptedJWT.getPayload().toSignedJWT(); + if (signedJWTPayload == null) { + throw new BadJWTException("The payload is not a nested signed JWT"); + } + return process(signedJWTPayload, context); + } + + try { + var claimsSet = encryptedJWT.getJWTClaimsSet(); + if (getJWTClaimsSetVerifier() != null) { + getJWTClaimsSetVerifier().verify(claimsSet, context); + } + return claimsSet; + } catch (final ParseException e) { + throw new BadJWTException(e.getMessage(), e); + } + } + throw new BadJOSEException("Encrypted JWT rejected: No matching decrypter(s) found"); + } + + private JWTClaimsSet decryptNestedJwt(final EncryptedJWT encryptedJWT, final SecurityContext context) throws BadJOSEException, JOSEException { + getJWETypeVerifier().verify(encryptedJWT.getHeader().getType(), context); + var keyCandidates = getJWEKeySelector().selectJWEKeys(encryptedJWT.getHeader(), context); + if (keyCandidates == null || keyCandidates.isEmpty()) { + throw new BadJOSEException("Encrypted JWT rejected: Another algorithm expected, or no matching key(s) found"); + } + var it = keyCandidates.listIterator(); + while (it.hasNext()) { + var decrypter = getJWEDecrypterFactory().createJWEDecrypter(encryptedJWT.getHeader(), it.next()); + if (decrypter == null) { + continue; + } + try { + encryptedJWT.decrypt(decrypter); + } catch (JOSEException e) { + if (it.hasNext()) { + continue; + } + throw new BadJWEException("Encrypted JWT rejected: " + e.getMessage(), e); + } + try { + var claimsSet = encryptedJWT.getJWTClaimsSet(); + if (getJWTClaimsSetVerifier() != null) { + getJWTClaimsSetVerifier().verify(claimsSet, context); + } + return claimsSet; + } catch (final ParseException e) { + throw new BadJWTException(e.getMessage(), e); + } + } + throw new BadJOSEException("Encrypted JWT rejected: No matching decrypter(s) found"); + } + } +} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/SimpleGroup.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/SimpleGroup.java deleted file mode 100644 index 794098ef7..000000000 --- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/SimpleGroup.java +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.authentication; - -import java.security.Principal; -import java.security.acl.Group; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; - -/** - * Simple security group implementation - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.11 - * - */ -public final class SimpleGroup extends SimplePrincipal implements Group { - - /** SimpleGroup.java */ - private static final long serialVersionUID = 4382154818494550205L; - - /** Group members */ - private final Set members = new HashSet(); - - /** - * Creates a new group with the given name. - * @param name Group name. - */ - public SimpleGroup(final String name) { - super(name); - } - - @Override - public boolean addMember(final Principal user) { - return this.members.add(user); - } - - @Override - public boolean isMember(final Principal member) { - return this.members.contains(member); - } - - @Override - public Enumeration members() { - return Collections.enumeration(this.members); - } - - @Override - public boolean removeMember(final Principal user) { - return this.members.remove(user); - } - - public String toString() { - return super.toString() + ": " + members.toString(); - } -} diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java b/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java deleted file mode 100644 index 45e301388..000000000 --- a/cas-client-core/src/main/java/org/jasig/cas/client/configuration/ConfigurationKeys.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.configuration; - -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.authentication.AuthenticationRedirectStrategy; -import org.jasig.cas.client.authentication.DefaultGatewayResolverImpl; -import org.jasig.cas.client.authentication.GatewayResolver; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; - -import javax.net.ssl.HostnameVerifier; - -/** - * Holder interface for all known configuration keys. - * - * @author Scott Battaglia - * @since 3.4.0 - */ -public interface ConfigurationKeys { - - ConfigurationKey ARTIFACT_PARAMETER_NAME = new ConfigurationKey("artifactParameterName", Protocol.CAS2.getArtifactParameterName()); - ConfigurationKey SERVER_NAME = new ConfigurationKey("serverName", null); - ConfigurationKey SERVICE = new ConfigurationKey("service"); - ConfigurationKey RENEW = new ConfigurationKey("renew", Boolean.FALSE); - ConfigurationKey LOGOUT_PARAMETER_NAME = new ConfigurationKey("logoutParameterName", "logoutRequest"); - ConfigurationKey ARTIFACT_PARAMETER_OVER_POST = new ConfigurationKey("artifactParameterOverPost", Boolean.FALSE); - ConfigurationKey EAGERLY_CREATE_SESSIONS = new ConfigurationKey("eagerlyCreateSessions", Boolean.TRUE); - ConfigurationKey ENCODE_SERVICE_URL = new ConfigurationKey("encodeServiceUrl", Boolean.TRUE); - ConfigurationKey SSL_CONFIG_FILE = new ConfigurationKey("sslConfigFile", null); - ConfigurationKey ROLE_ATTRIBUTE = new ConfigurationKey("roleAttribute", null); - ConfigurationKey IGNORE_CASE = new ConfigurationKey("ignoreCase", Boolean.FALSE); - ConfigurationKey CAS_SERVER_LOGIN_URL = new ConfigurationKey("casServerLoginUrl", null); - ConfigurationKey GATEWAY = new ConfigurationKey("gateway", Boolean.FALSE); - ConfigurationKey METHOD = new ConfigurationKey("method", null); - ConfigurationKey> AUTHENTICATION_REDIRECT_STRATEGY_CLASS = new ConfigurationKey>("authenticationRedirectStrategyClass", null); - ConfigurationKey> GATEWAY_STORAGE_CLASS = new ConfigurationKey>("gatewayStorageClass", DefaultGatewayResolverImpl.class); - ConfigurationKey CAS_SERVER_URL_PREFIX = new ConfigurationKey("casServerUrlPrefix", null); - ConfigurationKey ENCODING = new ConfigurationKey("encoding", null); - ConfigurationKey TOLERANCE = new ConfigurationKey("tolerance", 1000L); - ConfigurationKey PRIVATE_KEY_PATH = new ConfigurationKey("privateKeyPath", null); - ConfigurationKey PRIVATE_KEY_ALGORITHM = new ConfigurationKey("privateKeyAlgorithm", "RSA"); - - /** - * @deprecated As of 3.4. This constant is not used by the client and will - * be removed in future versions. - */ - @Deprecated - ConfigurationKey DISABLE_XML_SCHEMA_VALIDATION = new ConfigurationKey("disableXmlSchemaValidation", Boolean.FALSE); - ConfigurationKey IGNORE_PATTERN = new ConfigurationKey("ignorePattern", null); - ConfigurationKey IGNORE_URL_PATTERN_TYPE = new ConfigurationKey("ignoreUrlPatternType", "REGEX"); - ConfigurationKey> HOSTNAME_VERIFIER = new ConfigurationKey>("hostnameVerifier", null); - ConfigurationKey HOSTNAME_VERIFIER_CONFIG = new ConfigurationKey("hostnameVerifierConfig", null); - ConfigurationKey EXCEPTION_ON_VALIDATION_FAILURE = new ConfigurationKey("exceptionOnValidationFailure", Boolean.TRUE); - ConfigurationKey REDIRECT_AFTER_VALIDATION = new ConfigurationKey("redirectAfterValidation", Boolean.TRUE); - ConfigurationKey USE_SESSION = new ConfigurationKey("useSession", Boolean.TRUE); - ConfigurationKey SECRET_KEY = new ConfigurationKey("secretKey", null); - ConfigurationKey CIPHER_ALGORITHM = new ConfigurationKey("cipherAlgorithm", "DESede"); - ConfigurationKey PROXY_RECEPTOR_URL = new ConfigurationKey("proxyReceptorUrl", null); - ConfigurationKey> PROXY_GRANTING_TICKET_STORAGE_CLASS = new ConfigurationKey>("proxyGrantingTicketStorageClass", ProxyGrantingTicketStorageImpl.class); - ConfigurationKey MILLIS_BETWEEN_CLEAN_UPS = new ConfigurationKey("millisBetweenCleanUps", 60000); - ConfigurationKey ACCEPT_ANY_PROXY = new ConfigurationKey("acceptAnyProxy", Boolean.FALSE); - ConfigurationKey ALLOWED_PROXY_CHAINS = new ConfigurationKey("allowedProxyChains", null); - ConfigurationKey> TICKET_VALIDATOR_CLASS = new ConfigurationKey>("ticketValidatorClass", null); - ConfigurationKey PROXY_CALLBACK_URL = new ConfigurationKey("proxyCallbackUrl", null); - ConfigurationKey RELAY_STATE_PARAMETER_NAME = new ConfigurationKey("relayStateParameterName", "RelayState"); - ConfigurationKey LOGOUT_CALLBACK_PATH = new ConfigurationKey("logoutCallbackPath", null); -} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java b/cas-client-core/src/test/java/org/apereo/cas/client/PublicTestHttpServer.java similarity index 79% rename from cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java rename to cas-client-core/src/test/java/org/apereo/cas/client/PublicTestHttpServer.java index 87137dfc9..f251bb6f3 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/PublicTestHttpServer.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/PublicTestHttpServer.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,11 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client; - -import java.io.*; +package org.apereo.cas.client; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; import java.net.ServerSocket; -import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; @@ -32,43 +36,43 @@ */ public final class PublicTestHttpServer extends Thread { - public byte[] content; + private static final Map serverMap = new HashMap<>(); + + public final String encoding; private final byte[] header; private final int port; - public final String encoding; - - private ServerSocket server; - private final CountDownLatch ready = new CountDownLatch(1); - private static final Map serverMap = new HashMap(); + public byte[] content; + + private ServerSocket server; private PublicTestHttpServer(final String data, final String encoding, final String MIMEType, final int port) - throws UnsupportedEncodingException { + throws UnsupportedEncodingException { this(data.getBytes(encoding), encoding, MIMEType, port); } private PublicTestHttpServer(final byte[] data, final String encoding, final String MIMEType, final int port) - throws UnsupportedEncodingException { + throws UnsupportedEncodingException { this.content = data; this.port = port; this.encoding = encoding; - final String header = "HTTP/1.0 200 OK\r\n" + "Server: OneFile 1.0\r\n" + "Content-type: " + MIMEType + "\r\n\r\n"; + final var header = "HTTP/1.0 200 OK\r\n" + "Server: OneFile 1.0\r\n" + "Content-type: " + MIMEType + "\r\n\r\n"; this.header = header.getBytes("ASCII"); } public static synchronized PublicTestHttpServer instance(final int port) { if (serverMap.containsKey(port)) { - final PublicTestHttpServer server = serverMap.get(port); + final var server = serverMap.get(port); server.waitUntilReady(); return server; } try { - final PublicTestHttpServer server = new PublicTestHttpServer("test", "ASCII", "text/plain", port); + final var server = new PublicTestHttpServer("test", "ASCII", "text/plain", port); server.start(); serverMap.put(port, server); server.waitUntilReady(); @@ -78,15 +82,6 @@ public static synchronized PublicTestHttpServer instance(final int port) { } } - private void waitUntilReady() { - try { - ready.await(10, TimeUnit.SECONDS); - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("interrupted", e); - } - } - public void shutdown() { System.out.println("Shutting down connection on port " + server.getLocalPort()); try { @@ -105,17 +100,16 @@ public void run() { notifyReady(); while (true) { - Socket connection = null; - try { - connection = server.accept(); + try (final var connection = server.accept()) { final OutputStream out = new BufferedOutputStream(connection.getOutputStream()); final InputStream in = new BufferedInputStream(connection.getInputStream()); // read the first line only; that's all we need - final StringBuffer request = new StringBuffer(80); + final var request = new StringBuffer(80); while (true) { - final int c = in.read(); - if (c == '\r' || c == '\n' || c == -1) + final var c = in.read(); + if (c == '\r' || c == '\n' || c == -1) { break; + } request.append((char) c); } @@ -128,12 +122,8 @@ public void run() { } out.write(this.content); out.flush(); - } // end try - catch (final IOException e) { + } catch (final IOException e) { // nothing to do with this IOException - } finally { - if (connection != null) - connection.close(); } } // end while @@ -144,6 +134,15 @@ public void run() { } // end run + private void waitUntilReady() { + try { + ready.await(10, TimeUnit.SECONDS); + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("interrupted", e); + } + } + private void notifyReady() { ready.countDown(); } diff --git a/cas-client-core/src/test/java/org/apereo/cas/client/SerializationTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/SerializationTests.java new file mode 100644 index 000000000..6ac6b54d8 --- /dev/null +++ b/cas-client-core/src/test/java/org/apereo/cas/client/SerializationTests.java @@ -0,0 +1,75 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client; + +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.authentication.SimplePrincipal; +import org.apereo.cas.client.jaas.AssertionPrincipal; +import org.apereo.cas.client.validation.AssertionImpl; + +import junit.framework.TestCase; +import org.junit.Assert; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.util.Collections; + +/** + * Confirms serialization support for classes intended for session storage or + * other potential serialization use cases. + * + * @author Marvin S. Addison + * @version $Revision$ + * @since 3.1.11 + */ +public class SerializationTests extends TestCase { + + public void testSerializeDeserialize() throws Exception { + final var subjects = getTestSubjects(); + for (final Object subject : subjects) { + final var byteOut = new ByteArrayOutputStream(); + try (final ObjectOutput out = new ObjectOutputStream(byteOut)) { + out.writeObject(subject); + } catch (final Exception e) { + Assert.fail("Serialization failed for " + subject); + } + + final var byteIn = new ByteArrayInputStream(byteOut.toByteArray()); + try (final ObjectInput in = new ObjectInputStream(byteIn)) { + Assert.assertEquals(subject, in.readObject()); + } catch (final Exception e) { + Assert.fail("Deserialization failed for " + subject); + } + } + } + + private static Object[] getTestSubjects() { + final var simplePrincipal = new SimplePrincipal("simple"); + final var attributePrincipal = new AttributePrincipalImpl("attr", + Collections.singletonMap("LOA", "3")); + final var assertionPrincipal = new AssertionPrincipal("assertion", new AssertionImpl( + attributePrincipal, Collections.singletonMap("authenticationMethod", "username"))); + + return new Object[]{simplePrincipal, attributePrincipal, assertionPrincipal,}; + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/AuthenticationFilterTests.java similarity index 68% rename from cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/authentication/AuthenticationFilterTests.java index 0caa4ad54..7bff85b4d 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/AuthenticationFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/AuthenticationFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; + +import org.apereo.cas.client.util.AbstractCasFilter; +import org.apereo.cas.client.validation.AssertionImpl; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpSession; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.validation.AssertionImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -29,12 +36,7 @@ import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockServletContext; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import java.io.IOException; -import java.lang.reflect.Field; import java.net.URL; import java.net.URLEncoder; @@ -51,6 +53,7 @@ public final class AuthenticationFilterTests { private static final String CAS_SERVICE_URL = "https://localhost:8443/service"; private static final String CAS_PREFIX = "https://localhost:8443/cas"; + private static final String CAS_LOGIN_URL = CAS_PREFIX + "/login"; private AuthenticationFilter filter; @@ -58,7 +61,7 @@ public final class AuthenticationFilterTests { @Before public void setUp() throws Exception { this.filter = new AuthenticationFilter(); - final MockFilterConfig config = new MockFilterConfig(); + final var config = new MockFilterConfig(); config.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); config.addInitParameter("service", CAS_SERVICE_URL); this.filter.init(config); @@ -80,42 +83,15 @@ public void testRedirectWithCasServerPrefixConfig() throws Exception { doRedirectTest(); } - private void replaceFilterWithPrefixConfiguredFilter() throws ServletException { - this.filter = new AuthenticationFilter(); - final MockFilterConfig config = new MockFilterConfig(); - config.addInitParameter("casServerUrlPrefix", CAS_PREFIX); - config.addInitParameter("service", CAS_SERVICE_URL); - this.filter.init(config); - } - - private void doRedirectTest() throws IOException, ServletException { - final MockHttpSession session = new MockHttpSession(); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { - - @Override - public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { - // nothing to do - } - }; - - request.setSession(session); - this.filter.doFilter(request, response, filterChain); - - assertEquals(CAS_LOGIN_URL + "?service=" + URLEncoder.encode(CAS_SERVICE_URL, "UTF-8"), - response.getRedirectedUrl()); - } - @Test public void testRedirectWithQueryString() throws Exception { - final MockHttpSession session = new MockHttpSession(); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final HttpSession session = new MockHttpSession(); + final var request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); request.setQueryString("test=12456"); request.setRequestURI("/test"); request.setSecure(true); - final FilterChain filterChain = new FilterChain() { + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { @@ -126,7 +102,7 @@ public void doFilter(final ServletRequest request, final ServletResponse respons request.setSession(session); this.filter = new AuthenticationFilter(); - final MockFilterConfig config = new MockFilterConfig(); + final var config = new MockFilterConfig(); config.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); config.addInitParameter("serverName", "localhost:8443"); this.filter.init(config); @@ -135,18 +111,18 @@ public void doFilter(final ServletRequest request, final ServletResponse respons assertEquals( CAS_LOGIN_URL - + "?service=" - + URLEncoder.encode( + + "?service=" + + URLEncoder.encode( "https://localhost:8443" + request.getRequestURI() + "?" + request.getQueryString(), "UTF-8"), response.getRedirectedUrl()); } @Test public void testAssertion() throws Exception { - final MockHttpSession session = new MockHttpSession(); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final HttpSession session = new MockHttpSession(); + final var request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { @@ -163,10 +139,10 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testRenew() throws Exception { - final MockHttpSession session = new MockHttpSession(); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final HttpSession session = new MockHttpSession(); + final var request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { @@ -184,10 +160,10 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testGateway() throws Exception { - final MockHttpSession session = new MockHttpSession(); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final HttpSession session = new MockHttpSession(); + final var request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { @@ -202,12 +178,12 @@ public void doFilter(final ServletRequest request, final ServletResponse respons assertNotNull(session.getAttribute(DefaultGatewayResolverImpl.CONST_CAS_GATEWAY)); assertNotNull(response.getRedirectedUrl()); - final MockHttpServletResponse response2 = new MockHttpServletResponse(); + final var response2 = new MockHttpServletResponse(); this.filter.doFilter(request, response2, filterChain); assertNotNull(session.getAttribute(DefaultGatewayResolverImpl.CONST_CAS_GATEWAY)); assertNull(response2.getRedirectedUrl()); - final MockHttpServletResponse response3 = new MockHttpServletResponse(); + final var response3 = new MockHttpServletResponse(); this.filter.doFilter(request, response3, filterChain); assertNotNull(session.getAttribute(DefaultGatewayResolverImpl.CONST_CAS_GATEWAY)); assertNull(response3.getRedirectedUrl()); @@ -215,8 +191,8 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testRenewInitParamThrows() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockFilterConfig config = new MockFilterConfig(); + final var f = new AuthenticationFilter(); + final var config = new MockFilterConfig(); config.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); config.addInitParameter("service", CAS_SERVICE_URL); config.addInitParameter("renew", "true"); @@ -230,48 +206,48 @@ public void testRenewInitParamThrows() throws Exception { @Test public void testAllowsRenewContextParam() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); context.addInitParameter("service", CAS_SERVICE_URL); context.addInitParameter("renew", "true"); f.init(new MockFilterConfig(context)); - final Field renewField = AuthenticationFilter.class.getDeclaredField("renew"); + final var renewField = AuthenticationFilter.class.getDeclaredField("renew"); renewField.setAccessible(true); assertTrue((Boolean) renewField.get(f)); } @Test public void customRedirectStrategy() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); context.addInitParameter("service", CAS_SERVICE_URL); context.addInitParameter("authenticationRedirectStrategyClass", - "org.jasig.cas.client.authentication.FacesCompatibleAuthenticationRedirectStrategy"); + "org.apereocas.client.authentication.FacesCompatibleAuthenticationRedirectStrategy"); f.init(new MockFilterConfig(context)); } @Test public void testIgnorePatterns() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); context.addInitParameter("ignorePattern", "=valueTo(\\w+)"); context.addInitParameter("service", CAS_SERVICE_URL); f.init(new MockFilterConfig(context)); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final String URL = CAS_SERVICE_URL + "?param=valueToIgnore"; + final var request = new MockHttpServletRequest(); + final var URL = CAS_SERVICE_URL + "?param=valueToIgnore"; request.setRequestURI(URL); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { } @@ -283,8 +259,8 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testIgnorePatternsWithContainsMatching() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); context.addInitParameter("ignorePattern", "=valueToIgnore"); @@ -292,16 +268,16 @@ public void testIgnorePatternsWithContainsMatching() throws Exception { context.addInitParameter("service", CAS_SERVICE_URL); f.init(new MockFilterConfig(context)); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final String URL = CAS_SERVICE_URL + "?param=valueToIgnore"; + final var request = new MockHttpServletRequest(); + final var URL = CAS_SERVICE_URL + "?param=valueToIgnore"; request.setRequestURI(URL); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { } @@ -313,30 +289,30 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testIgnorePatternsWithExactMatching() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); - final URL url = new URL(CAS_SERVICE_URL + "?param=valueToIgnore"); + final var url = new URL(CAS_SERVICE_URL + "?param=valueToIgnore"); context.addInitParameter("ignorePattern", url.toExternalForm()); context.addInitParameter("ignoreUrlPatternType", "EXACT"); context.addInitParameter("service", CAS_SERVICE_URL); f.init(new MockFilterConfig(context)); - final MockHttpServletRequest request = new MockHttpServletRequest(); + final var request = new MockHttpServletRequest(); request.setScheme(url.getProtocol()); request.setServerName(url.getHost()); request.setServerPort(url.getPort()); request.setQueryString(url.getQuery()); request.setRequestURI(url.getPath()); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { } @@ -348,8 +324,8 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testIgnorePatternsWithExactClassname() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); context.addInitParameter("ignorePattern", "=valueToIgnore"); @@ -357,16 +333,16 @@ public void testIgnorePatternsWithExactClassname() throws Exception { context.addInitParameter("service", CAS_SERVICE_URL); f.init(new MockFilterConfig(context)); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final String URL = CAS_SERVICE_URL + "?param=valueToIgnore"; + final var request = new MockHttpServletRequest(); + final var URL = CAS_SERVICE_URL + "?param=valueToIgnore"; request.setRequestURI(URL); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { } @@ -378,8 +354,8 @@ public void doFilter(final ServletRequest request, final ServletResponse respons @Test public void testIgnorePatternsWithInvalidClassname() throws Exception { - final AuthenticationFilter f = new AuthenticationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new AuthenticationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerLoginUrl", CAS_LOGIN_URL); context.addInitParameter("ignorePattern", "=valueToIgnore"); @@ -387,16 +363,16 @@ public void testIgnorePatternsWithInvalidClassname() throws Exception { context.addInitParameter("service", CAS_SERVICE_URL); f.init(new MockFilterConfig(context)); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final String URL = CAS_SERVICE_URL + "?param=valueToIgnore"; + final var request = new MockHttpServletRequest(); + final var URL = CAS_SERVICE_URL + "?param=valueToIgnore"; request.setRequestURI(URL); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var response = new MockHttpServletResponse(); - final FilterChain filterChain = new FilterChain() { + final var filterChain = new FilterChain() { @Override public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { } @@ -405,4 +381,31 @@ public void doFilter(final ServletRequest request, final ServletResponse respons f.doFilter(request, response, filterChain); System.out.println(response.getRedirectedUrl()); } + + private void replaceFilterWithPrefixConfiguredFilter() throws ServletException { + this.filter = new AuthenticationFilter(); + final var config = new MockFilterConfig(); + config.addInitParameter("casServerUrlPrefix", CAS_PREFIX); + config.addInitParameter("service", CAS_SERVICE_URL); + this.filter.init(config); + } + + private void doRedirectTest() throws IOException, ServletException { + final HttpSession session = new MockHttpSession(); + final var request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); + final var filterChain = new FilterChain() { + + @Override + public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { + // nothing to do + } + }; + + request.setSession(session); + this.filter.doFilter(request, response, filterChain); + + assertEquals(CAS_LOGIN_URL + "?service=" + URLEncoder.encode(CAS_SERVICE_URL, "UTF-8"), + response.getRedirectedUrl()); + } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java similarity index 78% rename from cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java index b715e1054..6914d6752 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/DefaultAuthenticationRedirectStrategyTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; -import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; + +import static org.junit.Assert.*; + public class DefaultAuthenticationRedirectStrategyTests { private DefaultAuthenticationRedirectStrategy strategy; @@ -35,9 +38,9 @@ public void setUp() throws Exception { @Test public void didWeRedirect() throws Exception { - final String redirectUrl = "http://www.jasig.org"; - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var redirectUrl = "http://www.apereo.org"; + final HttpServletRequest request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); this.strategy.redirect(request, response, redirectUrl); assertEquals(redirectUrl, response.getRedirectedUrl()); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultGatewayResolverImplTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/DefaultGatewayResolverImplTests.java similarity index 76% rename from cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultGatewayResolverImplTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/authentication/DefaultGatewayResolverImplTests.java index b591b583b..18470209c 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/DefaultGatewayResolverImplTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/DefaultGatewayResolverImplTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,16 +16,18 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +import static org.junit.Assert.*; + public class DefaultGatewayResolverImplTests { private DefaultGatewayResolverImpl resolver; @@ -37,35 +39,35 @@ public void setUp() throws Exception { @Test public void testReentrancy() throws Exception { - final MockHttpServletRequest request1 = new MockHttpServletRequest(); + final HttpServletRequest request1 = new MockHttpServletRequest(); assertFalse(this.resolver.hasGatewayedAlready(request1, "foo")); assertFalse(this.resolver.hasGatewayedAlready(request1, "foo")); assertEquals("foo", this.resolver.storeGatewayInformation(request1, "foo")); assertEquals("foo", this.resolver.storeGatewayInformation(request1, "foo")); assertTrue(this.resolver.hasGatewayedAlready(request1, "foo")); assertTrue(this.resolver.hasGatewayedAlready(request1, "foo")); - } - + } + @Test public void testSessionConcurrency() throws Exception { - final MockHttpSession session = new MockHttpSession(); - final MockHttpServletRequest request1 = new MockHttpServletRequest(); - final MockHttpServletRequest request2 = new MockHttpServletRequest(); - request1.setSession(session); - request2.setSession(session); + final HttpSession session = new MockHttpSession(); + final var request1 = new MockHttpServletRequest(); + final var request2 = new MockHttpServletRequest(); + request1.setSession(session); + request2.setSession(session); assertFalse(this.resolver.hasGatewayedAlready(request1, "abc")); assertFalse(this.resolver.hasGatewayedAlready(request2, "def")); - + assertEquals("abc", this.resolver.storeGatewayInformation(request1, "abc")); - + assertTrue(this.resolver.hasGatewayedAlready(request2, "def")); assertTrue(this.resolver.hasGatewayedAlready(request1, "abc")); - + assertEquals("def", this.resolver.storeGatewayInformation(request2, "def")); - assertTrue(this.resolver.hasGatewayedAlready(request1, "abc")); + assertTrue(this.resolver.hasGatewayedAlready(request1, "abc")); assertTrue(this.resolver.hasGatewayedAlready(request2, "def")); - } + } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java similarity index 76% rename from cas-client-core/src/test/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java index bce6e0fd9..4ddabd0f5 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/authentication/FacesCompatibleAuthenticationRedirectStrategyTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; -import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; + +import static org.junit.Assert.*; + public class FacesCompatibleAuthenticationRedirectStrategyTests { private FacesCompatibleAuthenticationRedirectStrategy strategy; @@ -35,9 +38,9 @@ public void setUp() throws Exception { @Test public void didWeRedirect() throws Exception { - final String redirectUrl = "http://www.jasig.org"; - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var redirectUrl = "http://www.apereo.org"; + final HttpServletRequest request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); this.strategy.redirect(request, response, redirectUrl); assertEquals(redirectUrl, response.getRedirectedUrl()); @@ -45,9 +48,9 @@ public void didWeRedirect() throws Exception { @Test public void facesPartialResponse() throws Exception { - final String redirectUrl = "http://www.jasig.org"; - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var redirectUrl = "http://www.apereo.org"; + final var request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); request.setParameter("javax.faces.partial.ajax", "true"); this.strategy.redirect(request, response, redirectUrl); assertNull(response.getRedirectedUrl()); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/ConfigurationKeyTests.java similarity index 74% rename from cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/configuration/ConfigurationKeyTests.java index 6ae6f4bcb..d0f87f91a 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationKeyTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/ConfigurationKeyTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; import org.junit.Test; @@ -27,8 +27,8 @@ public final class ConfigurationKeyTests { @Test public void gettersWithNoDefaultValue() { - final String name = "name"; - final ConfigurationKey configurationKey = new ConfigurationKey(name); + final var name = "name"; + final var configurationKey = new ConfigurationKey(name); assertEquals(name, configurationKey.getName()); assertNull(configurationKey.getDefaultValue()); } @@ -36,9 +36,9 @@ public void gettersWithNoDefaultValue() { @Test public void gettersWithDefaultValue() { - final String name = "name"; - final Boolean defaultValue = Boolean.TRUE; - final ConfigurationKey configurationKey = new ConfigurationKey(name, defaultValue); + final var name = "name"; + final var defaultValue = Boolean.TRUE; + final var configurationKey = new ConfigurationKey<>(name, defaultValue); assertEquals(name, configurationKey.getName()); assertEquals(defaultValue, configurationKey.getDefaultValue()); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/ConfigurationStrategyNameTests.java similarity index 93% rename from cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/configuration/ConfigurationStrategyNameTests.java index 429974394..c56395391 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/ConfigurationStrategyNameTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/ConfigurationStrategyNameTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,13 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; import org.junit.Test; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; - import static org.junit.Assert.*; public final class ConfigurationStrategyNameTests { @@ -46,13 +45,13 @@ public void resolveToClass() { private class TestClass extends BaseConfigurationStrategy { @Override - protected String get(final ConfigurationKey configurationKey) { - return null; + public void init(final FilterConfig filterConfig, final Class filterClazz) { + } @Override - public void init(final FilterConfig filterConfig, final Class filterClazz) { - + protected String get(final ConfigurationKey configurationKey) { + return null; } } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/SystemPropertiesConfigurationStrategyImplTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/SystemPropertiesConfigurationStrategyImplTests.java similarity index 80% rename from cas-client-core/src/test/java/org/jasig/cas/client/configuration/SystemPropertiesConfigurationStrategyImplTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/configuration/SystemPropertiesConfigurationStrategyImplTests.java index 456085105..5e2b02b2b 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/SystemPropertiesConfigurationStrategyImplTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/SystemPropertiesConfigurationStrategyImplTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,15 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; -import static org.junit.Assert.assertEquals; +import org.apereo.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.AbstractCasFilter; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockFilterConfig; +import static org.junit.Assert.*; + /** * Tests {@link SystemPropertiesConfigurationStrategyImpl}. * @@ -33,7 +34,7 @@ */ public class SystemPropertiesConfigurationStrategyImplTests { - private final static String PARAMETER_NAME = "parameter"; + private static final String PARAMETER_NAME = "parameter"; private SystemPropertiesConfigurationStrategyImpl impl; @@ -48,14 +49,14 @@ public void setUp() throws Exception { @Test public void testNoSystemPropertyDefined() { - final ConfigurationKey key = ConfigurationKeys.SERVER_NAME; + final var key = ConfigurationKeys.SERVER_NAME; // no system property defined assertEquals(key.getDefaultValue(), impl.getString(key)); } @Test public void testWithSystemProperty() { - final ConfigurationKey key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; + final var key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; System.setProperty(key.getName(), PARAMETER_NAME); assertEquals(PARAMETER_NAME, impl.getString(key)); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java similarity index 66% rename from cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java index bee92438c..2ae1d87bd 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/configuration/WebXmlConfigurationStrategyImplTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,9 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.configuration; +package org.apereo.cas.client.configuration; + +import org.apereo.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.AbstractCasFilter; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockFilterConfig; @@ -42,35 +43,35 @@ public void setUp() throws Exception { @Test public void noKeyFoundGetDefaultForBoolean() { - final ConfigurationKey key = ConfigurationKeys.ACCEPT_ANY_PROXY; + final var key = ConfigurationKeys.ACCEPT_ANY_PROXY; assertEquals(key.getDefaultValue(), this.impl.getBoolean(key)); } @Test public void noKeyFoundGetDefaultForString() { - final ConfigurationKey key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; + final var key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; assertEquals(key.getDefaultValue(), this.impl.getString(key)); } @Test public void noKeyFoundGetDefaultForLong() { - final ConfigurationKey key = ConfigurationKeys.TOLERANCE; + final var key = ConfigurationKeys.TOLERANCE; assertEquals(key.getDefaultValue().longValue(), this.impl.getLong(key)); } @Test public void noKeyFoundGetDefaultForInt() { - final ConfigurationKey key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; + final var key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; assertEquals(key.getDefaultValue().intValue(), this.impl.getInt(key)); } @Test public void filterConfigValueForBoolean() { - final ConfigurationKey key = ConfigurationKeys.ACCEPT_ANY_PROXY; - final Boolean value = Boolean.TRUE; + final var key = ConfigurationKeys.ACCEPT_ANY_PROXY; + final var value = Boolean.TRUE; this.filterConfig.addInitParameter(key.getName(), value.toString()); assertEquals(value, this.impl.getBoolean(key)); } @@ -78,8 +79,8 @@ public void filterConfigValueForBoolean() { @Test public void filterConfigValueForString() { - final ConfigurationKey key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; - final String value = "foobar"; + final var key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; + final var value = "foobar"; this.filterConfig.addInitParameter(key.getName(), value); assertEquals(value, this.impl.getString(key)); } @@ -87,7 +88,7 @@ public void filterConfigValueForString() { @Test public void filterConfigValueForLong() { - final ConfigurationKey key = ConfigurationKeys.TOLERANCE; + final var key = ConfigurationKeys.TOLERANCE; final long value = 1500; this.filterConfig.addInitParameter(key.getName(), Long.toString(value)); assertEquals(value, this.impl.getLong(key)); @@ -96,8 +97,8 @@ public void filterConfigValueForLong() { @Test public void filterConfigValueForInt() { - final ConfigurationKey key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; - final int value = 1500; + final var key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; + final var value = 1500; this.filterConfig.addInitParameter(key.getName(), Integer.toString(value)); assertEquals(value, this.impl.getInt(key)); } @@ -105,9 +106,9 @@ public void filterConfigValueForInt() { @Test public void servletConfigValueForBoolean() { - final ConfigurationKey key = ConfigurationKeys.ACCEPT_ANY_PROXY; - final Boolean value = Boolean.TRUE; - final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext(); + final var key = ConfigurationKeys.ACCEPT_ANY_PROXY; + final var value = Boolean.TRUE; + final var context = (MockServletContext) this.filterConfig.getServletContext(); context.addInitParameter(key.getName(), value.toString()); assertEquals(value, this.impl.getBoolean(key)); } @@ -115,9 +116,9 @@ public void servletConfigValueForBoolean() { @Test public void servletConfigValueForString() { - final ConfigurationKey key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; - final String value = "foobar"; - final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext(); + final var key = ConfigurationKeys.ARTIFACT_PARAMETER_NAME; + final var value = "foobar"; + final var context = (MockServletContext) this.filterConfig.getServletContext(); context.addInitParameter(key.getName(), value); assertEquals(value, this.impl.getString(key)); } @@ -125,9 +126,9 @@ public void servletConfigValueForString() { @Test public void servletConfigValueForLong() { - final ConfigurationKey key = ConfigurationKeys.TOLERANCE; + final var key = ConfigurationKeys.TOLERANCE; final long value = 1500; - final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext(); + final var context = (MockServletContext) this.filterConfig.getServletContext(); context.addInitParameter(key.getName(), Long.toString(value)); assertEquals(value, this.impl.getLong(key)); } @@ -135,9 +136,9 @@ public void servletConfigValueForLong() { @Test public void servletConfigValueForInt() { - final ConfigurationKey key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; - final int value = 1500; - final MockServletContext context = (MockServletContext) this.filterConfig.getServletContext(); + final var key = ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS; + final var value = 1500; + final var context = (MockServletContext) this.filterConfig.getServletContext(); context.addInitParameter(key.getName(), Integer.toString(value)); assertEquals(value, this.impl.getInt(key)); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/jaas/CasLoginModuleTests.java similarity index 58% rename from cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/jaas/CasLoginModuleTests.java index f6b35a6b4..f73305cb3 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/jaas/CasLoginModuleTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/jaas/CasLoginModuleTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,28 +16,29 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.jaas; +package org.apereo.cas.client.jaas; + +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.validation.Cas20ServiceTicketValidator; +import org.apereo.cas.client.validation.TicketValidationException; -import static org.junit.Assert.*; -import java.security.Principal; -import java.security.acl.Group; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import javax.security.auth.Subject; -import javax.security.auth.login.LoginException; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.validation.TicketValidationException; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import javax.security.auth.Subject; +import javax.security.auth.login.LoginException; +import java.security.Principal; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + /** * Unit test for {@link CasLoginModule} class. * * @author Marvin S. Addison * @version $Revision$ - * */ public class CasLoginModuleTests { @@ -60,60 +61,60 @@ public static void classCleanUp() { public void setUp() throws Exception { module = new CasLoginModule(); subject = new Subject(); - options = new HashMap(); + options = new HashMap<>(); options.put("service", "https://service.example.com/webapp"); - options.put("ticketValidatorClass", "org.jasig.cas.client.validation.Cas20ServiceTicketValidator"); + options.put("ticketValidatorClass", Cas20ServiceTicketValidator.class.getName()); options.put("casServerUrlPrefix", CONST_CAS_SERVER_URL); options.put("proxyCallbackUrl", "https://service.example.com/webapp/proxy"); options.put("renew", "true"); options.put("defaultRoles", "ADMIN"); - options.put("principalGroupName", "CallerPrincipal"); options.put("roleGroupName", "Roles"); } /** * Test JAAS login success. + * * @throws Exception On errors. */ @Test public void testLoginSuccess() throws Exception { - final String USERNAME = "username"; - final String SERVICE = "https://example.com/service"; - final String TICKET = "ST-100000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; - final String RESPONSE = "" - + "" + USERNAME - + ""; + final var USERNAME = "username"; + final var SERVICE = "https://example.com/service"; + final var TICKET = "ST-100000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; + final var RESPONSE = "" + + "" + USERNAME + + ""; server.content = RESPONSE.getBytes(server.encoding); module.initialize( - subject, - new ServiceAndTicketCallbackHandler(SERVICE, TICKET), - new HashMap(), - options); + subject, + new ServiceAndTicketCallbackHandler(SERVICE, TICKET), + new HashMap<>(), + options); module.login(); module.commit(); - assertEquals(this.subject.getPrincipals().size(), 3); + assertEquals(this.subject.getPrincipals().size(), 1); assertEquals(TICKET, this.subject.getPrivateCredentials().iterator().next().toString()); assertTrue(hasPrincipalName(this.subject, AssertionPrincipal.class, USERNAME)); - assertTrue(hasPrincipalName(this.subject, Group.class, "CallerPrincipal")); - assertTrue(hasPrincipalName(this.subject, Group.class, "Roles")); } /** * Test JAAS login failure. + * * @throws Exception On errors. */ @Test public void testLoginFailure() throws Exception { - final String SERVICE = "https://example.com/service"; - final String TICKET = "ST-200000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; - final String RESPONSE = "Ticket ST-200000-aA5Yuvrxzpv8Tau1cYQ7-srv1 not recognized"; + final var SERVICE = "https://example.com/service"; + final var TICKET = "ST-200000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; + final var RESPONSE = + "Ticket ST-200000-aA5Yuvrxzpv8Tau1cYQ7-srv1 not recognized"; server.content = RESPONSE.getBytes(server.encoding); module.initialize( - subject, - new ServiceAndTicketCallbackHandler(SERVICE, TICKET), - new HashMap(), - options); + subject, + new ServiceAndTicketCallbackHandler(SERVICE, TICKET), + new HashMap<>(), + options); try { module.login(); fail("Login did not throw FailedLoginException as expected."); @@ -127,6 +128,7 @@ public void testLoginFailure() throws Exception { /** * Test JAAS logout after successful login to ensure subject cleanup. + * * @throws Exception On errors. */ @Test @@ -139,30 +141,32 @@ public void testLogout() throws Exception { /** * Confirm that CasLoginModule#logout() destroys cached data and prevents subsequent login w/expired ticket. + * * @throws Exception On errors. */ @Test public void testAssertionCaching() throws Exception { - final String USERNAME = "username"; - final String SERVICE = "https://example.com/service"; - final String TICKET = "ST-300000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; - final String SUCCESS_RESPONSE = "" - + "" + USERNAME - + ""; - final String FAILURE_RESPONSE = "Ticket ST-300000-aA5Yuvrxzpv8Tau1cYQ7-srv1 not recognized"; + final var USERNAME = "username"; + final var SERVICE = "https://example.com/service"; + final var TICKET = "ST-300000-aA5Yuvrxzpv8Tau1cYQ7-srv1"; + final var SUCCESS_RESPONSE = "" + + "" + USERNAME + + ""; + final var FAILURE_RESPONSE = + "Ticket ST-300000-aA5Yuvrxzpv8Tau1cYQ7-srv1 not recognized"; options.put("cacheAssertions", "true"); options.put("cacheTimeout", "1"); server.content = SUCCESS_RESPONSE.getBytes(server.encoding); module.initialize( - subject, - new ServiceAndTicketCallbackHandler(SERVICE, TICKET), - new HashMap(), - options); + subject, + new ServiceAndTicketCallbackHandler(SERVICE, TICKET), + new HashMap<>(), + options); module.login(); module.commit(); - assertEquals(this.subject.getPrincipals().size(), 3); + assertEquals(this.subject.getPrincipals().size(), 1); assertEquals(TICKET, this.subject.getPrivateCredentials().iterator().next().toString()); // Logout should destroy all authenticated state data including assertion cache entries @@ -173,10 +177,10 @@ public void testAssertionCaching() throws Exception { // Verify we can't log in again with same ticket module.initialize( - subject, - new ServiceAndTicketCallbackHandler(SERVICE, TICKET), - new HashMap(), - options); + subject, + new ServiceAndTicketCallbackHandler(SERVICE, TICKET), + new HashMap<>(), + options); try { module.login(); module.commit(); @@ -190,19 +194,20 @@ public void testAssertionCaching() throws Exception { /** * Verify that cached assertions that are expired are never be accessible - * by {@link org.jasig.cas.client.jaas.CasLoginModule#login()} method. + * by {@link CasLoginModule#login()} method. * * @throws Exception On errors. */ @Test public void testAssertionCachingExpiration() throws Exception { - final String USERNAME = "hizzy"; - final String SERVICE = "https://example.com/service"; - final String TICKET = "ST-12345-ABCDEFGHIJKLMNOPQRSTUVWXYZ-hosta"; - final String SUCCESS_RESPONSE = "" - + "" + USERNAME - + ""; - final String FAILURE_RESPONSE = "Ticket ST-12345-ABCDEFGHIJKLMNOPQRSTUVWXYZ-hosta not recognized"; + final var USERNAME = "hizzy"; + final var SERVICE = "https://example.com/service"; + final var TICKET = "ST-12345-ABCDEFGHIJKLMNOPQRSTUVWXYZ-hosta"; + final var SUCCESS_RESPONSE = "" + + "" + USERNAME + + ""; + final var FAILURE_RESPONSE = + "Ticket ST-12345-ABCDEFGHIJKLMNOPQRSTUVWXYZ-hosta not recognized"; options.put("cacheAssertions", "true"); // Cache timeout is 1 second @@ -211,10 +216,10 @@ public void testAssertionCachingExpiration() throws Exception { server.content = SUCCESS_RESPONSE.getBytes(server.encoding); module.initialize( - subject, - new ServiceAndTicketCallbackHandler(SERVICE, TICKET), - new HashMap(), - options); + subject, + new ServiceAndTicketCallbackHandler(SERVICE, TICKET), + new HashMap<>(), + options); assertTrue(module.login()); module.commit(); @@ -222,10 +227,10 @@ public void testAssertionCachingExpiration() throws Exception { // Assertion should now be expired from cache server.content = FAILURE_RESPONSE.getBytes(server.encoding); module.initialize( - subject, - new ServiceAndTicketCallbackHandler(SERVICE, TICKET), - new HashMap(), - options); + subject, + new ServiceAndTicketCallbackHandler(SERVICE, TICKET), + new HashMap<>(), + options); try { module.login(); fail("Should have thrown FailedLoginException."); @@ -234,9 +239,9 @@ public void testAssertionCachingExpiration() throws Exception { } } - private boolean hasPrincipalName(final Subject subject, final Class principalClass, - final String name) { - final Set principals = subject.getPrincipals(principalClass); + private static boolean hasPrincipalName(final Subject subject, final Class principalClass, + final String name) { + final var principals = subject.getPrincipals(principalClass); for (final Principal p : principals) { if (p.getName().equals(name)) { return true; diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/proxy/CleanUpTimerTaskTest.java b/cas-client-core/src/test/java/org/apereo/cas/client/proxy/CleanUpTimerTaskTest.java similarity index 80% rename from cas-client-core/src/test/java/org/jasig/cas/client/proxy/CleanUpTimerTaskTest.java rename to cas-client-core/src/test/java/org/apereo/cas/client/proxy/CleanUpTimerTaskTest.java index d31ebbd22..6fdde3577 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/proxy/CleanUpTimerTaskTest.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/proxy/CleanUpTimerTaskTest.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,24 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; + +import org.apereo.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter; -import java.util.TimerTask; import junit.framework.TestCase; -import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter; /** * Unit test for the {@link CleanUpTimerTask} - * + * * @author Brad Cupit (brad [at] lsu {dot} edu) */ public class CleanUpTimerTaskTest extends TestCase { public void testRun() throws Exception { - final ProxyGrantingTicketStorageTestImpl storage = new ProxyGrantingTicketStorageTestImpl(); + final var storage = new ProxyGrantingTicketStorageTestImpl(); new Cas20ProxyReceivingTicketValidationFilter().setProxyGrantingTicketStorage(storage); - final TimerTask timerTask = new CleanUpTimerTask(storage); + final Runnable timerTask = new CleanUpTimerTask(storage); timerTask.run(); assertTrue(storage.cleanUpWasCalled()); @@ -41,7 +41,7 @@ public void testRun() throws Exception { /** * implementation of the storage interface used only for testing - * + * * @author Brad Cupit (brad [at] lsu {dot} edu) */ private static final class ProxyGrantingTicketStorageTestImpl implements ProxyGrantingTicketStorage { @@ -52,8 +52,7 @@ public boolean cleanUpWasCalled() { } @Override - public void cleanUp() { - cleanUpCalled = true; + public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { } @Override @@ -62,7 +61,8 @@ public String retrieve(final String proxyGrantingTicketIou) { } @Override - public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { + public void cleanUp() { + cleanUpCalled = true; } } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorageImplTest.java b/cas-client-core/src/test/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorageImplTest.java similarity index 85% rename from cas-client-core/src/test/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorageImplTest.java rename to cas-client-core/src/test/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorageImplTest.java index 0b48d4038..ca37b4a60 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/proxy/ProxyGrantingTicketStorageImplTest.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/proxy/ProxyGrantingTicketStorageImplTest.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; import org.junit.Assert; import org.junit.Test; /** * Unit test for {@link ProxyGrantingTicketStorageImpl} - * + * * @author Brad Cupit (brad [at] lsu {dot} edu) */ public class ProxyGrantingTicketStorageImplTest { @@ -34,9 +34,9 @@ public class ProxyGrantingTicketStorageImplTest { @Test public void cleanUp() throws Exception { - final String proxyGrantingTicketIou = "proxyGrantingTicketIou"; + final var proxyGrantingTicketIou = "proxyGrantingTicketIou"; - final int timeout = 250; + final var timeout = 250; this.storage.save(proxyGrantingTicketIou, "proxyGrantingTicket"); // sleep long enough for the ticket to timeout diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/session/LogoutMessageGenerator.java b/cas-client-core/src/test/java/org/apereo/cas/client/session/LogoutMessageGenerator.java similarity index 65% rename from cas-client-core/src/test/java/org/jasig/cas/client/session/LogoutMessageGenerator.java rename to cas-client-core/src/test/java/org/apereo/cas/client/session/LogoutMessageGenerator.java index df7191083..b8021c8be 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/session/LogoutMessageGenerator.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/session/LogoutMessageGenerator.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,40 +16,40 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; +package org.apereo.cas.client.session; -import javax.xml.bind.DatatypeConverter; import java.nio.charset.Charset; +import java.util.Base64; import java.util.Date; import java.util.zip.Deflater; /** * Logout message generator to perform tests on Single Sign Out feature. * Greatly inspired by the source code in the CAS server itself. - * + * * @author Jerome Leleu * @since 3.4.0 */ public final class LogoutMessageGenerator { private static final String LOGOUT_REQUEST_TEMPLATE = - "@NOT_USED@" - + "%s"; + "@NOT_USED@" + + "%s"; public static String generateBackChannelLogoutMessage(final String sessionIndex) { return String.format(LOGOUT_REQUEST_TEMPLATE, new Date(), sessionIndex); } public static String generateFrontChannelLogoutMessage(final String sessionIndex) { - final String logoutMessage = generateBackChannelLogoutMessage(sessionIndex); - final Deflater deflater = new Deflater(); + final var logoutMessage = generateBackChannelLogoutMessage(sessionIndex); + final var deflater = new Deflater(); deflater.setInput(logoutMessage.getBytes(Charset.forName("ASCII"))); deflater.finish(); - final byte[] buffer = new byte[logoutMessage.length()]; - final int resultSize = deflater.deflate(buffer); - final byte[] output = new byte[resultSize]; + final var buffer = new byte[logoutMessage.length()]; + final var resultSize = deflater.deflate(buffer); + final var output = new byte[resultSize]; System.arraycopy(buffer, 0, output, 0, resultSize); - return DatatypeConverter.printBase64Binary(output); + return Base64.getEncoder().encodeToString(output); } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/session/SingleSignOutFilterTests.java similarity index 79% rename from cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/session/SingleSignOutFilterTests.java index 8af19169d..f9fa5f4f3 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/session/SingleSignOutFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,17 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +package org.apereo.cas.client.session; -import java.io.IOException; +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.configuration.ConfigurationKeys; -import javax.servlet.ServletException; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpSession; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockFilterChain; @@ -35,6 +32,10 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; +import java.io.IOException; + +import static org.junit.Assert.*; + /** * Tests {@link SingleSignOutFilter}. * @@ -43,12 +44,16 @@ */ public class SingleSignOutFilterTests { - private final static String TICKET = "ST-yyyyy"; - private final static String RELAY_STATE = "e1s1"; + private static final String TICKET = "ST-yyyyy"; + + private static final String RELAY_STATE = "e1s1"; private SingleSignOutFilter filter = new SingleSignOutFilter(); + private MockHttpServletRequest request; + private MockHttpServletResponse response; + private MockFilterChain filterChain; @Before @@ -65,7 +70,7 @@ public void setUp() throws Exception { public void tokenRequest() throws IOException, ServletException { request.setParameter(Protocol.CAS2.getArtifactParameterName(), TICKET); request.setQueryString(Protocol.CAS2.getArtifactParameterName() + "=" + TICKET); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); filter.doFilter(request, response, filterChain); assertEquals(session, SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().removeSessionByMappingId(TICKET)); @@ -74,9 +79,9 @@ public void tokenRequest() throws IOException, ServletException { @Test public void backChannelRequest() throws IOException, ServletException { request.setParameter(ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue(), - LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET)); + LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET)); request.setMethod("POST"); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().addSessionById(TICKET, session); filter.doFilter(request, response, filterChain); assertNull(SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().removeSessionByMappingId(TICKET)); @@ -84,11 +89,11 @@ public void backChannelRequest() throws IOException, ServletException { @Test public void frontChannelRequest() throws IOException, ServletException { - final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); request.setParameter(ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue(), logoutMessage); request.setQueryString(ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue() + "=" + logoutMessage); request.setMethod("GET"); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().addSessionById(TICKET, session); filter.doFilter(request, response, filterChain); assertNull(SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().removeSessionByMappingId(TICKET)); @@ -97,13 +102,13 @@ public void frontChannelRequest() throws IOException, ServletException { @Test public void frontChannelRequestRelayState() throws IOException, ServletException { - final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); request.setParameter(ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue(), logoutMessage); request.setParameter(ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue(), RELAY_STATE); request.setQueryString(ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue() + "=" + logoutMessage + "&" + - ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue() + "=" + RELAY_STATE); + ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue() + "=" + RELAY_STATE); request.setMethod("GET"); - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().addSessionById(TICKET, session); filter.doFilter(request, response, filterChain); assertNull(SingleSignOutFilter.getSingleSignOutHandler().getSessionMappingStorage().removeSessionByMappingId(TICKET)); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutHandlerTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/session/SingleSignOutHandlerTests.java similarity index 62% rename from cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutHandlerTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/session/SingleSignOutHandlerTests.java index 78ee0e9ae..c8bd6e257 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/session/SingleSignOutHandlerTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/session/SingleSignOutHandlerTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,12 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.session; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +package org.apereo.cas.client.session; import org.junit.Before; import org.junit.Test; @@ -29,25 +24,40 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; +import jakarta.servlet.http.HttpSession; + +import java.io.UnsupportedEncodingException; + +import static org.junit.Assert.*; + /** * @author Matt Brown * @since 3.2.1 */ public final class SingleSignOutHandlerTests { - private final static String ANOTHER_PARAMETER = "anotherParameter"; - private final static String TICKET = "ST-xxxxxxxx"; - private final static String LOGOUT_PARAMETER_NAME = "logoutRequest"; - private final static String RELAY_STATE_PARAMETER_NAME = "RelayState"; - private final static String ARTIFACT_PARAMETER_NAME = "ticket2"; + private static final String ANOTHER_PARAMETER = "anotherParameter"; + + private static final String TICKET = "ST-xxxxxxxx"; + + private static final String JSONP_CALLBACK_PARAMETER_NAME = "jsonpCallback"; + + private static final String LOGOUT_PARAMETER_NAME = "logoutRequest"; + + private static final String RELAY_STATE_PARAMETER_NAME = "RelayState"; + + private static final String ARTIFACT_PARAMETER_NAME = "ticket2"; private SingleSignOutHandler handler; + private MockHttpServletRequest request; + private MockHttpServletResponse response; @Before public void setUp() throws Exception { handler = new SingleSignOutHandler(); + handler.setJsonpCallbackParameterName(JSONP_CALLBACK_PARAMETER_NAME); handler.setLogoutParameterName(LOGOUT_PARAMETER_NAME); handler.setRelayStateParameterName(RELAY_STATE_PARAMETER_NAME); handler.setArtifactParameterName(ARTIFACT_PARAMETER_NAME); @@ -63,39 +73,39 @@ public void tokenRequestFailsIfNoSession() { request.setParameter(ARTIFACT_PARAMETER_NAME, TICKET); request.setQueryString(ARTIFACT_PARAMETER_NAME + "=" + TICKET); assertTrue(handler.process(request, response)); - final SessionMappingStorage storage = handler.getSessionMappingStorage(); + final var storage = handler.getSessionMappingStorage(); assertNull(storage.removeSessionByMappingId(TICKET)); } @Test public void tokenRequestFailsIfBadParameter() { - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); request.setParameter(ANOTHER_PARAMETER, TICKET); request.setQueryString(ANOTHER_PARAMETER + "=" + TICKET); assertTrue(handler.process(request, response)); - final SessionMappingStorage storage = handler.getSessionMappingStorage(); + final var storage = handler.getSessionMappingStorage(); assertNull(storage.removeSessionByMappingId(TICKET)); } @Test public void tokenRequestOK() { - final MockHttpSession session = new MockHttpSession(); + final HttpSession session = new MockHttpSession(); request.setSession(session); request.setParameter(ARTIFACT_PARAMETER_NAME, TICKET); request.setQueryString(ARTIFACT_PARAMETER_NAME + "=" + TICKET); assertTrue(handler.process(request, response)); - final SessionMappingStorage storage = handler.getSessionMappingStorage(); + final var storage = handler.getSessionMappingStorage(); assertEquals(session, storage.removeSessionByMappingId(TICKET)); } @Test public void backChannelLogoutFailsIfMultipart() { - final String logoutMessage = LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET); + final var logoutMessage = LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET); request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); request.setMethod("POST"); request.setContentType("multipart/form-data"); - final MockHttpSession session = new MockHttpSession(); + final var session = new MockHttpSession(); handler.getSessionMappingStorage().addSessionById(TICKET, session); assertTrue(handler.process(request, response)); assertFalse(session.isInvalid()); @@ -103,10 +113,10 @@ public void backChannelLogoutFailsIfMultipart() { @Test public void backChannelLogoutFailsIfNoSessionIndex() { - final String logoutMessage = LogoutMessageGenerator.generateBackChannelLogoutMessage(""); + final var logoutMessage = LogoutMessageGenerator.generateBackChannelLogoutMessage(""); request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); request.setMethod("POST"); - final MockHttpSession session = new MockHttpSession(); + final var session = new MockHttpSession(); handler.getSessionMappingStorage().addSessionById(TICKET, session); assertFalse(handler.process(request, response)); assertFalse(session.isInvalid()); @@ -114,7 +124,7 @@ public void backChannelLogoutFailsIfNoSessionIndex() { @Test public void backChannelLogoutOK() { - final MockHttpSession session = doBackChannelLogout(); + final var session = doBackChannelLogout(); assertFalse(handler.process(request, response)); assertTrue(session.isInvalid()); } @@ -123,7 +133,7 @@ public void backChannelLogoutOK() { public void backChannelLogoutDoesNotRunIfPathIsNotEligibleForLogout() { handler.setLogoutCallbackPath("/logout"); request.setServletPath("/not-a-logout"); - final MockHttpSession session = doBackChannelLogout(); + final var session = doBackChannelLogout(); assertTrue(handler.process(request, response)); assertFalse(session.isInvalid()); } @@ -132,27 +142,18 @@ public void backChannelLogoutDoesNotRunIfPathIsNotEligibleForLogout() { public void backChannelLogoutRunsIfPathEqualsLogoutPath() { handler.setLogoutCallbackPath("/logout"); request.setServletPath("/logout"); - final MockHttpSession session = doBackChannelLogout(); + final var session = doBackChannelLogout(); assertFalse(handler.process(request, response)); assertTrue(session.isInvalid()); } - private MockHttpSession doBackChannelLogout() { - final String logoutMessage = LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET); - request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); - request.setMethod("POST"); - final MockHttpSession session = new MockHttpSession(); - handler.getSessionMappingStorage().addSessionById(TICKET, session); - return session; - } - @Test public void frontChannelLogoutFailsIfBadParameter() { - final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); request.setParameter(ANOTHER_PARAMETER, logoutMessage); request.setMethod("GET"); request.setQueryString(ANOTHER_PARAMETER + "=" + logoutMessage); - final MockHttpSession session = new MockHttpSession(); + final var session = new MockHttpSession(); handler.getSessionMappingStorage().addSessionById(TICKET, session); assertTrue(handler.process(request, response)); assertFalse(session.isInvalid()); @@ -160,11 +161,11 @@ public void frontChannelLogoutFailsIfBadParameter() { @Test public void frontChannelLogoutFailsIfNoSessionIndex() { - final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(""); + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(""); request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); request.setQueryString(LOGOUT_PARAMETER_NAME + "=" + logoutMessage); request.setMethod("GET"); - final MockHttpSession session = new MockHttpSession(); + final var session = new MockHttpSession(); handler.getSessionMappingStorage().addSessionById(TICKET, session); assertFalse(handler.process(request, response)); assertFalse(session.isInvalid()); @@ -172,11 +173,11 @@ public void frontChannelLogoutFailsIfNoSessionIndex() { @Test public void frontChannelLogoutOK() { - final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); request.setQueryString(LOGOUT_PARAMETER_NAME + "=" + logoutMessage); request.setMethod("GET"); - final MockHttpSession session = new MockHttpSession(); + final var session = new MockHttpSession(); handler.getSessionMappingStorage().addSessionById(TICKET, session); assertFalse(handler.process(request, response)); assertTrue(session.isInvalid()); @@ -185,14 +186,51 @@ public void frontChannelLogoutOK() { @Test public void frontChannelLogoutRelayStateOK() { - final String logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); request.setParameter(RELAY_STATE_PARAMETER_NAME, TICKET); request.setQueryString(LOGOUT_PARAMETER_NAME + "=" + logoutMessage + "&" + RELAY_STATE_PARAMETER_NAME + "=" + TICKET); request.setMethod("GET"); - final MockHttpSession session = new MockHttpSession(); + final var session = new MockHttpSession(); + handler.getSessionMappingStorage().addSessionById(TICKET, session); + assertFalse(handler.process(request, response)); + assertTrue(session.isInvalid()); + } + + @Test + public void frontChannelLogoutCallbackOK() throws UnsupportedEncodingException { + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); + request.setParameter(JSONP_CALLBACK_PARAMETER_NAME, "testCallback"); + request.setQueryString(LOGOUT_PARAMETER_NAME + "=" + logoutMessage + "&" + JSONP_CALLBACK_PARAMETER_NAME + "=testCallback"); + request.setMethod("GET"); + final var session = new MockHttpSession(); handler.getSessionMappingStorage().addSessionById(TICKET, session); assertFalse(handler.process(request, response)); + assertEquals("application/javascript", response.getContentType()); + assertEquals("testCallback(true)", response.getContentAsString()); assertTrue(session.isInvalid()); } + + @Test + public void frontChannelLogoutCallbackNotPresentOK() throws UnsupportedEncodingException { + final var logoutMessage = LogoutMessageGenerator.generateFrontChannelLogoutMessage(TICKET); + request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); + request.setQueryString(LOGOUT_PARAMETER_NAME + "=" + logoutMessage); + request.setMethod("GET"); + final var session = new MockHttpSession(); + handler.getSessionMappingStorage().addSessionById(TICKET, session); + assertFalse(handler.process(request, response)); + assertTrue(response.getContentAsString().isEmpty()); + assertTrue(session.isInvalid()); + } + + private MockHttpSession doBackChannelLogout() { + final var logoutMessage = LogoutMessageGenerator.generateBackChannelLogoutMessage(TICKET); + request.setParameter(LOGOUT_PARAMETER_NAME, logoutMessage); + request.setMethod("POST"); + final var session = new MockHttpSession(); + handler.getSessionMappingStorage().addSessionById(TICKET, session); + return session; + } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/ssl/HttpsURLConnectionFactoryTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/ssl/HttpsURLConnectionFactoryTests.java similarity index 65% rename from cas-client-core/src/test/java/org/jasig/cas/client/ssl/HttpsURLConnectionFactoryTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/ssl/HttpsURLConnectionFactoryTests.java index 92b917fe0..e7ee9e657 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/ssl/HttpsURLConnectionFactoryTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/ssl/HttpsURLConnectionFactoryTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,12 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; import org.junit.Before; import org.junit.Test; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; import static org.junit.Assert.*; @@ -38,18 +42,18 @@ public void setUp() throws Exception { @Test public void serializeAndDeserialize() throws Exception { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final ObjectOutputStream oos = new ObjectOutputStream(baos); + final var baos = new ByteArrayOutputStream(); + final ObjectOutput oos = new ObjectOutputStream(baos); oos.writeObject(this.httpsURLConnectionFactory); oos.close(); - final byte[] serializedHttpsUrlConnectionFactory = baos.toByteArray(); + final var serializedHttpsUrlConnectionFactory = baos.toByteArray(); - final ByteArrayInputStream bais = new ByteArrayInputStream(serializedHttpsUrlConnectionFactory); - final ObjectInputStream ois = new ObjectInputStream(bais); + final var bais = new ByteArrayInputStream(serializedHttpsUrlConnectionFactory); + final var ois = new ObjectInputStream(bais); - final HttpsURLConnectionFactory deserializedObject = (HttpsURLConnectionFactory) ois.readObject(); + final var deserializedObject = (HttpsURLConnectionFactory) ois.readObject(); assertEquals(this.httpsURLConnectionFactory, deserializedObject); } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/ssl/RegexHostnameVerifierTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/ssl/RegexHostnameVerifierTests.java similarity index 86% rename from cas-client-core/src/test/java/org/jasig/cas/client/ssl/RegexHostnameVerifierTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/ssl/RegexHostnameVerifierTests.java index cc41ada0f..5d2a01bb6 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/ssl/RegexHostnameVerifierTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/ssl/RegexHostnameVerifierTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -29,10 +29,13 @@ Version: $Revision$ Updated: $Date$ */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; -import org.junit.Assert; import junit.framework.TestCase; +import org.junit.Assert; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; /** * Unit test for {@link RegexHostnameVerifier} class. @@ -47,7 +50,7 @@ public class RegexHostnameVerifierTests extends TestCase { * Test method for {@link RegexHostnameVerifier#verify(String, SSLSession)}. */ public void testVerify() { - final RegexHostnameVerifier verifier = new RegexHostnameVerifier("\\w+\\.vt\\.edu"); + final HostnameVerifier verifier = new RegexHostnameVerifier("\\w+\\.vt\\.edu"); Assert.assertTrue(verifier.verify("a.vt.edu", null)); Assert.assertTrue(verifier.verify("host.vt.edu", null)); Assert.assertFalse(verifier.verify("1-host.vt.edu", null)); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/ssl/WhitelistHostnameVerifierTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/ssl/WhitelistHostnameVerifierTests.java similarity index 86% rename from cas-client-core/src/test/java/org/jasig/cas/client/ssl/WhitelistHostnameVerifierTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/ssl/WhitelistHostnameVerifierTests.java index 13767165e..2994004a1 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/ssl/WhitelistHostnameVerifierTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/ssl/WhitelistHostnameVerifierTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -29,10 +29,12 @@ Version: $Revision$ Updated: $Date$ */ -package org.jasig.cas.client.ssl; +package org.apereo.cas.client.ssl; -import org.junit.Assert; import junit.framework.TestCase; +import org.junit.Assert; + +import javax.net.ssl.HostnameVerifier; /** * Unit test for {@link WhitelistHostnameVerifier} class. @@ -46,7 +48,7 @@ public class WhitelistHostnameVerifierTests extends TestCase { * Test method for {@link WhitelistHostnameVerifier#verify(String, javax.net.ssl.SSLSession)}. */ public void testVerify() { - final WhitelistHostnameVerifier verifier = new WhitelistHostnameVerifier("red.vt.edu, green.vt.edu,blue.vt.edu"); + final HostnameVerifier verifier = new WhitelistHostnameVerifier("red.vt.edu, green.vt.edu,blue.vt.edu"); Assert.assertTrue(verifier.verify("red.vt.edu", null)); Assert.assertTrue(verifier.verify("green.vt.edu", null)); Assert.assertTrue(verifier.verify("blue.vt.edu", null)); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/CasFilterTests.java similarity index 72% rename from cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/util/CasFilterTests.java index c2433f908..b357a0ae5 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/CasFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/CasFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,20 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; -import static org.junit.Assert.assertTrue; -import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import org.apereo.cas.client.Protocol; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; -import org.jasig.cas.client.Protocol; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import java.io.IOException; + +import static org.junit.Assert.*; + /** * @author Scott Battaglia * @version $Revision$ $Date$ @@ -39,14 +43,14 @@ public final class CasFilterTests { @Test public void serverName() { - final String serverNameWithoutSlash = "http://www.cnn.com"; - final String serverNameWithSlash = "http://www.cnn.com/"; + final var serverNameWithoutSlash = "http://www.cnn.com"; + final var serverNameWithSlash = "http://www.cnn.com/"; - final TestCasFilter testCasFilter = new TestCasFilter(); + final var testCasFilter = new TestCasFilter(); testCasFilter.setServerName(serverNameWithoutSlash); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final var request = new MockHttpServletRequest(); + final HttpServletResponse response = new MockHttpServletResponse(); request.setContextPath("/cas"); request.setRequestURI("/cas/test"); @@ -61,9 +65,10 @@ private static class TestCasFilter extends AbstractCasFilter { public TestCasFilter() { super(Protocol.CAS2); } + @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, - ServletException { + ServletException { // nothing to do } } diff --git a/cas-client-core/src/test/java/org/apereo/cas/client/util/CommonUtilsTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/CommonUtilsTests.java new file mode 100644 index 000000000..2abf2146c --- /dev/null +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/CommonUtilsTests.java @@ -0,0 +1,147 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client.util; + +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.ssl.HttpsURLConnectionFactory; + +import junit.framework.TestCase; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Tests for the CommonUtils. + * + * @author Scott Battaglia + * @since 3.0 + */ +public final class CommonUtilsTests extends TestCase { + + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8092); + + public void testRedirectUrlWithParam() { + final var loginUrl = "http://localhost:8080/login?myName=foo"; + final var fullyConstructedUrl = CommonUtils.constructRedirectUrl(loginUrl, "foo", "foo", false, false, null); + + assertEquals("http://localhost:8080/login?myName=foo&foo=foo", fullyConstructedUrl); + + var count = 0; + final var chars = fullyConstructedUrl.toCharArray(); + + for (final char aChar : chars) { + if (aChar == '?') { + count++; + } + } + + assertEquals(1, count); + } + + public void testRedirectUrlWithMethod() { + final var loginUrl = "http://localhost:8080/login"; + final var redirectUrl = CommonUtils.constructRedirectUrl(loginUrl, "foo", "foo", true, true, "post"); + + assertEquals("http://localhost:8080/login?foo=foo&renew=true&gateway=true&method=post", redirectUrl); + } + + public void testAssertNotNull() { + final var CONST_MESSAGE = "test"; + CommonUtils.assertNotNull(new Object(), CONST_MESSAGE); + try { + CommonUtils.assertNotNull(null, CONST_MESSAGE); + } catch (final IllegalArgumentException e) { + assertEquals(CONST_MESSAGE, e.getMessage()); + } + } + + public void testAssertNotEmpty() { + final var CONST_MESSAGE = "test"; + final Collection c = new ArrayList<>(); + c.add(new Object()); + CommonUtils.assertNotEmpty(c, CONST_MESSAGE); + try { + CommonUtils.assertNotEmpty(new ArrayList<>(), CONST_MESSAGE); + } catch (final IllegalArgumentException e) { + assertEquals(CONST_MESSAGE, e.getMessage()); + } + + try { + CommonUtils.assertNotEmpty(null, CONST_MESSAGE); + } catch (final IllegalArgumentException e) { + assertEquals(CONST_MESSAGE, e.getMessage()); + } + } + + public void testAssertTrue() { + final var CONST_MESSAGE = "test"; + CommonUtils.assertTrue(true, CONST_MESSAGE); + try { + CommonUtils.assertTrue(false, CONST_MESSAGE); + } catch (final IllegalArgumentException e) { + assertEquals(CONST_MESSAGE, e.getMessage()); + } + } + + public void testIsEmpty() { + assertFalse(CommonUtils.isEmpty("test")); + assertFalse(CommonUtils.isEmpty(" test")); + assertTrue(CommonUtils.isEmpty("")); + assertTrue(CommonUtils.isEmpty(null)); + assertFalse(CommonUtils.isEmpty(" ")); + } + + public void testIsNotEmpty() { + assertTrue(CommonUtils.isNotEmpty("test")); + assertTrue(CommonUtils.isNotEmpty(" test")); + assertFalse(CommonUtils.isNotEmpty("")); + assertFalse(CommonUtils.isNotEmpty(null)); + assertTrue(CommonUtils.isNotEmpty(" ")); + } + + public void testIsBlank() { + assertFalse(CommonUtils.isBlank("test")); + assertFalse(CommonUtils.isBlank(" test")); + assertTrue(CommonUtils.isBlank("")); + assertTrue(CommonUtils.isBlank(null)); + assertTrue(CommonUtils.isBlank(" ")); + } + + public void testIsNotBlank() { + assertTrue(CommonUtils.isNotBlank("test")); + assertTrue(CommonUtils.isNotBlank(" test")); + assertFalse(CommonUtils.isNotBlank("")); + assertFalse(CommonUtils.isNotBlank(null)); + assertFalse(CommonUtils.isNotBlank(" ")); + } + + public void testGetResponseFromServer() throws Exception { + final var RESPONSE = "test1\r\ntest2"; + server.content = RESPONSE.getBytes(server.encoding); + + final var responsedContent = CommonUtils.getResponseFromServer(new URL("http://localhost:8092"), new HttpsURLConnectionFactory(), null); + assertEquals(RESPONSE, responsedContent); + } + + public void testUrlEncode() { + assertEquals("this+is+a+very+special+parameter+with+%3D%25%2F", + CommonUtils.urlEncode("this is a very special parameter with =%/")); + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/ErrorRedirectFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/ErrorRedirectFilterTests.java similarity index 85% rename from cas-client-core/src/test/java/org/jasig/cas/client/util/ErrorRedirectFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/util/ErrorRedirectFilterTests.java index b18b153bc..ec2147911 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/ErrorRedirectFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/ErrorRedirectFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletRequest; import org.junit.Before; import org.junit.Test; @@ -25,8 +28,6 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import javax.servlet.FilterChain; - import static org.junit.Assert.*; public final class ErrorRedirectFilterTests { @@ -42,7 +43,7 @@ public final class ErrorRedirectFilterTests { public void setUp() throws Exception { this.errorRedirectFilter = new ErrorRedirectFilter(); - final MockFilterConfig filterConfig = new MockFilterConfig(); + final var filterConfig = new MockFilterConfig(); filterConfig.addInitParameter(IllegalStateException.class.getName(), REDIRECT_URL); this.errorRedirectFilter.init(filterConfig); this.filterChain = new MockFilterChain(); @@ -51,8 +52,8 @@ public void setUp() throws Exception { @Test public void noRootCause() throws Exception { - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpServletResponse response = new MockHttpServletResponse(); + final ServletRequest request = new MockHttpServletRequest(); + final var response = new MockHttpServletResponse(); // this should be okay as the mock filter chain allows one call this.errorRedirectFilter.doFilter(request, response, this.filterChain); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/HttpServletRequestWrapperFilterTests.java similarity index 66% rename from cas-client-core/src/test/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/util/HttpServletRequestWrapperFilterTests.java index 1a6311e3a..207b3c7ce 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/HttpServletRequestWrapperFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/HttpServletRequestWrapperFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,26 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; + +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.validation.AssertionImpl; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; import junit.framework.TestCase; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.validation.AssertionImpl; import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + /** * Tests for the HttpServletRequestWrapperFilter. * @@ -45,13 +45,13 @@ public final class HttpServletRequestWrapperFilterTests extends TestCase { - protected HttpServletRequest mockRequest; + private HttpServletRequest mockRequest; public void testWrappedRequest() throws Exception { - final HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter(); + final var filter = new HttpServletRequestWrapperFilter(); filter.init(new MockFilterConfig()); - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpSession session = new MockHttpSession(); + final var request = new MockHttpServletRequest(); + final HttpSession session = new MockHttpSession(); session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, new AssertionImpl("test")); request.setSession(session); @@ -63,15 +63,15 @@ public void testWrappedRequest() throws Exception { } public void testIsUserInRole() throws Exception { - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpSession session = new MockHttpSession(); - final MockFilterConfig config = new MockFilterConfig(); + final var request = new MockHttpServletRequest(); + final HttpSession session = new MockHttpSession(); + final var config = new MockFilterConfig(); config.addInitParameter("roleAttribute", "memberOf"); - final HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter(); + final var filter = new HttpServletRequestWrapperFilter(); filter.init(config); - final Map attributes = new HashMap(); + final Map attributes = new HashMap<>(); attributes.put("memberOf", "administrators"); final AttributePrincipal principal = new AttributePrincipalImpl("alice", attributes); session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, new AssertionImpl(principal)); @@ -89,17 +89,17 @@ public void testIsUserInRole() throws Exception { } public void testIsUserInRoleCaseInsensitive() throws Exception { - final MockHttpServletRequest request = new MockHttpServletRequest(); - final MockHttpSession session = new MockHttpSession(); - final MockFilterConfig config = new MockFilterConfig(); + final var request = new MockHttpServletRequest(); + final HttpSession session = new MockHttpSession(); + final var config = new MockFilterConfig(); config.addInitParameter("roleAttribute", "groupMembership"); config.addInitParameter("ignoreCase", "true"); - final HttpServletRequestWrapperFilter filter = new HttpServletRequestWrapperFilter(); + final var filter = new HttpServletRequestWrapperFilter(); filter.init(config); - final Map attributes = new HashMap(); - attributes.put("groupMembership", Arrays.asList(new Object[] { "animals", "ducks" })); + final Map attributes = new HashMap<>(); + attributes.put("groupMembership", Arrays.asList(new Object[]{"animals", "ducks"})); final AttributePrincipal principal = new AttributePrincipalImpl("daffy", attributes); session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, new AssertionImpl(principal)); @@ -118,12 +118,6 @@ public void testIsUserInRoleCaseInsensitive() throws Exception { } private FilterChain createFilterChain() { - return new FilterChain() { - @Override - public void doFilter(final ServletRequest request, final ServletResponse response) throws IOException, ServletException { - HttpServletRequestWrapperFilterTests.this.mockRequest = (HttpServletRequest) request; - } - - }; + return (request, response) -> HttpServletRequestWrapperFilterTests.this.mockRequest = (HttpServletRequest) request; } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/MethodFlag.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/MethodFlag.java similarity index 89% rename from cas-client-core/src/test/java/org/jasig/cas/client/util/MethodFlag.java rename to cas-client-core/src/test/java/org/apereo/cas/client/util/MethodFlag.java index 907a1552f..faa488171 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/MethodFlag.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/MethodFlag.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; /** * A mutable boolean-like flag for unit tests which use @@ -24,7 +24,7 @@ *

* A simple boolean would be ideal, except Java requires us * to mark enclosing local variables as final. - * + * * @author Brad Cupit (brad [at] lsu {dot} edu) */ public class MethodFlag { diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/ReflectUtilsTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/ReflectUtilsTests.java similarity index 81% rename from cas-client-core/src/test/java/org/jasig/cas/client/util/ReflectUtilsTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/util/ReflectUtilsTests.java index 76ea14218..2f0fcd219 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/ReflectUtilsTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/ReflectUtilsTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; import junit.framework.TestCase; @@ -30,19 +30,19 @@ */ public class ReflectUtilsTests extends TestCase { /** - * Test method for {@link org.jasig.cas.client.util.ReflectUtils#newInstance(java.lang.String, java.lang.Object[])}. + * Test method for {@link ReflectUtils#newInstance(String, Object[])}. */ public void testNewInstanceStringObjectArray() { - final Object result = ReflectUtils.newInstance("org.jasig.cas.client.validation.Cas10TicketValidator", - new Object[] { "https://localhost/cas" }); + final var result = ReflectUtils.newInstance("org.apereo.cas.client.validation.Cas10TicketValidator", + new Object[]{"https://localhost/cas"}); assertNotNull(result); } /** - * Test method for {@link org.jasig.cas.client.util.ReflectUtils#setProperty(java.lang.String, java.lang.Object, java.lang.Object)}. + * Test method for {@link ReflectUtils#setProperty(String, Object, Object)}. */ public void testSetPropertyStringObjectObject() { - final TestBean bean = new TestBean(); + final var bean = new TestBean(); ReflectUtils.setProperty("count", new Integer(30000), bean); assertEquals(30000, bean.getCount()); @@ -55,20 +55,22 @@ public void testSetPropertyStringObjectObject() { } public void testGetField() { - final TestBean bean = new TestBean(); + final var bean = new TestBean(); bean.setName("bob"); assertEquals(bean.getName(), ReflectUtils.getField("name", bean)); } public void testGetFieldSuperclass() { - final TestSubBean bean = new TestSubBean(); + final var bean = new TestSubBean(); bean.setName("bob"); assertEquals(bean.getName(), ReflectUtils.getField("name", bean)); } static class TestBean { private int count; + private boolean flag; + private String name; /** diff --git a/cas-client-core/src/test/java/org/apereo/cas/client/util/URIBuilderTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/URIBuilderTests.java new file mode 100644 index 000000000..2604e23ec --- /dev/null +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/URIBuilderTests.java @@ -0,0 +1,333 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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. + */ +/* + + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + * + * 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.apereo.cas.client.util; + +import org.junit.Test; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + +/** + * @author Misagh Moayyed + */ +public class URIBuilderTests { + + @Test + public void allPartsUsed() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("http://apache.org/shindig?hello=world#foo", builder.toString()); + } + + @Test + public void noSchemeUsed() { + final var builder = new URIBuilder() + .setHost("apache.org") + .setPath("/shindig") + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("//apache.org/shindig?hello=world#foo", builder.toString()); + } + + @Test + public void noAuthorityUsed() { + final var builder = new URIBuilder() + .setScheme("http") + .setPath("/shindig") + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("http:/shindig?hello=world#foo", builder.toString()); + } + + @Test + public void noPathUsed() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("http://apache.org?hello=world#foo", builder.toString()); + } + + @Test + public void noQueryUsed() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .setFragment("foo"); + assertEquals("http://apache.org/shindig#foo", builder.toString()); + } + + @Test + public void noFragmentUsed() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .setCustomQuery("hello=world"); + assertEquals("http://apache.org/shindig?hello=world", builder.toString()); + } + + @Test + public void hostRelativePaths() { + final var builder = new URIBuilder() + .setPath("/shindig") + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("/shindig?hello=world#foo", builder.toString()); + } + + @Test + public void relativePaths() { + final var builder = new URIBuilder() + .setPath("foo") + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("foo?hello=world#foo", builder.toString()); + } + + @Test + public void noPathNoHostNoAuthority() { + final var builder = new URIBuilder() + .setCustomQuery("hello=world") + .setFragment("foo"); + assertEquals("?hello=world#foo", builder.toString()); + } + + @Test + public void justSchemeAndAuthority() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org"); + assertEquals("http://apache.org", builder.toString()); + } + + @Test + public void justPath() { + final var builder = new URIBuilder() + .setPath("/shindig"); + assertEquals("/shindig", builder.toString()); + } + + @Test + public void justAuthorityAndPath() { + final var builder = new URIBuilder() + .setHost("apache.org") + .setPath("/shindig"); + assertEquals("//apache.org/shindig", builder.toString()); + } + + @Test + public void justQuery() { + final var builder = new URIBuilder() + .setCustomQuery("hello=world"); + assertEquals("?hello=world", builder.toString()); + } + + @Test + public void justFragment() { + final var builder = new URIBuilder() + .setFragment("foo"); + assertEquals("#foo", builder.toString()); + } + + @Test + public void addSingleQueryParameter() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .addParameter("hello", "world") + .setFragment("foo"); + assertEquals("http://apache.org/shindig?hello=world#foo", builder.toString()); + } + + @Test + public void addTwoQueryParameters() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .addParameter("hello", "world") + .addParameter("foo", "bar") + .setFragment("foo"); + assertEquals("http://apache.org/shindig?hello=world&foo=bar#foo", builder.toString()); + } + + @Test + public void iterableQueryParameters() { + final List list = new ArrayList<>(); + list.add(new URIBuilder.BasicNameValuePair("hello", "world")); + list.add(new URIBuilder.BasicNameValuePair("hello", "monde")); + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .addParameters(list) + .setFragment("foo"); + assertEquals("http://apache.org/shindig?hello=world&hello=monde#foo", builder.toString()); + } + + @Test + public void removeQueryParameter() { + final var uri = new URIBuilder("http://www.example.com/foo?bar=baz&quux=baz"); + uri.removeQuery(); + assertEquals("http://www.example.com/foo", uri.toString()); + } + + @Test + public void addIdenticalParameters() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .addParameter("hello", "world") + .addParameter("hello", "goodbye") + .setFragment("foo"); + assertEquals("http://apache.org/shindig?hello=world&hello=goodbye#foo", builder.toString()); + } + + @Test + public void queryStringIsUnescaped() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .setCustomQuery("hello+world=world%26bar"); + assertEquals("world&bar", builder.build().getQuery().split("=")[1]); + } + + @Test + public void queryParamsAreEscaped() { + final var builder = new URIBuilder(true) + .setScheme("http") + .setHost("apache.org") + .setEncodedPath("/shindig") + .addParameter("hello world", "foo&bar") + .setFragment("foo"); + assertEquals("http://apache.org/shindig?hello+world=foo%26bar#foo", builder.toString()); + assertEquals("hello+world=foo&bar", builder.build().getQuery()); + } + + @Test + public void addSingleFragmentParameter() { + final var builder = new URIBuilder() + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .setFragment("hello=world") + .setCustomQuery("foo"); + assertEquals("http://apache.org/shindig?foo#hello=world", builder.toString()); + } + + @Test + public void fragmentStringIsUnescaped() { + final var builder = new URIBuilder(true) + .setScheme("http") + .setHost("apache.org") + .setPath("/shindig") + .setEncodedFragment("hello+world=world%26bar"); + + assertEquals("world&bar", builder.build().getFragment().split("=")[1]); + } + + @Test + public void parse() { + final var builder = new URIBuilder() + .digestURI(URI.create("http://apache.org/shindig?foo=bar%26baz&foo=three%3Dbaz#blah")); + + assertEquals("http", builder.getScheme()); + assertEquals("apache.org", builder.getHost()); + assertEquals("/shindig", builder.getPath()); + + final var list = builder.getQueryParams(); + for (final var pair : list) { + assertEquals("foo", pair.name()); + assertTrue(pair.value().equals("three=baz") || pair.value().equals("bar&baz")); + } + assertEquals(list.size(), 2); + assertEquals("blah", builder.getFragment()); + } + + @Test + public void constructFromUriAndBack() { + final var uri = URI.create("http://apache.org/foo/bar?foo=bar&a=b&c=d&y=z&foo=zoo#foo"); + final var builder = new URIBuilder(uri); + + assertEquals(uri, builder.build()); + } + + @Test + public void constructFromUriAndModify() { + final var uri = URI.create("http://apache.org/foo/bar?foo=bar#foo"); + final var builder = new URIBuilder(uri); + + builder.setHost("example.org"); + builder.addParameter("bar", "foo"); + + assertEquals("http://example.org/foo/bar?foo=bar&bar=foo#foo", builder.toString()); + } + + @Test + public void equalsAndHashCodeOk() { + final var uri = new URIBuilder().digestURI(URI.create("http://example.org/foo/bar/baz?blah=blah#boo")); + final var uri2 = new URIBuilder(URI.create("http://example.org/foo/bar/baz?blah=blah#boo")); + + assertEquals(uri, uri2); + assertEquals(uri2, uri); + + assertEquals(uri, uri); + + assertNotNull(uri); + assertNotSame(uri, "http://example.org/foo/bar/baz?blah=blah#boo"); + assertNotSame(uri, URI.create("http://example.org/foo/bar/baz?blah=blah#boo")); + assertEquals(uri.hashCode(), uri2.hashCode()); + } + + +} diff --git a/cas-client-core/src/test/java/org/apereo/cas/client/util/WebUtilsTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/util/WebUtilsTests.java new file mode 100644 index 000000000..0e9cd0a1c --- /dev/null +++ b/cas-client-core/src/test/java/org/apereo/cas/client/util/WebUtilsTests.java @@ -0,0 +1,233 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client.util; + +import org.apereo.cas.client.Protocol; + +import jakarta.servlet.http.HttpServletResponse; +import junit.framework.TestCase; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +/** + * Tests for the WebUtils. + * + * @author Jerome LELEU + * @since 4.0.3 + */ +public final class WebUtilsTests extends TestCase { + + public void testConstructServiceUrlWithTrailingSlash() { + final var CONST_MY_URL = "https://www.myserver.com/hello/hithere/"; + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + "service", "ticket", false); + + assertEquals(CONST_MY_URL, constructedUrl); + } + + public void testConstructServiceUrlWithServerNameContainingPath() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.my.server.com/app", + Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); + + assertEquals("https://www.my.server.com/app/hello/hithere/", constructedUrl); + } + + public void testConstructServiceUrlWithServerNameContainingPathAndSchema() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "https://www.my.server.com/app", + Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); + + assertEquals("https://www.my.server.com/app/hello/hithere/", constructedUrl); + } + + public void testConstructServiceUrlWithParamsCas() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("service=this&ticket=that&custom=custom"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); + } + + public void testConstructServiceUrlWithParamsCasAndServerNameWithSchema() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("service=this&ticket=that&custom=custom"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "https://www.myserver.com", + Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); + } + + + public void testConstructServiceUrlWithParamsSaml() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("TARGET=this&SAMLart=that&custom=custom"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), false); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); + } + + public void testConstructServiceUrlWithEncodedParamsSaml() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("TARGET%3Dthis%26SAMLart%3Dthat%26custom%3Dcustom"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), false); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); + } + + public void testConstructServiceUrlWithNoServiceParametersPassed() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("TARGET=Test1&service=Test2&custom=custom"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.SAML11.getArtifactParameterName(), true); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); + } + + public void testConstructServiceUrlWithEncodedParams2Saml() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("TARGET%3Dthis%26SAMLart%3Dthat%26custom%3Dcustom%20value%20here%26another%3Dgood"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), true); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom+value+here&another=good", constructedUrl); + } + + public void testConstructServiceUrlWithoutEncodedParamsSamlAndNoEncoding() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("TARGET=this&SAMLart=that&custom=custom value here&another=good"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), false); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom value here&another=good", constructedUrl); + } + + public void testConstructServiceUrlWithEncodedParamsSamlAndNoEncoding() { + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.setScheme("https"); + request.setSecure(true); + request.setQueryString("TARGET=this&SAMLart=that&custom=custom+value+here&another=good"); + + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, "www.myserver.com", + Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), true); + + assertEquals("https://www.myserver.com/hello/hithere/?custom=custom+value+here&another=good", constructedUrl); + } + + public void testConstructUrlNonStandardPortAndNoScheme() { + constructUrlNonStandardPortAndNoPortInConfigTest("www.myserver.com"); + } + + public void testConstructUrlNonStandardPortAndScheme() { + constructUrlNonStandardPortAndNoPortInConfigTest("https://www.myserver.com"); + } + + public void testConstructUrlWithMultipleHostsNoPortsOrProtocol() { + final var CONST_MY_URL = "https://www.myserver.com/hello/hithere/"; + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.addHeader("Host", "www.myserver.com"); + request.setScheme("https"); + request.setSecure(true); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, + "www.amazon.com www.bestbuy.com www.myserver.com", "service", "ticket", false); + assertEquals(CONST_MY_URL, constructedUrl); + } + + public void testConstructURlWithMultipleHostsAndPorts() { + final var CONST_MY_URL = "https://www.myserver.com/hello/hithere/"; + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.addHeader("Host", "www.myserver.com"); + request.setScheme("https"); + request.setSecure(true); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, + "http://www.amazon.com https://www.bestbuy.com https://www.myserver.com", "service", "ticket", false); + assertEquals(CONST_MY_URL, constructedUrl); + } + + public void testUrlEncodeWithQueryParameters() { + final var request = new MockHttpServletRequest("GET", "/idp/authN/ExtCas"); + request.setQueryString("conversation=e1s1&ticket=ST-1234-123456789-a&entityId=https://test.edu/sp?alias=1234-1234-1234-1234&something=else"); + request.addHeader("Host", "www.myserver.com"); + request.setScheme("https"); + request.setSecure(true); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, + "https://my.server.com", + "service", "ticket", false); + assertEquals("https://my.server.com/idp/authN/ExtCas?conversation=e1s1&entityId=https://test.edu/sp?alias=1234-1234-1234-1234&something=else", + constructedUrl); + } + + private static void constructUrlNonStandardPortAndNoPortInConfigTest(final String serverNameList) { + final var CONST_MY_URL = "https://www.myserver.com:555/hello/hithere/"; + final var request = new MockHttpServletRequest("GET", "/hello/hithere/"); + request.addHeader("Host", "www.myserver.com"); + request.setScheme("https"); + request.setSecure(true); + request.setServerPort(555); + final HttpServletResponse response = new MockHttpServletResponse(); + final var constructedUrl = WebUtils.constructServiceUrl(request, response, null, + serverNameList, "service", "ticket", false); + assertEquals(CONST_MY_URL, constructedUrl); + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/AbstractTicketValidatorTests.java similarity index 91% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/AbstractTicketValidatorTests.java index 388800c11..0af513a24 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/AbstractTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/AbstractTicketValidatorTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; /** * Base class for all TicketValidator tests to inherit from. diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/AssertionImplTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/AssertionImplTests.java similarity index 88% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/AssertionImplTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/AssertionImplTests.java index 73bbf7180..ff7998b11 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/AssertionImplTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/AssertionImplTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; + +import junit.framework.TestCase; import java.util.Date; import java.util.HashMap; import java.util.Map; -import junit.framework.TestCase; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; /** * Test cases for the {@link AssertionImpl}. @@ -35,7 +37,7 @@ public final class AssertionImplTests extends TestCase { private static final AttributePrincipal CONST_PRINCIPAL = new AttributePrincipalImpl("test"); - private static final Map CONST_ATTRIBUTES = new HashMap(); + private static final Map CONST_ATTRIBUTES = new HashMap<>(); static { CONST_ATTRIBUTES.put("test", "test"); @@ -53,7 +55,7 @@ public void testAssertionValidity() throws Exception { final Assertion assertion = new AssertionImpl(CONST_PRINCIPAL, new Date(), new Date(), new Date(), CONST_ATTRIBUTES); assertTrue(assertion.isValid()); } - + public void testCompleteConstructor() { final Assertion assertion = new AssertionImpl(CONST_PRINCIPAL, CONST_ATTRIBUTES); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas10TicketValidationFilterTests.java similarity index 75% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas10TicketValidationFilterTests.java index edb49c947..3e23e2d40 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidationFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas10TicketValidationFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import org.junit.Test; import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockServletContext; +import jakarta.servlet.FilterConfig; + +import static org.junit.Assert.*; + /** * Unit test for {@link Cas10TicketValidationFilter}. * @@ -32,8 +34,8 @@ public class Cas10TicketValidationFilterTests { @Test public void testThrowsRenewInitParam() throws Exception { - final Cas10TicketValidationFilter f = new Cas10TicketValidationFilter(); - final MockFilterConfig config = new MockFilterConfig(); + final var f = new Cas10TicketValidationFilter(); + final var config = new MockFilterConfig(); config.addInitParameter("casServerUrlPrefix", "https://cas.example.com"); config.addInitParameter("renew", "true"); try { @@ -46,15 +48,15 @@ public void testThrowsRenewInitParam() throws Exception { @Test public void testAllowsRenewContextParam() throws Exception { - final Cas10TicketValidationFilter f = new Cas10TicketValidationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new Cas10TicketValidationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerUrlPrefix", "https://cas.example.com"); context.addInitParameter("renew", "true"); context.addInitParameter("service", "http://www.jasig.org"); - final MockFilterConfig config = new MockFilterConfig(context); + final FilterConfig config = new MockFilterConfig(context); f.init(config); - final TicketValidator validator = f.getTicketValidator(config); + final var validator = f.getTicketValidator(config); assertTrue(validator instanceof Cas10TicketValidator); assertTrue(((Cas10TicketValidator) validator).isRenew()); } -} \ No newline at end of file +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas10TicketValidatorTests.java similarity index 80% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas10TicketValidatorTests.java index 1bcb40d54..3ec925455 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas10TicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas10TicketValidatorTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.PublicTestHttpServer; -import static org.junit.Assert.*; -import java.io.UnsupportedEncodingException; -import org.jasig.cas.client.PublicTestHttpServer; import org.junit.Before; import org.junit.Test; +import java.io.UnsupportedEncodingException; + +import static org.junit.Assert.*; + /** * Test cases for the {@link Cas10TicketValidator}. * @@ -33,6 +36,7 @@ public final class Cas10TicketValidatorTests extends AbstractTicketValidatorTests { private static final int PORT = 8989; + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(PORT); private Cas10TicketValidator ticketValidator; @@ -65,7 +69,7 @@ public void testNoResponse() throws Exception { @Test public void testYesResponse() throws TicketValidationException, UnsupportedEncodingException { server.content = "yes\nusername\n\n".getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("testTicket", "myService"); + final var assertion = this.ticketValidator.validate("testTicket", "myService"); assertEquals(CONST_USERNAME, assertion.getPrincipal().getName()); } @@ -82,11 +86,12 @@ public void testBadResponse() throws UnsupportedEncodingException { @Test public void urlEncodedValues() { - final String ticket = "ST-1-owKEOtYJjg77iHcCQpkl-cas01.example.org%26%73%65%72%76%69%63%65%3d%68%74%74%70%25%33%41%25%32%46%25%32%46%31%32%37%2e%30%2e%30%2e%31%25%32%46%62%6f%72%69%6e%67%25%32%46%23"; - final String service = "foobar"; - final String url = this.ticketValidator.constructValidationUrl(ticket, service); + final var ticket = + "ST-1-owKEOtYJjg77iHcCQpkl-cas01.example.org%26%73%65%72%76%69%63%65%3d%68%74%74%70%25%33%41%25%32%46%25%32%46%31%32%37%2e%30%2e%30%2e%31%25%32%46%62%6f%72%69%6e%67%25%32%46%23"; + final var service = "foobar"; + final var url = this.ticketValidator.constructValidationUrl(ticket, service); - final String encodedValue = this.ticketValidator.encodeUrl(ticket); + final var encodedValue = AbstractUrlBasedTicketValidator.encodeUrl(ticket); assertTrue(url.contains(encodedValue)); assertFalse(url.contains(ticket)); } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java similarity index 66% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java index e167fcbbc..d5bf3f558 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,21 +16,25 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.proxy.CleanUpTimerTask; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.util.MethodFlag; -import java.util.Timer; -import java.util.TimerTask; import junit.framework.TestCase; -import org.jasig.cas.client.proxy.CleanUpTimerTask; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl; -import org.jasig.cas.client.util.MethodFlag; import org.junit.Test; import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockServletContext; +import jakarta.servlet.FilterConfig; + +import java.util.Timer; +import java.util.TimerTask; + /** - * Unit test for {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter} + * Unit test for {@link Cas20ProxyReceivingTicketValidationFilter} * * @author Brad Cupit (brad [at] lsu {dot} edu) */ @@ -43,10 +47,10 @@ public class Cas20ProxyReceivingTicketValidationFilterTests extends TestCase { private final CleanUpTimerTask defaultTimerTask = new CleanUpTimerTask(storage); public void testStartsThreadAtStartup() throws Exception { - final MethodFlag scheduleMethodFlag = new MethodFlag(); - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var scheduleMethodFlag = new MethodFlag(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); - final Timer timer = new Timer(true) { + final var timer = new Timer(true) { @Override public void schedule(final TimerTask task, final long delay, final long period) { scheduleMethodFlag.setCalled(); @@ -63,10 +67,10 @@ public void schedule(final TimerTask task, final long delay, final long period) } public void testShutsDownTimerThread() throws Exception { - final MethodFlag cancelMethodFlag = new MethodFlag(); - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var cancelMethodFlag = new MethodFlag(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); - final Timer timer = new Timer(true) { + final var timer = new Timer(true) { @Override public void cancel() { cancelMethodFlag.setCalled(); @@ -85,17 +89,17 @@ public void cancel() { } public void testCallsCleanAllOnSchedule() throws Exception { - final MethodFlag timerTaskFlag = new MethodFlag(); - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var timerTaskFlag = new MethodFlag(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); - final TimerTask timerTask = new TimerTask() { + final var timerTask = new TimerTask() { @Override public void run() { timerTaskFlag.setCalled(); } }; - final int millisBetweenCleanUps = 250; + final var millisBetweenCleanUps = 250; filter.setProxyGrantingTicketStorage(storage); filter.setTimerTask(timerTask); filter.setTimer(defaultTimer); @@ -111,17 +115,17 @@ public void run() { } public void testDelaysFirstCleanAll() throws Exception { - final MethodFlag timerTaskFlag = new MethodFlag(); - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var timerTaskFlag = new MethodFlag(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); - final TimerTask timerTask = new TimerTask() { + final var timerTask = new TimerTask() { @Override public void run() { timerTaskFlag.setCalled(); } }; - final int millisBetweenCleanUps = 250; + final var millisBetweenCleanUps = 250; filter.setProxyGrantingTicketStorage(storage); filter.setMillisBetweenCleanUps(millisBetweenCleanUps); filter.setTimer(defaultTimer); @@ -140,7 +144,7 @@ public void run() { } public void testThrowsForNullStorage() throws Exception { - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); filter.setProxyGrantingTicketStorage(null); try { @@ -152,10 +156,10 @@ public void testThrowsForNullStorage() throws Exception { } public void testGetTicketValidator() throws Exception { - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); // Test case #1 - final MockFilterConfig config1 = new MockFilterConfig(); + final var config1 = new MockFilterConfig(); config1.addInitParameter("allowedProxyChains", "https://a.example.com"); config1.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/"); config1.addInitParameter("service", "http://www.jasig.org"); @@ -165,9 +169,9 @@ public void testGetTicketValidator() throws Exception { @Test public void getTicketValidatorWithProxyChains() throws Exception { - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); // Test case #2 - final MockFilterConfig config2 = new MockFilterConfig(); + final var config2 = new MockFilterConfig(); config2.addInitParameter("allowedProxyChains", "https://a.example.com https://b.example.com"); config2.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/"); config2.addInitParameter("service", "http://www.jasig.org"); @@ -178,12 +182,12 @@ public void getTicketValidatorWithProxyChains() throws Exception { @Test public void getTIcketValidatorWithProxyChainsAndLineBreak() throws Exception { - final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter(); + final var filter = newCas20ProxyReceivingTicketValidationFilter(); // Test case #3 - final MockFilterConfig config3 = new MockFilterConfig(); + final var config3 = new MockFilterConfig(); config3.addInitParameter("allowedProxyChains", - "https://a.example.com https://b.example.com\nhttps://c.example.com"); + "https://a.example.com https://b.example.com\nhttps://c.example.com"); config3.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/"); config3.addInitParameter("service", "http://www.jasig.org"); filter.init(config3); @@ -191,8 +195,8 @@ public void getTIcketValidatorWithProxyChainsAndLineBreak() throws Exception { } public void testRenewInitParamThrows() throws Exception { - final Cas20ProxyReceivingTicketValidationFilter f = new Cas20ProxyReceivingTicketValidationFilter(); - final MockFilterConfig config = new MockFilterConfig(); + final var f = new Cas20ProxyReceivingTicketValidationFilter(); + final var config = new MockFilterConfig(); config.addInitParameter("casServerUrlPrefix", "https://cas.example.com"); config.addInitParameter("renew", "true"); try { @@ -204,23 +208,23 @@ public void testRenewInitParamThrows() throws Exception { } public void testAllowsRenewContextParam() throws Exception { - final Cas20ProxyReceivingTicketValidationFilter f = new Cas20ProxyReceivingTicketValidationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new Cas20ProxyReceivingTicketValidationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerUrlPrefix", "https://cas.example.com"); context.addInitParameter("renew", "true"); context.addInitParameter("service", "http://www.jasig.org"); - final MockFilterConfig config = new MockFilterConfig(context); + final FilterConfig config = new MockFilterConfig(context); f.init(config); - final TicketValidator validator = f.getTicketValidator(config); + final var validator = f.getTicketValidator(config); assertTrue(validator instanceof AbstractUrlBasedTicketValidator); assertTrue(((AbstractUrlBasedTicketValidator) validator).isRenew()); } /** - * construct a working {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter} + * construct a working {@link Cas20ProxyReceivingTicketValidationFilter} */ - private Cas20ProxyReceivingTicketValidationFilter newCas20ProxyReceivingTicketValidationFilter() { - final Cas20ProxyReceivingTicketValidationFilter filter = new Cas20ProxyReceivingTicketValidationFilter(); + private static Cas20ProxyReceivingTicketValidationFilter newCas20ProxyReceivingTicketValidationFilter() { + final var filter = new Cas20ProxyReceivingTicketValidationFilter(); filter.setServerName("localhost"); filter.setTicketValidator(new Cas20ProxyTicketValidator("")); diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ProxyTicketValidatorTests.java similarity index 53% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ProxyTicketValidatorTests.java index a964b9a84..4686e7af5 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ProxyTicketValidatorTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,21 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.proxy.ProxyRetriever; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl; -import org.jasig.cas.client.proxy.ProxyRetriever; import org.junit.Before; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; +import java.io.Serial; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.*; + /** * Test cases for the {@link Cas20ProxyTicketValidator}. * @@ -54,8 +57,8 @@ public static void classCleanUp() { @Before public void setUp() throws Exception { - final List list = new ArrayList(); - list.add(new String[] { "proxy1", "proxy2", "proxy3" }); + final List list = new ArrayList<>(); + list.add(new String[]{"proxy1", "proxy2", "proxy3"}); this.ticketValidator = new Cas20ProxyTicketValidator(CONST_CAS_SERVER_URL_PREFIX + "8089"); this.ticketValidator.setRenew(true); @@ -65,36 +68,21 @@ public void setUp() throws Exception { this.ticketValidator.setAllowedProxyChains(new ProxyList(list)); } - private ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return new ProxyGrantingTicketStorageImpl(); - } - - private ProxyRetriever getProxyRetriever() { - return new ProxyRetriever() { - - /** Unique Id For serialization. */ - private static final long serialVersionUID = 1L; - - @Override - public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { - return "test"; - } - }; - } - @Test public void testProxyChainWithValidProxy() throws TicketValidationException, UnsupportedEncodingException { - final String USERNAME = "username"; - final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3"; + final var USERNAME = "username"; + final var RESPONSE = + "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3"; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); } @Test public void testProxyChainWithInvalidProxy() throws TicketValidationException, UnsupportedEncodingException { - final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy7proxy2proxy3"; + final var RESPONSE = + "usernamePGTIOU-84678-8a9d...proxy7proxy2proxy3"; server.content = RESPONSE.getBytes(server.encoding); try { @@ -107,27 +95,29 @@ public void testProxyChainWithInvalidProxy() throws TicketValidationException, U @Test public void testRegexProxyChainWithValidProxy() throws TicketValidationException, UnsupportedEncodingException { - final List list = new ArrayList(); - list.add(new String[] { "proxy1", "proxy2", "^proxy3/[a-z]*/" }); + final List list = new ArrayList<>(); + list.add(new String[]{"proxy1", "proxy2", "^proxy3/[a-z]*/"}); this.ticketValidator.setAllowedProxyChains(new ProxyList(list)); - - final String USERNAME = "username"; - final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3/abc/"; + + final var USERNAME = "username"; + final var RESPONSE = + "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3/abc/"; server.content = RESPONSE.getBytes(server.encoding); - - final Assertion assertion = this.ticketValidator.validate("test", "test"); + + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); } - + @Test public void testRegexProxyChainWithInvalidProxy() throws TicketValidationException, UnsupportedEncodingException { - final List list = new ArrayList(); - list.add(new String[] { "proxy1", "proxy2", "^proxy3/[a-z]*/" }); + final List list = new ArrayList<>(); + list.add(new String[]{"proxy1", "proxy2", "^proxy3/[a-z]*/"}); this.ticketValidator.setAllowedProxyChains(new ProxyList(list)); - - final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3/ABC/"; + + final var RESPONSE = + "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3/ABC/"; server.content = RESPONSE.getBytes(server.encoding); - + try { this.ticketValidator.validate("test", "test"); fail("Invalid proxy chain"); @@ -135,19 +125,38 @@ public void testRegexProxyChainWithInvalidProxy() throws TicketValidationExcepti // expected } } - + @Test public void testConstructionFromSpringBean() throws TicketValidationException, UnsupportedEncodingException { - final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( - "classpath:cas20ProxyTicketValidator.xml"); - final Cas20ProxyTicketValidator v = (Cas20ProxyTicketValidator) context.getBean("proxyTicketValidator"); + final var context = new ClassPathXmlApplicationContext( + "classpath:cas20ProxyTicketValidator.xml"); + final TicketValidator v = (Cas20ProxyTicketValidator) context.getBean("proxyTicketValidator"); - final String USERNAME = "username"; - final String RESPONSE = "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3"; + final var USERNAME = "username"; + final var RESPONSE = + "usernamePGTIOU-84678-8a9d...proxy1proxy2proxy3"; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = v.validate("test", "test"); + final var assertion = v.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); } + + private static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { + return new ProxyGrantingTicketStorageImpl(); + } + + private static ProxyRetriever getProxyRetriever() { + return new ProxyRetriever() { + + /** Unique Id For serialization. */ + @Serial + private static final long serialVersionUID = 1L; + + @Override + public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { + return "test"; + } + }; + } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ServiceTicketValidatorTests.java similarity index 56% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ServiceTicketValidatorTests.java index 569b8e9fd..7590313c1 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ServiceTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas20ServiceTicketValidatorTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,19 +16,26 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import static org.junit.Assert.*; +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.authentication.AttributePrincipal; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.proxy.ProxyRetriever; + +import org.junit.Before; +import org.junit.Test; + +import java.io.Serial; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; +import java.security.Principal; +import java.util.Collection; import java.util.List; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl; -import org.jasig.cas.client.proxy.ProxyRetriever; -import org.junit.Before; -import org.junit.Test; + +import static org.junit.Assert.*; /** * Test cases for the {@link Cas20ServiceTicketValidator}. @@ -39,10 +46,15 @@ public final class Cas20ServiceTicketValidatorTests extends AbstractTicketValidatorTests { private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8088); + private static final String USERNAME = "username"; + private static final String PGTIOU = "PGTIOU-1-test"; + private static final String PGT = "PGT-1-ixcY6jtRXZ4OrJ39SadtLEcTLsGNhE8-NYtvDTK3kk5iAEdatRcnGrGjLckOwK8xU6ocastest"; - private static final String ENCRYPTED_PGT = "H3wqFQLBlvhbrPVo4yrwIF9p8yJhCfzHnLHgTWTYVw42sLDJj7c3PBFHKgZfaY9l57qDbKA0fZY979GGFFgnSz1VOOlTgVRi/nmbpwlScRLHP8qUf2JGUyhu0+nTRp6TcQiEqpf5iquXNyQ9UXPyWPdTM/YtgtYtcIOzMovjN5c="; + + private static final String ENCRYPTED_PGT = + "H3wqFQLBlvhbrPVo4yrwIF9p8yJhCfzHnLHgTWTYVw42sLDJj7c3PBFHKgZfaY9l57qDbKA0fZY979GGFFgnSz1VOOlTgVRi/nmbpwlScRLHP8qUf2JGUyhu0+nTRp6TcQiEqpf5iquXNyQ9UXPyWPdTM/YtgtYtcIOzMovjN5c="; private Cas20ServiceTicketValidator ticketValidator; @@ -68,22 +80,10 @@ public void setUp() throws Exception { proxyGrantingTicketField.setAccessible(true); } - private ProxyRetriever getProxyRetriever() { - return new ProxyRetriever() { - - /** Unique Id for serialization. */ - private static final long serialVersionUID = 1L; - - @Override - public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { - return "test"; - } - }; - } - @Test public void testNoResponse() throws UnsupportedEncodingException { - final String RESPONSE = "Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized"; + final var RESPONSE = + "Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized"; server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); @@ -95,49 +95,49 @@ public void testNoResponse() throws UnsupportedEncodingException { @Test public void testYesResponseButNoPgtiou() throws TicketValidationException, UnsupportedEncodingException { - final String RESPONSE = "" - + USERNAME + ""; + final var RESPONSE = "" + + USERNAME + ""; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); } @Test public void testYesResponseWithPgtiou() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException { - final String RESPONSE = "" - + USERNAME - + "" - + PGTIOU - + ""; + final var RESPONSE = "" + + USERNAME + + "" + + PGTIOU + + ""; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); - final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal(); + final var assertion = this.ticketValidator.validate("test", "test"); + final Principal principal = (AttributePrincipalImpl) assertion.getPrincipal(); assertEquals(USERNAME, principal.getName()); assertEquals(PGT, proxyGrantingTicketField.get(principal)); } @Test public void testGetAttributes() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException { - final String RESPONSE = "" - + USERNAME - + "" - + PGTIOU - + "testidtest1\n\ntestvalue1value2"; + final var RESPONSE = "" + + USERNAME + + "" + + PGTIOU + + "testidtest1\n\ntestvalue1value2"; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); - final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal(); + final var assertion = this.ticketValidator.validate("test", "test"); + final AttributePrincipal principal = (AttributePrincipalImpl) assertion.getPrincipal(); assertEquals(USERNAME, principal.getName()); assertEquals("test", principal.getAttributes().get("password")); assertEquals("id", principal.getAttributes().get("eduPersonId")); assertEquals("test1\n\ntest", principal.getAttributes().get("longAttribute")); try { - final List multivalued = (List) principal.getAttributes().get("multivaluedAttribute"); - assertArrayEquals(new String[] { "value1", "value2" }, multivalued.toArray()); + final Collection multivalued = (List) principal.getAttributes().get("multivaluedAttribute"); + assertArrayEquals(new String[]{"value1", "value2"}, multivalued.toArray()); } catch (final Exception e) { fail("'multivaluedAttribute' attribute expected as List object."); } @@ -146,41 +146,41 @@ public void testGetAttributes() throws TicketValidationException, UnsupportedEnc @Test public void testYesResponseWithEncryptedPgt() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException { - final String RESPONSE = "" - + USERNAME - + "" - + ENCRYPTED_PGT - + ""; + final var RESPONSE = "" + + USERNAME + + "" + + ENCRYPTED_PGT + + ""; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); - final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal(); + final var assertion = this.ticketValidator.validate("test", "test"); + final Principal principal = (AttributePrincipalImpl) assertion.getPrincipal(); assertEquals(USERNAME, principal.getName()); assertEquals(PGT, proxyGrantingTicketField.get(principal)); } @Test public void testYesResponseWithPgtiouAndEncryptedPgt() throws TicketValidationException, UnsupportedEncodingException, IllegalAccessException { - final String RESPONSE = "" - + USERNAME - + "" - + PGTIOU - + "" - + ENCRYPTED_PGT - + ""; + final var RESPONSE = "" + + USERNAME + + "" + + PGTIOU + + "" + + ENCRYPTED_PGT + + ""; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); - final AttributePrincipalImpl principal = (AttributePrincipalImpl) assertion.getPrincipal(); + final var assertion = this.ticketValidator.validate("test", "test"); + final Principal principal = (AttributePrincipalImpl) assertion.getPrincipal(); assertEquals(USERNAME, principal.getName()); assertEquals(PGT, proxyGrantingTicketField.get(principal)); } @Test public void testInvalidResponse() throws Exception { - final String RESPONSE = ""; + final var RESPONSE = ""; server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); @@ -189,4 +189,18 @@ public void testInvalidResponse() throws Exception { // expected } } + + private static ProxyRetriever getProxyRetriever() { + return new ProxyRetriever() { + + /** Unique Id for serialization. */ + @Serial + private static final long serialVersionUID = 1L; + + @Override + public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { + return "test"; + } + }; + } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas30ServiceTicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas30ServiceTicketValidatorTests.java similarity index 57% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas30ServiceTicketValidatorTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas30ServiceTicketValidatorTests.java index 41b045a7b..8daf6316b 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas30ServiceTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/Cas30ServiceTicketValidatorTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,16 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; + +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.proxy.ProxyRetriever; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl; -import org.jasig.cas.client.proxy.ProxyRetriever; import org.junit.Before; import org.junit.Test; +import java.io.Serial; import java.io.UnsupportedEncodingException; +import java.util.Collection; import java.util.List; import static org.junit.Assert.*; @@ -58,26 +61,10 @@ public void setUp() throws Exception { this.ticketValidator.setRenew(true); } - private ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return new ProxyGrantingTicketStorageImpl(); - } - - private ProxyRetriever getProxyRetriever() { - return new ProxyRetriever() { - - /** Unique Id for serialization. */ - private static final long serialVersionUID = 1L; - - @Override - public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { - return "test"; - } - }; - } - @Test public void testNoResponse() throws UnsupportedEncodingException { - final String RESPONSE = "Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized"; + final var RESPONSE = + "Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized"; server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); @@ -89,54 +76,54 @@ public void testNoResponse() throws UnsupportedEncodingException { @Test public void testYesResponseButNoPgt() throws TicketValidationException, UnsupportedEncodingException { - final String USERNAME = "username"; - final String RESPONSE = "" - + USERNAME + ""; + final var USERNAME = "username"; + final var RESPONSE = "" + + USERNAME + ""; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); } @Test public void testYesResponseWithPgt() throws TicketValidationException, UnsupportedEncodingException { - final String USERNAME = "username"; - final String PGTIOU = "testPgtIou"; - final String PGT = "test"; - final String RESPONSE = "" - + USERNAME - + "" - + PGTIOU - + ""; + final var USERNAME = "username"; + final var PGTIOU = "testPgtIou"; + final var PGT = "test"; + final var RESPONSE = "" + + USERNAME + + "" + + PGTIOU + + ""; server.content = RESPONSE.getBytes(server.encoding); this.proxyGrantingTicketStorage.save(PGTIOU, PGT); - final Assertion assertion = this.ticketValidator.validate("test", "test"); + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); // assertEquals(PGT, assertion.getProxyGrantingTicketId()); } @Test public void testGetAttributes() throws TicketValidationException, UnsupportedEncodingException { - final String USERNAME = "username"; - final String PGTIOU = "testPgtIou"; - final String RESPONSE = "" - + USERNAME - + "" - + PGTIOU - + "testidtest1\n\ntestvalue1value2"; + final var USERNAME = "username"; + final var PGTIOU = "testPgtIou"; + final var RESPONSE = "" + + USERNAME + + "" + + PGTIOU + + "testidtest1\n\ntestvalue1value2"; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); assertEquals("test", assertion.getPrincipal().getAttributes().get("password")); assertEquals("id", assertion.getPrincipal().getAttributes().get("eduPersonId")); assertEquals("test1\n\ntest", assertion.getPrincipal().getAttributes().get("longAttribute")); try { - final List multivalued = (List) assertion.getPrincipal().getAttributes().get("multivaluedAttribute"); - assertArrayEquals(new String[] { "value1", "value2" }, multivalued.toArray()); + final Collection multivalued = (List) assertion.getPrincipal().getAttributes().get("multivaluedAttribute"); + assertArrayEquals(new String[]{"value1", "value2"}, multivalued.toArray()); } catch (final Exception e) { fail("'multivaluedAttribute' attribute expected as List object."); } @@ -145,23 +132,23 @@ public void testGetAttributes() throws TicketValidationException, UnsupportedEnc @Test public void testGetInlinedAttributes() throws TicketValidationException, UnsupportedEncodingException { - final String USERNAME = "username"; - final String PGTIOU = "testPgtIou"; - final String RESPONSE = "" - + USERNAME - + "" - + PGTIOU - + ""; + final var USERNAME = "username"; + final var PGTIOU = "testPgtIou"; + final var RESPONSE = "" + + USERNAME + + "" + + PGTIOU + + ""; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = this.ticketValidator.validate("test", "test"); + final var assertion = this.ticketValidator.validate("test", "test"); assertEquals(USERNAME, assertion.getPrincipal().getName()); assertEquals("test", assertion.getPrincipal().getAttributes().get("password")); assertEquals("id", assertion.getPrincipal().getAttributes().get("eduPersonId")); assertEquals("test1\n\ntest", assertion.getPrincipal().getAttributes().get("longAttribute")); try { - final List multivalued = (List) assertion.getPrincipal().getAttributes().get("multivaluedAttribute"); - assertArrayEquals(new String[] { "value1", "value2" }, multivalued.toArray()); + final Collection multivalued = (List) assertion.getPrincipal().getAttributes().get("multivaluedAttribute"); + assertArrayEquals(new String[]{"value1", "value2"}, multivalued.toArray()); } catch (final Exception e) { fail("'multivaluedAttribute' attribute expected as List object."); } @@ -170,7 +157,7 @@ public void testGetInlinedAttributes() throws TicketValidationException, Unsuppo @Test public void testInvalidResponse() throws Exception { - final String RESPONSE = ""; + final var RESPONSE = ""; server.content = RESPONSE.getBytes(server.encoding); try { this.ticketValidator.validate("test", "test"); @@ -179,4 +166,22 @@ public void testInvalidResponse() throws Exception { // expected } } + + private static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { + return new ProxyGrantingTicketStorageImpl(); + } + + private static ProxyRetriever getProxyRetriever() { + return new ProxyRetriever() { + + /** Unique Id for serialization. */ + @Serial + private static final long serialVersionUID = 1L; + + @Override + public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { + return "test"; + } + }; + } } diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/json/Cas30JsonServiceTicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/json/Cas30JsonServiceTicketValidatorTests.java similarity index 57% rename from cas-client-core/src/test/java/org/jasig/cas/client/validation/json/Cas30JsonServiceTicketValidatorTests.java rename to cas-client-core/src/test/java/org/apereo/cas/client/validation/json/Cas30JsonServiceTicketValidatorTests.java index eb0ea9c57..b123990e3 100644 --- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/json/Cas30JsonServiceTicketValidatorTests.java +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/json/Cas30JsonServiceTicketValidatorTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,18 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation.json; - -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl; -import org.jasig.cas.client.proxy.ProxyRetriever; -import org.jasig.cas.client.validation.AbstractTicketValidatorTests; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.TicketValidationException; +package org.apereo.cas.client.validation.json; + +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.proxy.ProxyRetriever; +import org.apereo.cas.client.validation.AbstractTicketValidatorTests; +import org.apereo.cas.client.validation.TicketValidationException; + +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.junit.Assert; + +import java.io.Serial; public class Cas30JsonServiceTicketValidatorTests extends AbstractTicketValidatorTests { private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8088); @@ -43,65 +45,65 @@ public void setUp() throws Exception { this.ticketValidator.setRenew(true); } - private ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return new ProxyGrantingTicketStorageImpl(); - } - - private ProxyRetriever getProxyRetriever() { - return new ProxyRetriever() { - - /** Unique Id for serialization. */ - private static final long serialVersionUID = 1L; - - @Override - public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { - return "test"; - } - }; - } - @Test public void testSuccessfulJsonResponse() throws Exception { - final String RESPONSE = "{ " + - "\"serviceResponse\" : { " + - "\"authenticationSuccess\" : { " + - "\"user\" : \"casuser\", " + - "\"proxyGrantingTicket\" : \"PGTIOU-84678-8a9d\" ," + - "\"attributes\" : { " + - "\"cn\" : [ \"Name\" ] " + - '}' + - '}' + - '}' + - '}'; + final var RESPONSE = "{ " + + "\"serviceResponse\" : { " + + "\"authenticationSuccess\" : { " + + "\"user\" : \"casuser\", " + + "\"proxyGrantingTicket\" : \"PGTIOU-84678-8a9d\" ," + + "\"attributes\" : { " + + "\"cn\" : [ \"Name\" ] " + + '}' + + '}' + + '}' + + '}'; server.content = RESPONSE.getBytes(server.encoding); - final Assertion assertion = ticketValidator.validate("test", "test"); + final var assertion = ticketValidator.validate("test", "test"); Assert.assertEquals(assertion.getPrincipal().getName(), "casuser"); Assert.assertTrue(assertion.getPrincipal().getAttributes().containsKey("cn")); } @Test(expected = TicketValidationException.class) public void testFailingJsonResponse() throws Exception { - final String RESPONSE = "{ " + - "\"serviceResponse\" : { " + - "\"authenticationFailure\" : { " + - "\"code\" : \"INVALID_TICKET\", " + - "\"description\" : \"Description\" " + - '}' + - '}' + - '}'; + final var RESPONSE = "{ " + + "\"serviceResponse\" : { " + + "\"authenticationFailure\" : { " + + "\"code\" : \"INVALID_TICKET\", " + + "\"description\" : \"Description\" " + + '}' + + '}' + + '}'; server.content = RESPONSE.getBytes(server.encoding); ticketValidator.validate("test", "test"); } - @Test public void testSuccessfulXmlResponseWithJson() throws Exception { - final String RESPONSE = "" - + "testPGTIOU"; + final var RESPONSE = "" + + "testPGTIOU"; server.content = RESPONSE.getBytes(server.encoding); ticketValidator.validate("test", "test"); } + + private static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { + return new ProxyGrantingTicketStorageImpl(); + } + + private static ProxyRetriever getProxyRetriever() { + return new ProxyRetriever() { + + /** Unique Id for serialization. */ + @Serial + private static final long serialVersionUID = 1L; + + @Override + public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) { + return "test"; + } + }; + } } diff --git a/cas-client-core/src/test/java/org/apereo/cas/client/validation/jwt/CasJWTSignatureBypassTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/jwt/CasJWTSignatureBypassTests.java new file mode 100644 index 000000000..0a26f885f --- /dev/null +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/jwt/CasJWTSignatureBypassTests.java @@ -0,0 +1,150 @@ +package org.apereo.cas.client.validation.jwt; + +import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWEAlgorithm; +import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.crypto.DirectEncrypter; +import com.nimbusds.jwt.EncryptedJWT; +import com.nimbusds.jwt.JWTClaimsSet; +import org.apereo.cas.client.validation.TicketValidationException; +import org.junit.Test; + +import java.util.Base64; +import java.util.Date; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Tests demonstrating signature verification bypass in CasJWTProcessor + * when processing JWE tokens with unsigned payloads. + * + * @see CasJWTTicketValidator + */ +public class CasJWTSignatureBypassTests { + + private static final String ENCRYPTION_KEY = "GR7E6uL9djKBSH59BN8boYQ68gQgzwehIIp6s1QicPc"; + private static final String SIGNING_KEY = "vTRQaUu8oDlMrsuhsgNgtk6yie2O6XwRsnDS1POstAQkA1_5TI8-mwrqo1wQ1VahGXLgjCtOb9PLOplmvFzvQA"; + private static final String ISSUER = "https://cas.example.org:8443/cas"; + private static final String AUDIENCE = "https://github.com/apereo/cas"; + + private static CasJWTTicketValidator getValidator() { + var validator = new CasJWTTicketValidator(); + validator.setEncryptionKey(ENCRYPTION_KEY); + validator.setSigningKey(SIGNING_KEY); + validator.setExpectedIssuer(ISSUER); + validator.setExpectedAudience(AUDIENCE); + validator.setMaxClockSkew(Integer.MAX_VALUE); + return validator; + } + + private static JWTClaimsSet forgedClaims() { + return new JWTClaimsSet.Builder() + .subject("attacker-forged-admin") + .issuer(ISSUER) + .audience(AUDIENCE) + .jwtID(UUID.randomUUID().toString()) + .issueTime(new Date()) + .expirationTime(new Date(System.currentTimeMillis() + 3600000)) + .claim("authenticationMethod", "Forged") + .claim("role", "ROLE_ADMIN") + .build(); + } + + private static byte[] getEncryptionKeyBytes() { + return Base64.getDecoder().decode(ENCRYPTION_KEY); + } + + /** + * Vector 1: JWE with cty="JWT" containing raw JSON claims (no nested JWS). + *

+ * toSignedJWT() returns null because the payload is raw JSON, not a signed JWT. + * The current code checks if payload is valid JSON and falls through to return + * the unsigned claims. This SHOULD throw BadJWTException. + */ + @Test + public void rejectJweWithCtyJwtButNoNestedSignature() throws Exception { + var keyBytes = getEncryptionKeyBytes(); + + var header = new JWEHeader.Builder(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256) + .contentType("JWT") + .type(JOSEObjectType.JWT) + .build(); + + var encJwt = new EncryptedJWT(header, forgedClaims()); + encJwt.encrypt(new DirectEncrypter(keyBytes)); + var forgedToken = encJwt.serialize(); + + var validator = getValidator(); + try { + var assertion = validator.validate(forgedToken, "https://example.org"); + fail("JWE with cty=JWT but no nested signed JWT should be rejected. " + + "Got subject: " + assertion.getPrincipal().getName()); + } catch (TicketValidationException e) { + // Expected: signature verification bypass should be blocked + assertTrue("Should reject unsigned nested payload", + e.getMessage().contains("not a nested signed JWT") + || e.getCause().getMessage().contains("not a nested signed JWT")); + } + } + + /** + * Vector 1 with attacker-controlled claims: demonstrates full identity forgery. + *

+ * The forged claims include a subject, issuer, and audience that match the + * validator's expected values. The claims verifier passes because the values + * are correct — the only missing piece is the cryptographic signature, which + * is never checked. + */ + @Test + public void rejectForgedIdentityInJweWithCtyJwt() throws Exception { + var keyBytes = getEncryptionKeyBytes(); + + var attackerClaims = new JWTClaimsSet.Builder() + .subject("admin") + .issuer(ISSUER) + .audience(AUDIENCE) + .jwtID(UUID.randomUUID().toString()) + .issueTime(new Date()) + .expirationTime(new Date(System.currentTimeMillis() + 3600000)) + .claim("role", "ROLE_ADMIN") + .claim("clientIpAddress", "10.0.0.1") + .build(); + + var header = new JWEHeader.Builder(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256) + .contentType("JWT") + .type(JOSEObjectType.JWT) + .build(); + + var encJwt = new EncryptedJWT(header, attackerClaims); + encJwt.encrypt(new DirectEncrypter(keyBytes)); + var forgedToken = encJwt.serialize(); + + var validator = getValidator(); + try { + var assertion = validator.validate(forgedToken, "https://example.org"); + fail("Forged identity in unsigned JWE should be rejected. " + + "Attacker authenticated as: " + assertion.getPrincipal().getName() + + " with role: " + assertion.getPrincipal().getAttributes().get("role")); + } catch (TicketValidationException e) { + // Expected: forged claims without signature should be blocked + } + } + + /** + * Sanity check: the existing signed-then-encrypted token from the test suite + * should continue to validate successfully after the fix. + */ + @Test + public void existingSignedAndEncryptedJwtStillValidates() throws Exception { + var validator = getValidator(); + var jwt = "eyJ6aXAiOiJERUYiLCJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiY3R5IjoiSldUIiwidHlwIjoiSldUIiwia2lkIjoiNGQ4NjExN2YtZWMyZC00MTY1LThjNDYtY2QyYWI0MDdhYTA5Iiwib3JnLmFwZXJlby5jYXMuc2VydmljZXMuUmVnaXN0ZXJlZFNlcnZpY2UiOiIxIn0..SX4YsSHImUrnFzo5_F_lNw.viFHp1nFcP-LNZlx_ngVEg3H6TIZRRezO88cGe8iVjTG549L5ROkUCu7nCpuc8wiK6KmUQVIjzRLhlWZ3G0kkf0-zMiPT9UQxPlLRrtm0XM2_Okj3DUcK5tRi7TEEn67leDOx6sIKi3I2zA_80Ac84DPSsnuTd-EZwnOE8p3yxN3GVxIq-qzKgaTsl-eaER7fxePkOKION98OxsKiySWriu5UchOA25qpVr4eRq-JJCjPt2pC_DvFQVk_aPBAfsUpQttYvrzvOFN25ylLobQUHs9fGylEt8uAIr0l-Ai4rRyh46RiFEW74iyhUJpa5aPQkMACvRobjcAHVzuGduKMciF-65Ooa7MeDQM3H31hlq3VCu58Jv0AZbQRNz-Fwv7ICeUFQOzMZPzAq0sNi0akYqal-a5Q-mrlWwTABnb7amIP_1i5yXxdRiLlzSeMW3CrfmvKeIlH_ttr3ra3B6Hms23Zsw7qrmJSCFKyuwyGTiAYBJNWH5SjixBb2pLodg9eiQKkrSNHRAB-UE5cfSmm2hfl5yfLh8pLZe2BSr5Ul32UfoP2X3bW8GH_hQ3rbG0E-K5P2qRtDOC6p8yNd-3MwCD1tPKm27E1vAtGsiHlrfu_l2_i2RtzTSo24sF1EcKwfJDpNi9apReZQlaZOZ4vmmS1e7MZPfrQ83qvNGPjHx8-H9dbOWxLEfX0IuoeHwfc095o6gv3PA6rCHv5mlDRLXll31CeJPY8Xd0Xe9l8IzJZ_bF1idz2m-elr9-RXDZgWXgMNj69Vis0TbHUapEksgtLgxcjjA664goGJb87YF4fli6H5JmPSF_gbzW4f1KjVrXtEFHpHamdB3-3_HrW64oTwTLU1irE-5hp5lumk3o9Ixdsn4-Eqo_cXPu2ps8.WcV_CeloEdJ7O4cWDzBXAw"; + var assertion = validator.validate(jwt, "https://example.org"); + assertNotNull("Existing signed+encrypted JWT should still validate", assertion); + assertEquals("casuser", assertion.getPrincipal().getName()); + } +} diff --git a/cas-client-core/src/test/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidatorTests.java b/cas-client-core/src/test/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidatorTests.java new file mode 100644 index 000000000..b6a224174 --- /dev/null +++ b/cas-client-core/src/test/java/org/apereo/cas/client/validation/jwt/CasJWTTicketValidatorTests.java @@ -0,0 +1,47 @@ +package org.apereo.cas.client.validation.jwt; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class CasJWTTicketValidatorTests { + + private static CasJWTTicketValidator getValidator(final String url) { + var validator = new CasJWTTicketValidator(); + validator.setEncryptionKey("GR7E6uL9djKBSH59BN8boYQ68gQgzwehIIp6s1QicPc"); + validator.setSigningKey("vTRQaUu8oDlMrsuhsgNgtk6yie2O6XwRsnDS1POstAQkA1_5TI8-mwrqo1wQ1VahGXLgjCtOb9PLOplmvFzvQA"); + validator.setExpectedIssuer("https://cas.example.org:8443/cas"); + validator.setExpectedAudience(url); + validator.setMaxClockSkew(Integer.MAX_VALUE); + return validator; + } + + @Test + public void verifyAesKeyWithSignedAndEncryptedJWT() throws Exception { + var validator = getValidator("https://github.com/apereo/cas"); + var jwt = "eyJ6aXAiOiJERUYiLCJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiY3R5IjoiSldUIiwidHlwIjoiSldUIiwia2lkIjoiNGQ4NjExN2YtZWMyZC00MTY1LThjNDYtY2QyYWI0MDdhYTA5Iiwib3JnLmFwZXJlby5jYXMuc2VydmljZXMuUmVnaXN0ZXJlZFNlcnZpY2UiOiIxIn0..SX4YsSHImUrnFzo5_F_lNw.viFHp1nFcP-LNZlx_ngVEg3H6TIZRRezO88cGe8iVjTG549L5ROkUCu7nCpuc8wiK6KmUQVIjzRLhlWZ3G0kkf0-zMiPT9UQxPlLRrtm0XM2_Okj3DUcK5tRi7TEEn67leDOx6sIKi3I2zA_80Ac84DPSsnuTd-EZwnOE8p3yxN3GVxIq-qzKgaTsl-eaER7fxePkOKION98OxsKiySWriu5UchOA25qpVr4eRq-JJCjPt2pC_DvFQVk_aPBAfsUpQttYvrzvOFN25ylLobQUHs9fGylEt8uAIr0l-Ai4rRyh46RiFEW74iyhUJpa5aPQkMACvRobjcAHVzuGduKMciF-65Ooa7MeDQM3H31hlq3VCu58Jv0AZbQRNz-Fwv7ICeUFQOzMZPzAq0sNi0akYqal-a5Q-mrlWwTABnb7amIP_1i5yXxdRiLlzSeMW3CrfmvKeIlH_ttr3ra3B6Hms23Zsw7qrmJSCFKyuwyGTiAYBJNWH5SjixBb2pLodg9eiQKkrSNHRAB-UE5cfSmm2hfl5yfLh8pLZe2BSr5Ul32UfoP2X3bW8GH_hQ3rbG0E-K5P2qRtDOC6p8yNd-3MwCD1tPKm27E1vAtGsiHlrfu_l2_i2RtzTSo24sF1EcKwfJDpNi9apReZQlaZOZ4vmmS1e7MZPfrQ83qvNGPjHx8-H9dbOWxLEfX0IuoeHwfc095o6gv3PA6rCHv5mlDRLXll31CeJPY8Xd0Xe9l8IzJZ_bF1idz2m-elr9-RXDZgWXgMNj69Vis0TbHUapEksgtLgxcjjA664goGJb87YF4fli6H5JmPSF_gbzW4f1KjVrXtEFHpHamdB3-3_HrW64oTwTLU1irE-5hp5lumk3o9Ixdsn4-Eqo_cXPu2ps8.WcV_CeloEdJ7O4cWDzBXAw"; + var assertion = validator.validate(jwt, "https://example.org"); + assertEquals("casuser", assertion.getPrincipal().getName()); + assertEquals("casuser", assertion.getPrincipal().getAttributes().get("sub")); + assertEquals("Static Credentials", assertion.getPrincipal().getAttributes().get("authenticationMethod")); + assertEquals("0:0:0:0:0:0:0:1", assertion.getPrincipal().getAttributes().get("clientIpAddress")); + } + + @Test + public void verifyAesKeyWithEncryptedAndSignedJWT() throws Exception { + var validator = getValidator("jwtservice"); + var jwt = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6IjU5MDg1MmZlLWE2MWEtNDE4Ni1hYTMyLTE4ZjI1M2ViMTZmOSJ9.ZXlKNmFYQWlPaUpFUlVZaUxDSmhiR2NpT2lKa2FYSWlMQ0psYm1NaU9pSkJNVEk0UTBKRExVaFRNalUySWl3aVkzUjVJam9pU2xkVUlpd2lkSGx3SWpvaVNsZFVJaXdpYTJsa0lqb2lNelpsTkdGbE5HWXRZMkV5TVMwMFpERXdMVGxrWW1JdE5XUmlNV05rTm1NNU5qYzRJbjAuLkRvVmtETV8wU1FaQUxxMEFFejE1UkEuOXg4TlpPbWoyMG8yMWpqb2FOY0ZwX0dzNF9jdHJiTlRtMDBVV1BWS1g1bnBNamJxdjZOTXJoWWhhT3E3N1E0OEpCUF9SZTVXSE9LazA4bEtfZHBuMlBIYlJJT0lZa1V0cjRBNkd3NnZBNnZvT0pud1hZS0pyZUlUeVhuZ3ptdVFjMV9wSmIzTlBpMjN5S010VGx0U2FOam5VODRzUE5fQVJNb0lObGktVGs0ZkowMk0zZzFXdkwzVFVPbHJqaVJzbzFQZXhoMkpTOHlhMUhud2RFZ3FtOEVXVEhpRGJGaXV2VldQMG1WLUJsRmx3TVNFcXR0dC1oc3JXQ3NyRTdKUnlhX0J0dkFnSnVYaklZUjV5SFdpcnI4QTQ0S2xOM21ORkhuLVlYaWViUjguOVJaRUh0czJrVmcteF8ycE56cTRiZw.C-pNsdLn4spTsM6NSvvfTIkSFJnjtCEIy4DmfAPhhnbEwV7Rl_NZ6M2IGxrMSeqOE3ckA65b1NceH6yaA_8IwQ"; + var assertion = validator.validate(jwt, "https://example.org"); + assertEquals("1f43798b-92c5-47f4-a1a9-0fcc51f185a9", assertion.getPrincipal().getName()); + assertEquals("1f43798b-92c5-47f4-a1a9-0fcc51f185a9", assertion.getPrincipal().getAttributes().get("sub")); + } + + @Test + public void verifyAesKeyWithEncryptedJWT() throws Exception { + var validator = getValidator("jwtservice"); + var jwt = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6ImQ4OTQ2MTMyLTRkZjYtNDBmZS05YTc0LWVhOTRkYTliMThjZCJ9.ZXlKNmFYQWlPaUpFUlVZaUxDSmhiR2NpT2lKa2FYSWlMQ0psYm1NaU9pSkJNVEk0UTBKRExVaFRNalUySWl3aVkzUjVJam9pU2xkVUlpd2lkSGx3SWpvaVNsZFVJaXdpYTJsa0lqb2lZamc0T0dZMVltWXRZekkyWVMwMFpEUmtMVGc0WTJZdE4yWTROV05oT0dWaE16WXdJbjAuLjY1TWdBZ1JnRXdGUnNhbmRFdGUwVXcuOHBEc1Bodnh5Q29Cc2ZIeFY3MjNzOUxvdkt0aEgyYkI4aUdsTlpEYXNpX0dQWmh1UHBsbGhNWHZrSTM5Q053Z1drWlRJQWRpOWxQSVk1YWc0RVNweWZDbEJRaUg3THdfaWNqTGhWaUVrY2RXRkx3THNQcFRaWkNUUnFKSTRmNzBQUnBBZmpFd0RKX0xzN204RERyVDRDYmFPalR2Q2JLdVAtYzFScDl0amg3cVFBUG5QcGplVGduQVppMExtaWxDXzlyYnhnZ0s1cmxYeXY5dzRQb0Z5aXR0MlZlRERmZjJGcXFLYlNnQUswZWRhdHV5ZHlqYjlFT1FvZktDdUNiZE1GRXI0TTBjOGtjN3BKU3VDZE1oYjBZUjliS3YySVY2Mks5VGU5em53MDQud0VLcTRRQjRXVlJNOUxIYnlnSW5aUQ.NiL7D5ZmBVOuG5zbgpESH-gwoWZyZwXPi8ueGdOjTYDPX14CdMitRS-827jAyC4o14q4Gdfue39yV1ahENpP4g"; + var assertion = validator.validate(jwt, "https://example.org"); + assertEquals("919d04b9-55c0-43ae-81fa-f5e3a55e6c85", assertion.getPrincipal().getName()); + assertEquals("919d04b9-55c0-43ae-81fa-f5e3a55e6c85", assertion.getPrincipal().getAttributes().get("sub")); + } +} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/SerializationTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/SerializationTests.java deleted file mode 100644 index 65e287186..000000000 --- a/cas-client-core/src/test/java/org/jasig/cas/client/SerializationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Collections; -import junit.framework.TestCase; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.authentication.SimpleGroup; -import org.jasig.cas.client.authentication.SimplePrincipal; -import org.jasig.cas.client.jaas.AssertionPrincipal; -import org.jasig.cas.client.validation.AssertionImpl; -import org.junit.Assert; - -/** - * Confirms serialization support for classes intended for session storage or - * other potential serialization use cases. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.11 - * - */ -public class SerializationTests extends TestCase { - - public void testSerializeDeserialize() throws Exception { - final Object[] subjects = getTestSubjects(); - for (int i = 0; i < subjects.length; i++) { - final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - final ObjectOutputStream out = new ObjectOutputStream(byteOut); - try { - out.writeObject(subjects[i]); - } catch (final Exception e) { - Assert.fail("Serialization failed for " + subjects[i]); - } finally { - out.close(); - } - - final ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); - final ObjectInputStream in = new ObjectInputStream(byteIn); - try { - Assert.assertEquals(subjects[i], in.readObject()); - } catch (final Exception e) { - Assert.fail("Deserialization failed for " + subjects[i]); - } finally { - in.close(); - } - } - } - - private Object[] getTestSubjects() { - final SimplePrincipal simplePrincipal = new SimplePrincipal("simple"); - final SimpleGroup simpleGroup = new SimpleGroup("group"); - final AttributePrincipalImpl attributePrincipal = new AttributePrincipalImpl("attr", - Collections. singletonMap("LOA", "3")); - final AssertionPrincipal assertionPrincipal = new AssertionPrincipal("assertion", new AssertionImpl( - attributePrincipal, Collections. singletonMap("authenticationMethod", "username"))); - - return new Object[] { simplePrincipal, simpleGroup, attributePrincipal, assertionPrincipal, }; - } -} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java deleted file mode 100644 index 2279c7152..000000000 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java +++ /dev/null @@ -1,347 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.util; - -import junit.framework.TestCase; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.ssl.HttpsURLConnectionFactory; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; - -/** - * Tests for the CommonUtils. - * - * @author Scott Battaglia - * @since 3.0 - */ -public final class CommonUtilsTests extends TestCase { - - private static final PublicTestHttpServer server = PublicTestHttpServer.instance(8092); - - public void testRedirectUrlWithParam() { - final String loginUrl = "http://localhost:8080/login?myName=foo"; - final String fullyConstructedUrl = CommonUtils.constructRedirectUrl(loginUrl, "foo", "foo", false, false, null); - - assertEquals("http://localhost:8080/login?myName=foo&foo=foo", fullyConstructedUrl); - - int count = 0; - final char[] chars = fullyConstructedUrl.toCharArray(); - - for (int i = 0; i < chars.length; i++) { - if (chars[i] == '?') { - count++; - } - } - - assertEquals(1, count); - } - - public void testRedirectUrlWithMethod() { - final String loginUrl = "http://localhost:8080/login"; - final String redirectUrl = CommonUtils.constructRedirectUrl(loginUrl, "foo", "foo", true, true, "post"); - - assertEquals("http://localhost:8080/login?foo=foo&renew=true&gateway=true&method=post", redirectUrl); - } - - public void testAssertNotNull() { - final String CONST_MESSAGE = "test"; - CommonUtils.assertNotNull(new Object(), CONST_MESSAGE); - try { - CommonUtils.assertNotNull(null, CONST_MESSAGE); - } catch (final IllegalArgumentException e) { - assertEquals(CONST_MESSAGE, e.getMessage()); - } - } - - public void testAssertNotEmpty() { - final String CONST_MESSAGE = "test"; - final Collection c = new ArrayList(); - c.add(new Object()); - CommonUtils.assertNotEmpty(c, CONST_MESSAGE); - try { - CommonUtils.assertNotEmpty(new ArrayList(), CONST_MESSAGE); - } catch (final IllegalArgumentException e) { - assertEquals(CONST_MESSAGE, e.getMessage()); - } - - try { - CommonUtils.assertNotEmpty(null, CONST_MESSAGE); - } catch (final IllegalArgumentException e) { - assertEquals(CONST_MESSAGE, e.getMessage()); - } - } - - public void testAssertTrue() { - final String CONST_MESSAGE = "test"; - CommonUtils.assertTrue(true, CONST_MESSAGE); - try { - CommonUtils.assertTrue(false, CONST_MESSAGE); - } catch (final IllegalArgumentException e) { - assertEquals(CONST_MESSAGE, e.getMessage()); - } - } - - public void testIsEmpty() { - assertFalse(CommonUtils.isEmpty("test")); - assertFalse(CommonUtils.isEmpty(" test")); - assertTrue(CommonUtils.isEmpty("")); - assertTrue(CommonUtils.isEmpty(null)); - assertFalse(CommonUtils.isEmpty(" ")); - } - - public void testIsNotEmpty() { - assertTrue(CommonUtils.isNotEmpty("test")); - assertTrue(CommonUtils.isNotEmpty(" test")); - assertFalse(CommonUtils.isNotEmpty("")); - assertFalse(CommonUtils.isNotEmpty(null)); - assertTrue(CommonUtils.isNotEmpty(" ")); - } - - public void testIsBlank() { - assertFalse(CommonUtils.isBlank("test")); - assertFalse(CommonUtils.isBlank(" test")); - assertTrue(CommonUtils.isBlank("")); - assertTrue(CommonUtils.isBlank(null)); - assertTrue(CommonUtils.isBlank(" ")); - } - - public void testIsNotBlank() { - assertTrue(CommonUtils.isNotBlank("test")); - assertTrue(CommonUtils.isNotBlank(" test")); - assertFalse(CommonUtils.isNotBlank("")); - assertFalse(CommonUtils.isNotBlank(null)); - assertFalse(CommonUtils.isNotBlank(" ")); - } - - public void testConstructServiceUrlWithTrailingSlash() { - final String CONST_MY_URL = "https://www.myserver.com/hello/hithere/"; - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - "service", "ticket", false); - - assertEquals(CONST_MY_URL, constructedUrl); - } - - public void testConstructServiceUrlWithServerNameContainingPath() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.my.server.com/app", - Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); - - assertEquals("https://www.my.server.com/app/hello/hithere/", constructedUrl); - } - - public void testConstructServiceUrlWithServerNameContainingPathAndSchema() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "https://www.my.server.com/app", - Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); - - assertEquals("https://www.my.server.com/app/hello/hithere/", constructedUrl); - } - - public void testConstructServiceUrlWithParamsCas() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("service=this&ticket=that&custom=custom"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); - } - - public void testConstructServiceUrlWithParamsCasAndServerNameWithSchema() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("service=this&ticket=that&custom=custom"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "https://www.myserver.com", - Protocol.CAS3.getServiceParameterName(), Protocol.CAS3.getArtifactParameterName(), false); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); - } - - - public void testConstructServiceUrlWithParamsSaml() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("TARGET=this&SAMLart=that&custom=custom"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), false); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); - } - - public void testConstructServiceUrlWithEncodedParamsSaml() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("TARGET%3Dthis%26SAMLart%3Dthat%26custom%3Dcustom"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), false); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); - } - - public void testConstructServiceUrlWithNoServiceParametersPassed() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("TARGET=Test1&service=Test2&custom=custom"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.SAML11.getArtifactParameterName(), true); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom", constructedUrl); - } - - public void testConstructServiceUrlWithEncodedParams2Saml() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("TARGET%3Dthis%26SAMLart%3Dthat%26custom%3Dcustom%20value%20here%26another%3Dgood"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), true); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom+value+here&another=good", constructedUrl); - } - - public void testConstructServiceUrlWithoutEncodedParamsSamlAndNoEncoding() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("TARGET=this&SAMLart=that&custom=custom value here&another=good"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), false); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom value here&another=good", constructedUrl); - } - - public void testConstructServiceUrlWithEncodedParamsSamlAndNoEncoding() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.setScheme("https"); - request.setSecure(true); - request.setQueryString("TARGET=this&SAMLart=that&custom=custom+value+here&another=good"); - - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, "www.myserver.com", - Protocol.SAML11.getServiceParameterName(), Protocol.SAML11.getArtifactParameterName(), true); - - assertEquals("https://www.myserver.com/hello/hithere/?custom=custom+value+here&another=good", constructedUrl); - } - - private void constructUrlNonStandardPortAndNoPortInConfigTest(final String serverNameList) { - final String CONST_MY_URL = "https://www.myserver.com:555/hello/hithere/"; - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.addHeader("Host", "www.myserver.com"); - request.setScheme("https"); - request.setSecure(true); - request.setServerPort(555); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, - serverNameList, "service", "ticket", false); - assertEquals(CONST_MY_URL, constructedUrl); - } - - public void testConstructUrlNonStandardPortAndNoScheme() { - constructUrlNonStandardPortAndNoPortInConfigTest("www.myserver.com"); - } - - public void testConstructUrlNonStandardPortAndScheme() { - constructUrlNonStandardPortAndNoPortInConfigTest("https://www.myserver.com"); - } - - public void testConstructUrlWithMultipleHostsNoPortsOrProtocol() { - final String CONST_MY_URL = "https://www.myserver.com/hello/hithere/"; - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.addHeader("Host", "www.myserver.com"); - request.setScheme("https"); - request.setSecure(true); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, - "www.amazon.com www.bestbuy.com www.myserver.com", "service", "ticket", false); - assertEquals(CONST_MY_URL, constructedUrl); - } - - public void testConstructURlWithMultipleHostsAndPorts() { - final String CONST_MY_URL = "https://www.myserver.com/hello/hithere/"; - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hello/hithere/"); - request.addHeader("Host", "www.myserver.com"); - request.setScheme("https"); - request.setSecure(true); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, - "http://www.amazon.com https://www.bestbuy.com https://www.myserver.com", "service", "ticket", false); - assertEquals(CONST_MY_URL, constructedUrl); - } - - public void testGetResponseFromServer() throws Exception { - final String RESPONSE = "test1\r\ntest2"; - server.content = RESPONSE.getBytes(server.encoding); - - final String responsedContent = CommonUtils.getResponseFromServer(new URL("http://localhost:8092"), new HttpsURLConnectionFactory(), null); - assertEquals(RESPONSE, responsedContent); - } - - public void testUrlEncode() { - assertEquals("this+is+a+very+special+parameter+with+%3D%25%2F", - CommonUtils.urlEncode("this is a very special parameter with =%/")); - } - - public void testUrlEncodeWithQueryParameters() { - final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/idp/authN/ExtCas"); - request.setQueryString("conversation=e1s1&ticket=ST-1234-123456789-a&entityId=https://test.edu/sp?alias=1234-1234-1234-1234&something=else"); - request.addHeader("Host", "www.myserver.com"); - request.setScheme("https"); - request.setSecure(true); - final MockHttpServletResponse response = new MockHttpServletResponse(); - final String constructedUrl = CommonUtils.constructServiceUrl(request, response, null, - "https://my.server.com", - "service", "ticket", false); - assertEquals("https://my.server.com/idp/authN/ExtCas?conversation=e1s1&entityId=https://test.edu/sp?alias=1234-1234-1234-1234&something=else", - constructedUrl); - } -} diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/URIBuilderTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/util/URIBuilderTests.java deleted file mode 100644 index 71379aca2..000000000 --- a/cas-client-core/src/test/java/org/jasig/cas/client/util/URIBuilderTests.java +++ /dev/null @@ -1,333 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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. - */ -/* - - * Licensed to Jasig under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Jasig 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 the following location: - * - * 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.jasig.cas.client.util; - -import org.junit.Test; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.*; - -/** - * @author Misagh Moayyed - */ -public class URIBuilderTests { - - @Test - public void allPartsUsed() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("http://apache.org/shindig?hello=world#foo", builder.toString()); - } - - @Test - public void noSchemeUsed() { - final URIBuilder builder = new URIBuilder() - .setHost("apache.org") - .setPath("/shindig") - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("//apache.org/shindig?hello=world#foo", builder.toString()); - } - - @Test - public void noAuthorityUsed() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setPath("/shindig") - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("http:/shindig?hello=world#foo", builder.toString()); - } - - @Test - public void noPathUsed() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("http://apache.org?hello=world#foo", builder.toString()); - } - - @Test - public void noQueryUsed() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .setFragment("foo"); - assertEquals("http://apache.org/shindig#foo", builder.toString()); - } - - @Test - public void noFragmentUsed() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .setCustomQuery("hello=world"); - assertEquals("http://apache.org/shindig?hello=world", builder.toString()); - } - - @Test - public void hostRelativePaths() { - final URIBuilder builder = new URIBuilder() - .setPath("/shindig") - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("/shindig?hello=world#foo", builder.toString()); - } - - @Test - public void relativePaths() { - final URIBuilder builder = new URIBuilder() - .setPath("foo") - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("foo?hello=world#foo", builder.toString()); - } - - @Test - public void noPathNoHostNoAuthority() { - final URIBuilder builder = new URIBuilder() - .setCustomQuery("hello=world") - .setFragment("foo"); - assertEquals("?hello=world#foo", builder.toString()); - } - - @Test - public void justSchemeAndAuthority() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org"); - assertEquals("http://apache.org", builder.toString()); - } - - @Test - public void justPath() { - final URIBuilder builder = new URIBuilder() - .setPath("/shindig"); - assertEquals("/shindig", builder.toString()); - } - - @Test - public void justAuthorityAndPath() { - final URIBuilder builder = new URIBuilder() - .setHost("apache.org") - .setPath("/shindig"); - assertEquals("//apache.org/shindig", builder.toString()); - } - - @Test - public void justQuery() { - final URIBuilder builder = new URIBuilder() - .setCustomQuery("hello=world"); - assertEquals("?hello=world", builder.toString()); - } - - @Test - public void justFragment() { - final URIBuilder builder = new URIBuilder() - .setFragment("foo"); - assertEquals("#foo", builder.toString()); - } - - @Test - public void addSingleQueryParameter() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .addParameter("hello", "world") - .setFragment("foo"); - assertEquals("http://apache.org/shindig?hello=world#foo", builder.toString()); - } - - @Test - public void addTwoQueryParameters() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .addParameter("hello", "world") - .addParameter("foo", "bar") - .setFragment("foo"); - assertEquals("http://apache.org/shindig?hello=world&foo=bar#foo", builder.toString()); - } - - @Test - public void iterableQueryParameters() { - final List list = new ArrayList(); - list.add(new URIBuilder.BasicNameValuePair("hello", "world")); - list.add(new URIBuilder.BasicNameValuePair("hello", "monde")); - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .addParameters(list) - .setFragment("foo"); - assertEquals("http://apache.org/shindig?hello=world&hello=monde#foo", builder.toString()); - } - - @Test - public void removeQueryParameter() { - final URIBuilder uri = new URIBuilder("http://www.example.com/foo?bar=baz&quux=baz"); - uri.removeQuery(); - assertEquals("http://www.example.com/foo", uri.toString()); - } - - @Test - public void addIdenticalParameters() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .addParameter("hello", "world") - .addParameter("hello", "goodbye") - .setFragment("foo"); - assertEquals("http://apache.org/shindig?hello=world&hello=goodbye#foo", builder.toString()); - } - - @Test - public void queryStringIsUnescaped() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .setCustomQuery("hello+world=world%26bar"); - assertEquals("world&bar", builder.build().getQuery().split("=")[1]); - } - - @Test - public void queryParamsAreEscaped() { - final URIBuilder builder = new URIBuilder(true) - .setScheme("http") - .setHost("apache.org") - .setEncodedPath("/shindig") - .addParameter("hello world", "foo&bar") - .setFragment("foo"); - assertEquals("http://apache.org/shindig?hello+world=foo%26bar#foo", builder.toString()); - assertEquals("hello+world=foo&bar", builder.build().getQuery()); - } - - @Test - public void addSingleFragmentParameter() { - final URIBuilder builder = new URIBuilder() - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .setFragment("hello=world") - .setCustomQuery("foo"); - assertEquals("http://apache.org/shindig?foo#hello=world", builder.toString()); - } - - @Test - public void fragmentStringIsUnescaped() { - final URIBuilder builder = new URIBuilder(true) - .setScheme("http") - .setHost("apache.org") - .setPath("/shindig") - .setEncodedFragment("hello+world=world%26bar"); - - assertEquals("world&bar", builder.build().getFragment().split("=")[1]); - } - - @Test - public void parse() { - final URIBuilder builder = new URIBuilder() - .digestURI(URI.create("http://apache.org/shindig?foo=bar%26baz&foo=three%3Dbaz#blah")); - - assertEquals("http", builder.getScheme()); - assertEquals("apache.org", builder.getHost()); - assertEquals("/shindig", builder.getPath()); - - final List list = builder.getQueryParams(); - for (final URIBuilder.BasicNameValuePair pair : list) { - assertEquals("foo", pair.getName()); - assertTrue(pair.getValue().equals("three=baz") || pair.getValue().equals("bar&baz")); - } - assertEquals(list.size(), 2); - assertEquals("blah", builder.getFragment()); - } - - @Test - public void constructFromUriAndBack() { - final URI uri = URI.create("http://apache.org/foo/bar?foo=bar&a=b&c=d&y=z&foo=zoo#foo"); - final URIBuilder builder = new URIBuilder(uri); - - assertEquals(uri, builder.build()); - } - - @Test - public void constructFromUriAndModify() { - final URI uri = URI.create("http://apache.org/foo/bar?foo=bar#foo"); - final URIBuilder builder = new URIBuilder(uri); - - builder.setHost("example.org"); - builder.addParameter("bar", "foo"); - - assertEquals("http://example.org/foo/bar?foo=bar&bar=foo#foo", builder.toString()); - } - - @Test - public void equalsAndHashCodeOk() { - final URIBuilder uri = new URIBuilder().digestURI(URI.create("http://example.org/foo/bar/baz?blah=blah#boo")); - final URIBuilder uri2 = new URIBuilder(URI.create("http://example.org/foo/bar/baz?blah=blah#boo")); - - assertEquals(uri, uri2); - assertEquals(uri2, uri); - - assertEquals(uri, uri); - - assertNotNull(uri); - assertNotSame(uri, "http://example.org/foo/bar/baz?blah=blah#boo"); - assertNotSame(uri, URI.create("http://example.org/foo/bar/baz?blah=blah#boo")); - assertEquals(uri.hashCode(), uri2.hashCode()); - } - - -} diff --git a/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml b/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml index f35698de7..1d76fb601 100644 --- a/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml +++ b/cas-client-core/src/test/resources/cas20ProxyTicketValidator.xml @@ -18,13 +18,13 @@ under the License. --> - + class="org.apereo.cas.client.validation.Cas20ProxyTicketValidator"> @@ -38,8 +38,8 @@ - \ No newline at end of file + diff --git a/cas-client-core/src/test/resources/log4j.properties b/cas-client-core/src/test/resources/log4j.properties index 5623caf1d..091913f1e 100644 --- a/cas-client-core/src/test/resources/log4j.properties +++ b/cas-client-core/src/test/resources/log4j.properties @@ -16,16 +16,14 @@ # specific language governing permissions and limitations # under the License. # - # # log4j configuration to get clean console listing during Maven tests # - # -# Licensed to Jasig under one or more contributor license +# Licensed to Apereo under one or more contributor license # agreements. See the NOTICE file distributed with this work # for additional information regarding copyright ownership. -# Jasig licenses this file to you under the Apache License, +# Apereo 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 the following location: @@ -39,12 +37,9 @@ # specific language governing permissions and limitations # under the License. # - log4j.rootCategory=WARN, stdout - log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%-5p %d{ISO8601} %t::%c{1} - %m%n - log4j.logger.org.apache.xml.security=OFF -log4j.logger.org.jasig.cas=WARN +log4j.logger.org.apereocas=WARN diff --git a/cas-client-integration-atlassian/LICENSE.txt b/cas-client-integration-atlassian/LICENSE.txt deleted file mode 100644 index ae5a56c4b..000000000 --- a/cas-client-integration-atlassian/LICENSE.txt +++ /dev/null @@ -1,50 +0,0 @@ -==== - Licensed to Apereo under one or more contributor license - agreements. See the NOTICE file distributed with this work - for additional information regarding copyright ownership. - Apereo 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 the following location: - - 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. -==== - -License for Use - -Copyright (c) 2007, JA-SIG, Inc. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of the JA-SIG, Inc. nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/cas-client-integration-atlassian/NOTICE b/cas-client-integration-atlassian/NOTICE deleted file mode 100644 index 264e83971..000000000 --- a/cas-client-integration-atlassian/NOTICE +++ /dev/null @@ -1,39 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - AOP alliance under Public Domain - Atlassian Event under Atlassian End User License - Atlassian JIRA - Code - Core under Atlassian End User License - Atlassian Seraph under Atlassian End User License - atlassian-osuser under Atlassian End User License - Confluence Core under Atlassian End User License - Google Collections Library under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Atlassian Integration under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JCL 1.1.1 implemented over SLF4J under MIT License - JUnit under Common Public License Version 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - spring-aop under The Apache Software License, Version 2.0 - spring-asm under The Apache Software License, Version 2.0 - spring-beans under The Apache Software License, Version 2.0 - spring-context under The Apache Software License, Version 2.0 - spring-core under The Apache Software License, Version 2.0 - spring-expression under The Apache Software License, Version 2.0 - diff --git a/cas-client-integration-atlassian/pom.xml b/cas-client-integration-atlassian/pom.xml deleted file mode 100644 index f676f2d7b..000000000 --- a/cas-client-integration-atlassian/pom.xml +++ /dev/null @@ -1,1466 +0,0 @@ - - - - org.jasig.cas.client - 3.6.3 - cas-client - - 4.0.0 - cas-client-integration-atlassian - jar - Jasig CAS Client for Java - Atlassian Integration - - - - - atlassian-seraph - com.atlassian.seraph - 4.1.3 - provided - jar - - - javax.transaction - jta - - - commons-lang - commons-lang - - - log4j - log4j - - - javax.servlet - servlet-api - - - opensymphony - oscore - - - com.atlassian.security - atlassian-secure-random - - - com.atlassian.security - atlassian-cookie-tools - - - commons-logging - commons-logging - - - true - - - - org.springframework - spring-context - - - - atlassian-user - com.atlassian.user - 5.4.14 - provided - jar - true - - - opensymphony - oscore - - - opensymphony - propertyset - - - commons-logging - commons-logging - - - javax.transaction - jta - - - ofbcore - ofbcore-jira-entity - - - ofbcore - ofbcore-jira-share - - - log4j - log4j - - - - commons-logging - commons-logging - - - dom4j - dom4j - - - - - - atlassian-osuser - com.atlassian.osuser - 1.1.2 - provided - jar - true - - - opensymphony - oscore - - - opensymphony - propertyset - - - commons-logging - commons-logging - - - - ofbcore - ofbcore-jira-entity - - - ofbcore - ofbcore-jira-share - - - log4j - log4j - - - javax.transaction - jta - - - dom4j - dom4j - - - - - - com.atlassian.confluence - confluence - 4.0 - provided - - - opensymphony - webwork - - - com.atlassian.crowd - embedded-crowd-api - - - com.atlassian.crowd - crowd-integration-api - - - com.atlassian.crowd - crowd-integration-seraph22 - - - com.atlassian.crowd - embedded-crowd-spi - - - com.atlassian.crowd - crowd-password-encoders - - - com.atlassian.crowd - atlassian-embedded-crowd-atlassian-user - - - com.atlassian.crowd - atlassian-embedded-crowd-hibernate2 - - - com.atlassian.crowd - embedded-crowd-core - - - com.atlassian.crowd - crowd-persistence - - - com.atlassian.crowd - crowd-ldap - - - org.springframework.ldap - spring-ldap-core - - - com.atlassian.confluence - confluence-upgrade - - - com.atlassian.gzipfilter - atlassian-gzipfilter - - - com.atlassian.applinks - applinks-api - - - com.atlassian.applinks - applinks-spi - - - com.atlassian.applinks - applinks-host - - - com.atlassian.util.concurrent - atlassian-util-concurrent - - - com.atlassian.modzdetector - modz-detector - - - com.atlassian.mail - atlassian-mail - - - com.atlassian.velocity - atlassian-velocity - - - com.atlassian.core - atlassian-core - - - com.atlassian.config - atlassian-config - - - com.atlassian.spring - atlassian-spring - - - com.atlassian.confluence - confluence-bucket - - - com.atlassian.xwork - atlassian-xwork-10 - - - com.atlassian.xwork - atlassian-xwork-core - - - com.atlassian.profiling - atlassian-profiling - - - com.atlassian.trackback - atlassian-trackback - - - com.atlassian.extras - atlassian-extras - - - com.atlassian.johnson - atlassian-johnson - - - com.atlassian.plugins - atlassian-plugins-core - - - com.atlassian.plugins - atlassian-plugins-servlet - - - com.atlassian.plugins - atlassian-plugins-webfragment - - - com.atlassian.plugins - atlassian-plugins-webresource - - - com.atlassian.plugins - atlassian-plugins-osgi - - - com.atlassian.plugins - atlassian-plugins-spring - - - com.atlassian.bandana - atlassian-bandana - - - com.atlassian.user - atlassian-user - - - com.atlassian.renderer - atlassian-renderer - - - com.atlassian.bonnie - atlassian-bonnie - - - com.atlassian.jdk.utilities - atlassian-jdk-utilities - - - joda-time - joda-time - - - com.atlassian.seraph - atlassian-seraph - - - com.atlassian.security.auth.trustedapps - atlassian-trusted-apps-core - - - com.atlassian.security.auth.trustedapps - atlassian-trusted-apps-seraph-integration - - - javax.activation - activation - - - log4j - log4j - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - org.slf4j - jul-to-slf4j - - - commons-lang - commons-lang - - - commons-logging - commons-logging - - - commons-io - commons-io - - - commons-beanutils - commons-beanutils - - - commons-fileupload - commons-fileupload - - - org.directwebremoting - dwr - - - hibernate - hibernate - - - cglib - cglib - - - dom4j - dom4j - - - odmg - odmg - - - c3p0 - c3p0 - - - javax.transaction - jta - - - javax.media - jai-core - - - com.sun - jai_codec - - - opensymphony - webwork - - - opensymphony - xwork - - - ognl - ognl - - - opensymphony - oscore - - - oscache - oscache - - - osuser - osuser - - - opensymphony - propertyset - - - org.apache.velocity - velocity - - - javax.servlet - servlet-api - - - javax.mail - mail - - - org.springframework - spring-core - - - org.springframework - spring-web - - - org.springframework - spring-support - - - org.springframework - spring-aop - - - org.springframework - spring-hibernate2 - - - org.springframework - spring-beans - - - org.springframework - spring-jdbc - - - org.springframework - spring-dao - - - org.springframework - spring-jmx - - - com.atlassian.paddle - atlassian-paddle - - - org.aspectj - aspectjweaver - - - net.sf.ldaptemplate - ldaptemplate - - - opensymphony - sitemesh - - - velocity-tools - velocity-tools - - - radeox - radeox - - - org.apache.lucene - lucene-core - - - org.apache.lucene - lucene-analyzers - - - org.apache.lucene - lucene-misc - - - org.apache.lucene - lucene-highlighter - - - commons-digester - commons-digester - - - batik - batik-all - - - net.sourceforge.cssparser - cssparser - - - org.hibernate - jtidy - - - org.quartz-scheduler - quartz - - - org.hsqldb - hsqldb - - - mockobjects - mockobjects-core - - - org.mockito - mockito-all - - - org.springframework - spring-mock - - - rome - rome - - - jdom - jdom - - - commons-jrcs - commons-jrcs - - - commons-httpclient - commons-httpclient - - - xerces - xercesImpl - - - xmlrpc - xmlrpc - - - glue - glue - - - exml - exml - - - axis - axis - - - axis - axis-jaxrpc - - - axis - axis-saaj - - - commons-discovery - commons-discovery - - - commons-codec - commons-codec - - - oro - oro - - - slide - slide - - - com.thoughtworks.xstream - xstream - - - jfree - jfreechart - - - xalan - xalan - - - com.octo.captcha - jcaptcha-all - - - net.java.dev.urlrewrite - urlrewrite - - - commons-collections - commons-collections - - - javax.xml.stream - stax-api - - - org.codehaus.woodstox - wstx-asl - - - org.codehaus.xfire - xfire-core - - - org.codehaus.xfire - xfire-aegis - - - net.jcip - jcip-annotations - - - com.atlassian.cache - atlassian-cache-api - - - com.atlassian.sal - sal-spi - - - com.atlassian.sal - sal-spring - - - com.atlassian.sal - sal-api - - - com.atlassian.cache - atlassian-cache-memory - - - net.sourceforge.findbugs - jsr305 - - - opensymphony - pell-multipart - - - ch.qos.logback - logback-classic - - - - - - com.atlassian.jira - jira-core - 4.4.5 - provided - jar - - - commons-logging - commons-logging - - - com.atlassian.jira - jira-api - - - com.atlassian.multitenant - multitenant-core - - - com.atlassian.multitenant - multitenant-utils - - - com.atlassian.crowd - atlassian-embedded-crowd-ofbiz - - - com.atlassian.crowd - embedded-crowd-core - - - com.atlassian.crowd - embedded-crowd-spi - - - com.atlassian.crowd - crowd-api - - - com.atlassian.crowd - crowd-core - - - com.atlassian.crowd - crowd-integration-api - - - com.atlassian.crowd - crowd-integration-client-rest - - - com.atlassian.crowd - crowd-persistence - - - com.atlassian.crowd - crowd-events - - - com.atlassian.crowd - crowd-ldap - - - com.atlassian.crowd - crowd-remote - - - com.atlassian.crowd - crowd-server-common - - - com.atlassian.crowd - crowd-password-encoders - - - com.atlassian.security - atlassian-password-encoder - - - org.springframework.security - spring-security-core - - - org.springframework - spring-core - - - org.springframework - spring-beans - - - org.springframework.ldap - spring-ldap-core - - - org.springframework - spring-tx - - - com.atlassian.crowd - crowd-integration-client - - - wsdl4j - wsdl4j - - - org.codehaus.xfire - xfire-core - - - org.codehaus.xfire - xfire-aegis - - - sal-spi - com.atlassian.sal - - - com.atlassian.sal - sal-core - - - com.atlassian.gadgets - atlassian-gadgets-api - - - com.atlassian.gadgets - atlassian-gadgets-spi - - - com.atlassian.oauth - atlassian-oauth-api - - - com.atlassian.p4package - atlassian-p4package - - - com.atlassian.extras - atlassian-extras - - - com.atlassian.cache - atlassian-cache-api - - - com.atlassian.cache - atlassian-cache-memory - - - joda-time - joda-time - - - com.sun - jai_core - - - com.sun - jai_codec - - - commons-lang - commons-lang - - - commons-collections - commons-collections - - - commons-io - commons-io - - - com.atlassian.activeobjects - activeobjects-spi - - - log4j - log4j - - - dom4j - dom4j - - - oro - oro - - - com.atlassian.util.concurrent - atlassian-util-concurrent - - - com.atlassian.profiling - atlassian-profiling - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-log4j12 - - - org.slf4j - jul-to-slf4j - - - org.slf4j - jcl-over-slf4j - - - com.atlassian.jdk.utilities - atlassian-jdk-utilities - - - com.atlassian.scheduler - atlassian-scheduler - - - com.atlassian.johnson - atlassian-johnson - - - com.atlassian.plugins - atlassian-plugins-core - - - com.atlassian.plugins - atlassian-plugins-servlet - - - com.atlassian.plugins - atlassian-plugins-webfragment - - - com.atlassian.plugins - atlassian-plugins-webresource - - - com.atlassian.plugins - atlassian-plugins-osgi - - - com.atlassian.plugins - atlassian-plugins-osgi-events - - - com.atlassian.seraph - atlassian-seraph - - - com.atlassian.security - atlassian-secure-random - - - com.atlassian.security.auth.trustedapps - atlassian-trusted-apps-core - - - com.atlassian.security.auth.trustedapps - atlassian-trusted-apps-seraph-integration - - - bouncycastle - bcprov-jdk15 - - - com.atlassian.renderer - atlassian-renderer - - - com.atlassian.gzipfilter - atlassian-gzipfilter - - - com.atlassian.event - atlassian-event - - - opensymphony - oscore - - - opensymphony - sitemesh - - - commons-digester - commons-digester - - - commons-beanutils - commons-beanutils - - - commons-configuration - commons-configuration - - - org.apache.lucene - lucene-analyzers - - - velocity - velocity - - - org.apache.velocity - velocity-tools - - - javax.activation - activation - - - javax.mail - mail - - - glue - glue - - - bsf - bsf - - - bsh - bsh - - - com.atlassian.ofbiz - entityengine-share - - - com.atlassian.ofbiz - entityengine - - - csv - csv - - - quartz - quartz - - - picocontainer - picocontainer - - - jzlib - jzlib - - - jsch - jsch - - - com.octo.captcha - jcaptcha - - - com.octo.captcha - jcaptcha-api - - - com.jhlabs - filters - - - javacvs - javacvs - - - statcvs - statcvs - - - commons-dbcp - commons-dbcp - - - commons-pool - commons-pool - - - hsqldb - hsqldb - - - jndi - jndi - - - jta - jta - - - ots-jts - ots-jts - - - jotm - jotm - - - jotm - jotm-jrmp_stubs - - - jotm - jotm-iiop_stubs - - - jotm - jonas_timer - - - jotm - objectweb-datasource - - - carol - carol - - - carol - carol-properties - - - xapool - xapool - - - xml-apis - xml-apis - - - saxon - saxon-noaelfred - - - commons-jelly - commons-jelly - - - commons-jelly - commons-jelly-tags-junit - - - commons-jelly - commons-jelly-tags-util - - - commons-jelly - commons-jelly-tags-email - - - commons-jelly - commons-jelly-tags-log - - - commons-jelly - commons-jelly-tags-http - - - commons-jelly - commons-jelly-tags-soap - - - commons-jelly - commons-jelly-tags-sql - - - commons-jelly - commons-jelly-tags-regexp - - - commons-jexl - commons-jexl - - - commons-httpclient - commons-httpclient - - - commons-codec - commons-codec - - - xmlrpc - xmlrpc - - - axis - axis - - - axis - axis-jaxrpc - - - axis - axis-saaj - - - commons-discovery - commons-discovery - - - xerces - xercesImpl - - - xalan - xalan - - - xml-security - xmlsec - - - datafile - datafile - - - xpp3 - xpp3 - - - com.thoughtworks.xstream - xstream - - - jfree - jfreechart - - - jfree - jcommon - - - net.java.dev.urlrewrite - urlrewrite - - - radeox - radeox - - - jtidy - jtidy - - - jdom - jdom - - - net.sf.ehcache - ehcache - - - org.codehaus.woodstox - wstx-asl - - - javax.servlet - servlet-api - - - javax.servlet - jsp-api - - - com.atlassian.modzdetector - modz-detector - - - org.antlr - antlr-runtime - - - commons-jrcs - commons-jrcs - - - com.google.collections - google-collections - - - com.atlassian.jira - jira-lang-ca_ES - - - com.atlassian.jira - jira-lang-cs_CZ - - - com.atlassian.jira - jira-lang-da_DK - - - com.atlassian.jira - jira-lang-de_CH - - - com.atlassian.jira - jira-lang-de_DE - - - com.atlassian.jira - jira-lang-en_UK - - - com.atlassian.jira - jira-lang-en_US - - - com.atlassian.jira - jira-lang-es_ES - - - com.atlassian.jira - jira-lang-fr_FR - - - com.atlassian.jira - jira-lang-hu_HU - - - com.atlassian.jira - jira-lang-it_IT - - - com.atlassian.jira - jira-lang-ja_JP - - - com.atlassian.jira - jira-lang-nl_BE - - - com.atlassian.jira - jira-lang-no_NO - - - com.atlassian.jira - jira-lang-pl_PL - - - com.atlassian.jira - jira-lang-pt_BR - - - com.atlassian.jira - jira-lang-ru_RU - - - com.atlassian.jira - jira-lang-sk_SK - - - com.atlassian.jira - jira-lang-tr_TR - - - com.atlassian.jira - jira-lang-zh_CN - - - com.atlassian.jira - jira-lang-zh_TW - - - com.google.code.findbugs - jsr305 - - - com.google.code.findbugs - annotations - - - cglib - cglib-nodep - - - com.atlassian.sal - sal-api - - - com.atlassian.applinks - applinks-api - - - com.atlassian.applinks - applinks-spi - - - com.atlassian.applinks - applinks-host - - - rhino - js - - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - compile - - - - - - atlassian - Atlassian Repository - https://maven.atlassian.com/content/repositories/atlassian-public/ - - - atlassian-3rdparty - Atlassian 3rd Party Repository - https://maven.atlassian.com/3rdparty/ - - - - diff --git a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/Confluence35CasAuthenticator.java b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/Confluence35CasAuthenticator.java deleted file mode 100644 index ac3de1bde..000000000 --- a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/Confluence35CasAuthenticator.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.integration.atlassian; - -import com.atlassian.confluence.event.events.security.LoginEvent; -import com.atlassian.confluence.event.events.security.LoginFailedEvent; -import com.atlassian.confluence.user.ConfluenceAuthenticator; -import com.atlassian.seraph.auth.AuthenticatorException; -import com.atlassian.seraph.auth.LoginReason; -import java.security.Principal; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.validation.Assertion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Extension of ConfluenceAuthenticator to allow people to configure Confluence 3.5+ to authenticate - * via CAS. - * - * Based on https://bitbucket.org/jaysee00/example-confluence-sso-authenticator - * - * @author Scott Battaglia - * @author John Watson - * @author Jozef Kotlar - * @version $Revision$ $Date$ - * @since 3.3.0 - */ -public final class Confluence35CasAuthenticator extends ConfluenceAuthenticator { - private static final long serialVersionUID = -6097438206488390678L; - - private static final Logger LOGGER = LoggerFactory.getLogger(Confluence35CasAuthenticator.class); - - public Principal getUser(final HttpServletRequest request, final HttpServletResponse response) { - Principal existingUser = getUserFromSession(request); - if (existingUser != null) { - LOGGER.debug("Session found; user already logged in."); - LoginReason.OK.stampRequestResponse(request, response); - return existingUser; - } - - final HttpSession session = request.getSession(); - final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - - if (assertion != null) { - final String username = assertion.getPrincipal().getName(); - final Principal user = getUser(username); - final String remoteIP = request.getRemoteAddr(); - final String remoteHost = request.getRemoteHost(); - - if (user != null) { - putPrincipalInSessionContext(request, user); - getElevatedSecurityGuard().onSuccessfulLoginAttempt(request, username); - // Firing this event is necessary to ensure the user's personal information is initialised correctly. - getEventPublisher().publish( - new LoginEvent(this, username, request.getSession().getId(), remoteHost, remoteIP)); - LoginReason.OK.stampRequestResponse(request, response); - LOGGER.debug("Logging in [{}] from CAS.", username); - } else { - LOGGER.debug("Failed logging [{}] from CAS.", username); - getElevatedSecurityGuard().onFailedLoginAttempt(request, username); - getEventPublisher().publish( - new LoginFailedEvent(this, username, request.getSession().getId(), remoteHost, remoteIP)); - } - return user; - } - - return super.getUser(request, response); - } - - public boolean logout(final HttpServletRequest request, final HttpServletResponse response) - throws AuthenticatorException { - final HttpSession session = request.getSession(); - - final Principal principal = (Principal) session.getAttribute(LOGGED_IN_KEY); - - if (principal != null) { - LOGGER.debug("Logging out [{}] from CAS.", principal.getName()); - } - - removePrincipalFromSessionContext(request); - session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, null); - return true; - } -} diff --git a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java deleted file mode 100644 index 8d95bb490..000000000 --- a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.integration.atlassian; - -import com.atlassian.confluence.user.ConfluenceAuthenticator; -import com.atlassian.seraph.auth.AuthenticatorException; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.validation.Assertion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.security.Principal; - -/** - * Extension of ConfluenceAuthenticator to allow people to configure Confluence to authenticate - * via CAS. - * - * @author Scott Battaglia - * @author John Watson - * @version $Revision$ $Date$ - * @since 3.1.2 - */ -public final class ConfluenceCasAuthenticator extends ConfluenceAuthenticator { - - /** - * ConfluenceCasAuthenticator.java - */ - private static final long serialVersionUID = -6097438206488390677L; - - private static final Logger LOGGER = LoggerFactory.getLogger(ConfluenceCasAuthenticator.class); - - public Principal getUser(final HttpServletRequest request, final HttpServletResponse response) { - final HttpSession session = request.getSession(); - - // user already exists - if (session.getAttribute(LOGGED_IN_KEY) != null) { - LOGGER.debug("Session found; user already logged in."); - return (Principal) session.getAttribute(LOGGED_IN_KEY); - } - - final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - - if (assertion != null) { - final String username = assertion.getPrincipal().getName(); - final Principal user = getUser(username); - - // user doesn't exist - if (user == null) { - LOGGER.error("Could not determine principal for [{}]", assertion.getPrincipal().getName()); - getElevatedSecurityGuard().onFailedLoginAttempt(request, username); - return null; - } - - LOGGER.debug("Logging in [{}] from CAS.", username); - - getElevatedSecurityGuard().onSuccessfulLoginAttempt(request, username); - session.setAttribute(LOGGED_IN_KEY, user); - session.setAttribute(LOGGED_OUT_KEY, null); - return user; - } - - return super.getUser(request, response); - } - - public boolean logout(final HttpServletRequest request, final HttpServletResponse response) - throws AuthenticatorException { - final HttpSession session = request.getSession(); - - final Principal principal = (Principal) session.getAttribute(LOGGED_IN_KEY); - - LOGGER.debug("Logging out [{}] from CAS.", principal.getName()); - - session.setAttribute(LOGGED_OUT_KEY, principal); - session.setAttribute(LOGGED_IN_KEY, null); - session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, null); - return true; - } -} diff --git a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/Jira44CasAuthenticator.java b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/Jira44CasAuthenticator.java deleted file mode 100644 index ef3ef6bd4..000000000 --- a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/Jira44CasAuthenticator.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.integration.atlassian; - -import com.atlassian.jira.security.login.JiraSeraphAuthenticator; -import com.atlassian.seraph.auth.AuthenticationContextAwareAuthenticator; -import com.atlassian.seraph.auth.AuthenticatorException; -import com.atlassian.seraph.auth.LoginReason; -import java.security.Principal; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.validation.Assertion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Extension of JiraSeraphAuthenticator to allow people to configure - * JIRA 4.4 and above to authenticate via Jasig CAS - * - * @author Scott Battaglia - * @author Martin Stiborsky - * @author Jozef Kotlar - * @version $Revision$ $Date$ - * @since 3.3.0 - */ -@AuthenticationContextAwareAuthenticator -public final class Jira44CasAuthenticator extends JiraSeraphAuthenticator { - - /** Jira43CasAuthenticator.java */ - private static final long serialVersionUID = 3852011252741183166L; - - private static final Logger LOGGER = LoggerFactory.getLogger(Jira44CasAuthenticator.class); - - public Principal getUser(final HttpServletRequest request, final HttpServletResponse response) { - // First, check to see if this session has already been authenticated during a previous request. - Principal existingUser = getUserFromSession(request); - if (existingUser != null) { - LOGGER.debug("Session found; user already logged in."); - return existingUser; - } - - final HttpSession session = request.getSession(); - final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - - if (assertion != null) { - final String username = assertion.getPrincipal().getName(); - final Principal user = getUser(username); - - if (user != null) { - putPrincipalInSessionContext(request, user); - getElevatedSecurityGuard().onSuccessfulLoginAttempt(request, username); - LoginReason.OK.stampRequestResponse(request, response); - LOGGER.debug("Logging in [{}] from CAS.", username); - } else { - LOGGER.debug("Failed logging [{}] from CAS.", username); - getElevatedSecurityGuard().onFailedLoginAttempt(request, username); - } - return user; - } - - return super.getUser(request, response); - } - - public boolean logout(final HttpServletRequest request, final HttpServletResponse response) - throws AuthenticatorException { - final HttpSession session = request.getSession(); - final Principal p = (Principal) session.getAttribute(LOGGED_IN_KEY); - - if (p != null) { - LOGGER.debug("Logging out [{}] from CAS.", p.getName()); - } - - removePrincipalFromSessionContext(request); - session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, null); - return true; - } -} diff --git a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java deleted file mode 100644 index 74e2ffb5f..000000000 --- a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.integration.atlassian; - -import com.atlassian.seraph.auth.AuthenticatorException; -import com.atlassian.seraph.auth.DefaultAuthenticator; -import com.opensymphony.user.EntityNotFoundException; -import com.opensymphony.user.UserManager; -import java.security.Principal; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.validation.Assertion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Extension of ConfluenceAuthenticator to allow people to configure Confluence to authenticate - * via CAS. - * - * @author Scott Battaglia - * @author John Watson - * @version $Revision$ $Date$ - * @since 3.1.3 - */ -public final class JiraCasAuthenticator extends DefaultAuthenticator { - - /** JiraCasAuthenticator.java */ - private static final long serialVersionUID = 3452011252741183166L; - - private static final Logger LOGGER = LoggerFactory.getLogger(JiraCasAuthenticator.class); - - @Override - protected boolean authenticate(final Principal principal, final String password) throws AuthenticatorException { - return true; - } - - @Override - protected Principal getUser(final String username) { - try { - return UserManager.getInstance().getUser(username); - } catch (final EntityNotFoundException e) { - LOGGER.warn("Could not find user '{}' in UserManager : {}", username, e); - } - return null; - } - - public Principal getUser(final HttpServletRequest request, final HttpServletResponse response) { - final HttpSession session = request.getSession(); - - // user already exists - if (session.getAttribute(LOGGED_IN_KEY) != null) { - LOGGER.debug("Session found; user already logged in."); - return (Principal) session.getAttribute(LOGGED_IN_KEY); - } - - final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - - if (assertion != null) { - final Principal p = getUser(assertion.getPrincipal().getName()); - - LOGGER.debug("Logging in [{}] from CAS.", p.getName()); - - session.setAttribute(LOGGED_IN_KEY, p); - session.setAttribute(LOGGED_OUT_KEY, null); - return p; - } - - return super.getUser(request, response); - } - - public boolean logout(final HttpServletRequest request, final HttpServletResponse response) - throws AuthenticatorException { - final HttpSession session = request.getSession(); - final Principal p = (Principal) session.getAttribute(LOGGED_IN_KEY); - - LOGGER.debug("Logging out [{}] from CAS.", p.getName()); - - session.setAttribute(LOGGED_OUT_KEY, p); - session.setAttribute(LOGGED_IN_KEY, null); - session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, null); - return true; - } -} diff --git a/cas-client-integration-jboss/NOTICE b/cas-client-integration-jboss/NOTICE deleted file mode 100644 index f01b69ff3..000000000 --- a/cas-client-integration-jboss/NOTICE +++ /dev/null @@ -1,40 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - JBoss Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JBoss Application Server Tomcat under lgpl - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-jboss/pom.xml b/cas-client-integration-jboss/pom.xml deleted file mode 100644 index ef92682da..000000000 --- a/cas-client-integration-jboss/pom.xml +++ /dev/null @@ -1,263 +0,0 @@ - - - - org.jasig.cas.client - 3.6.4 - cas-client - - 4.0.0 - cas-client-integration-jboss - jar - Jasig CAS Client for Java - JBoss Integration - - - - org.jasig.cas.client - cas-client-core - ${project.version} - compile - - - - - org.jboss.jbossas - jboss-as-tomcat - ${jboss.version} - provided - - - xml-apis - xml-apis - - - org.jboss.spec.javax.servlet.jstl - jboss-jstl-api_1.2_spec - - - jacorb - jacorb - - - org.jboss.logging - jboss-logging - - - org.picketbox - jboss-security-spi - - - jboss - jboss-serialization - - - org.jboss.integration - jboss-deployment-spi - - - org.picketbox - jbosssx-client - - - org.jboss.web - jbossweb - - - org.jboss.web - jasper-jdt - - - junit - junit - - - log4j - log4j - - - org.jboss - jboss-common-core - - - org.jboss.metadata - jboss-metadata-common - - - org.jboss.metadata - jboss-metadata-war - - - org.jboss - jboss-vfs - - - org.jboss.ws - jbossws-spi - - - org.jboss - jbossxb - - - org.jboss.aop - jboss-aop - - - org.jboss.spec.javax.security.auth.message - jboss-jaspi-api_1.0_spec - - - org.jboss.jbossas - jboss-as-connector - - - org.jboss.jbossas - jboss-as-ejb3 - - - org.jboss.ejb3 - jboss-ejb3-core - - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - - - org.jboss.cluster - jboss-ha-server-cache-spi - - - org.jboss.jbossas - jboss-as-iiop - - - org.jboss.jbossas - jboss-as-security - - - org.jboss.spec.javax.security.jacc - jboss-jacc-api_1.4_spec - - - org.jboss.spec.javax.resource - jboss-connector-api_1.5_spec - - - org.jboss.spec.javax.ejb - jboss-ejb-api_3.1_spec - - - org.jboss.spec.javax.servlet - jboss-servlet-api_3.0_spec - - - org.jboss.spec.javax.servlet.jsp - jboss-jsp-api_2.2_spec - - - org.jboss.spec.javax.el - jboss-el-api_2.2_spec - - - org.jboss.spec.javax.xml.ws - jboss-jaxws-api_2.2_spec - - - org.jboss.mx - jboss-j2se - - - org.jboss.jbossas - jboss-as-server - - - org.jboss.jbossas - jboss-as-system-jmx - - - org.jboss.cl - jboss-classloader - - - org.jboss.deployers - jboss-deployers-core-spi - - - org.jboss.deployers - jboss-deployers-impl - - - org.jboss.deployers - jboss-deployers-spi - - - org.jboss.deployers - jboss-deployers-structure-spi - - - org.jboss.deployers - jboss-deployers-vfs - - - org.jboss.deployers - jboss-deployers-vfs-spi - - - oswego-concurrent - concurrent - - - org.slf4j - jcl-over-slf4j - - - net.jcip - jcip-annotations - - - javax.validation - validation-api - - - org.jboss.mc-int - jboss-mc-int-servlet - - - org.jboss.mod_cluster - mod_cluster - - - - - - - - - - jboss - JBoss Repository - https://repository.jboss.org/nexus/content/groups/public// - - - - 6.1.0.Final - - diff --git a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java b/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java deleted file mode 100644 index 4704bcd05..000000000 --- a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/configuration/JBossCompatibleJndiConfigurationStrategyImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.configuration; - -/** - * Simple extension to the {@link org.jasig.cas.client.configuration.JndiConfigurationStrategyImpl} to provide a JBoss 7 compatible prefix. - * - * @author Scott Battaglia - * @since 3.4.0 - */ -public final class JBossCompatibleJndiConfigurationStrategyImpl extends JndiConfigurationStrategyImpl { - - private static final String ENVIRONMENT_PREFIX = "java:/comp/env/cas/"; - - public JBossCompatibleJndiConfigurationStrategyImpl() { - super(ENVIRONMENT_PREFIX); - } -} diff --git a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java b/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java deleted file mode 100644 index b1cedc435..000000000 --- a/cas-client-integration-jboss/src/main/java/org/jasig/cas/client/jboss/authentication/WebAuthenticationFilter.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.jboss.authentication; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.jaas.AssertionPrincipal; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.CommonUtils; -import org.jboss.web.tomcat.security.login.WebAuthentication; - -/** - * This servlet filter performs a programmatic JAAS login using the JBoss - * WebAuthentication class. - * The filter executes when it receives a CAS ticket and expects the - * {@link org.jasig.cas.client.jaas.CasLoginModule} JAAS module to perform the CAS - * ticket validation in order to produce an {@link AssertionPrincipal} from which - * the CAS assertion is obtained and inserted into the session to enable SSO. - *

- * If a service init-param is specified for this filter, it supersedes - * the service defined for the {@link org.jasig.cas.client.jaas.CasLoginModule}. - * - * @author Daniel Fisher - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.11 - */ -public final class WebAuthenticationFilter extends AbstractCasFilter { - - public WebAuthenticationFilter() { - super(Protocol.CAS2); - } - - @Override - public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, - final FilterChain chain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - final HttpSession session = request.getSession(); - final String ticket = CommonUtils.safeGetParameter(request, getProtocol().getArtifactParameterName()); - - if (session != null && session.getAttribute(CONST_CAS_ASSERTION) == null && ticket != null) { - try { - final String service = constructServiceUrl(request, response); - logger.debug("Attempting CAS ticket validation with service={} and ticket={}", service, ticket); - if (!new WebAuthentication().login(service, ticket)) { - logger.debug("JBoss Web authentication failed."); - throw new GeneralSecurityException("JBoss Web authentication failed."); - } - if (request.getUserPrincipal() instanceof AssertionPrincipal) { - final AssertionPrincipal principal = (AssertionPrincipal) request.getUserPrincipal(); - logger.debug("Installing CAS assertion into session."); - request.getSession().setAttribute(CONST_CAS_ASSERTION, principal.getAssertion()); - } else { - logger.debug("Aborting -- principal is not of type AssertionPrincipal"); - throw new GeneralSecurityException( - "JBoss Web authentication did not produce CAS AssertionPrincipal."); - } - } catch (final GeneralSecurityException e) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); - } - } else if (session != null && request.getUserPrincipal() == null) { - // There is evidence that in some cases the principal can disappear - // in JBoss despite a valid session. - // This block forces consistency between principal and assertion. - logger.info("User principal not found. Removing CAS assertion from session to force re-authentication."); - session.removeAttribute(CONST_CAS_ASSERTION); - } - chain.doFilter(request, response); - } -} diff --git a/cas-client-integration-jetty/NOTICE b/cas-client-integration-jetty/NOTICE deleted file mode 100644 index 55f24f07f..000000000 --- a/cas-client-integration-jetty/NOTICE +++ /dev/null @@ -1,61 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - asm under BSD-3-Clause - asm-analysis under BSD-3-Clause - asm-commons under BSD-3-Clause - asm-tree under BSD-3-Clause - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Eclipse Compiler for Java(TM) under Eclipse Public License - v 2.0 - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - Jetty Container Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - javax.annotation API under CDDL + GPLv2 with classpath exception - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Jetty :: Apache JSP Implementation under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Http Utility under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: IO Utility under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: JNDI Naming under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Plus under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Schemas under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Security under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Server Core under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Servlet Annotations under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Servlet Handling under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Utilities under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Utilities :: Ajax(JSON) under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: Webapp Application Support under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - Jetty :: XML utilities under Apache Software License - Version 2.0 or Eclipse Public License - Version 1.0 - JUnit under Eclipse Public License 1.0 - MortBay :: Apache EL :: API and Implementation under Apache License Version 2.0 - MortBay :: Apache Jasper :: JSP Implementation under Apache License Version 2.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-jetty/pom.xml b/cas-client-integration-jetty/pom.xml deleted file mode 100644 index 94f35e7df..000000000 --- a/cas-client-integration-jetty/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-jetty - jar - Jasig CAS Client for Java - Jetty Container Integration - - - - 9.4.44.v20210927 - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - - - org.eclipse.jetty - jetty-security - ${jetty.version} - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - test-jar - test - - - org.eclipse.jetty - jetty-webapp - ${jetty.version} - test - - - org.eclipse.jetty - jetty-plus - ${jetty.version} - test - - - org.eclipse.jetty - jetty-annotations - ${jetty.version} - test - - - org.eclipse.jetty - apache-jsp - ${jetty.version} - test - - - javax.servlet - javax.servlet-api - 4.0.1 - provided - - - - - diff --git a/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasAuthentication.java b/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasAuthentication.java deleted file mode 100644 index 5eb4199ec..000000000 --- a/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasAuthentication.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.jetty; - -import org.eclipse.jetty.security.UserAuthentication; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Assertion; - -/** - * CAS-specific user authentication. - * - * @author Marvin S. Addison - */ -public class CasAuthentication extends UserAuthentication { - - /** CAS authenticator that produced this authentication. */ - private final CasAuthenticator authenticator; - - /** CAS ticket that was successfully validated to permit authentication. */ - private final String ticket; - - - /** - * Creates a new instance. - * - * @param authenticator The authenticator that produced this authentication. - * @param ticket The CAS ticket that was successfully validated to permit authentication. - * @param assertion The CAS assertion produced from successful ticket validation. - */ - public CasAuthentication(final CasAuthenticator authenticator, final String ticket, final Assertion assertion) { - super(authenticator.getAuthMethod(), new CasUserIdentity(assertion, authenticator.getRoleAttribute())); - CommonUtils.assertNotNull(ticket, "Ticket cannot be null"); - CommonUtils.assertNotNull(authenticator, "CasAuthenticator cannot be null"); - this.authenticator = authenticator; - this.ticket = ticket; - } - - /** @return The CAS ticket that was successfully validated to permit authentication. */ - public String getTicket() { - return ticket; - } - - @Override - public void logout() { - super.logout(); - this.authenticator.clearCachedAuthentication(ticket); - } -} diff --git a/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasAuthenticator.java b/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasAuthenticator.java deleted file mode 100644 index 1a04aebcf..000000000 --- a/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasAuthenticator.java +++ /dev/null @@ -1,248 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.jetty; - -import org.eclipse.jetty.security.Authenticator; -import org.eclipse.jetty.security.ServerAuthException; -import org.eclipse.jetty.server.Authentication; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator; -import org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * Jetty authenticator component for container-managed CAS authentication. - *

NOTE: This component does not support CAS gateway mode.

- * - * @author Marvin S. Addison - * @since 3.4.2 - */ -public class CasAuthenticator extends AbstractLifeCycle implements Authenticator { - - /** Name of authentication method provided by this authenticator. */ - public static final String AUTH_METHOD = "CAS"; - - /** Session attribute used to cache CAS authentication data. */ - private static final String CACHED_AUTHN_ATTRIBUTE = "org.jasig.cas.client.jetty.Authentication"; - - /** Logger instance. */ - private final Logger logger = LoggerFactory.getLogger(CasAuthenticator.class); - - /** Map of tickets to sessions. */ - private final ConcurrentMap> sessionMap = - new ConcurrentHashMap>(); - - /** CAS ticket validator component. */ - private TicketValidator ticketValidator; - - /** Space-delimited list of server names. */ - private String serverNames; - - /** CAS principal attribute containing role data. */ - private String roleAttribute; - - /** URL to /login URI on CAS server. */ - private String casServerLoginUrl; - - /** Protocol used by ticket validator. */ - private Protocol protocol; - - /** CAS renew parameter. */ - private boolean renew; - - - /** - * Sets the CAS ticket validator component. - * - * @param ticketValidator Ticket validator, MUST NOT be null. - */ - public void setTicketValidator(final TicketValidator ticketValidator) { - CommonUtils.assertNotNull(ticketValidator, "TicketValidator cannot be null"); - if (ticketValidator instanceof AbstractUrlBasedTicketValidator) { - if (ticketValidator instanceof AbstractCasProtocolUrlBasedTicketValidator) { - protocol = Protocol.CAS2; - } else { - protocol = Protocol.SAML11; - } - casServerLoginUrl = ReflectUtils.getField("casServerUrlPrefix", ticketValidator) + "/login"; - renew = (Boolean) ReflectUtils.getField("renew", ticketValidator); - } else { - throw new IllegalArgumentException("Unsupported ticket validator " + ticketValidator); - } - this.ticketValidator = ticketValidator; - } - - /** - * Sets the names of the server host running Jetty. - * - * @param nameList Space-delimited list of one or more server names, e.g. "www1.example.com www2.example.com". - * MUST NOT be blank. - */ - public void setServerNames(final String nameList) { - CommonUtils.isNotBlank(nameList); - this.serverNames = nameList; - } - - /** @return The name of the CAS principal attribute that contains role data. */ - public String getRoleAttribute() { - return roleAttribute; - } - - /** - * Sets the name of the CAS principal attribute that contains role data. - * - * @param roleAttribute Role attribute name. MUST NOT be blank. - */ - public void setRoleAttribute(final String roleAttribute) { - CommonUtils.isNotBlank(roleAttribute); - this.roleAttribute = roleAttribute; - } - - @Override - public void setConfiguration(final AuthConfiguration configuration) { - // Nothing to do - // All configuration must be via CAS-specific setter methods - } - - @Override - public String getAuthMethod() { - return AUTH_METHOD; - } - - @Override - public void prepareRequest(final ServletRequest request) { - // Nothing to do - } - - @Override - public Authentication validateRequest( - final ServletRequest servletRequest, final ServletResponse servletResponse, final boolean mandatory) - throws ServerAuthException { - - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - - CasAuthentication authentication = fetchCachedAuthentication(request); - if (authentication != null) { - return authentication; - } - - final String ticket = request.getParameter(protocol.getArtifactParameterName()); - if (ticket != null && mandatory) { - try { - logger.debug("Attempting to validate {}", ticket); - final Assertion assertion = ticketValidator.validate(ticket, serviceUrl(request, response)); - logger.info("Successfully authenticated {}", assertion.getPrincipal()); - authentication = new CasAuthentication(this, ticket, assertion); - cacheAuthentication(request, authentication); - } catch (final Exception e) { - throw new ServerAuthException("CAS ticket validation failed", e); - } - } - if (authentication != null) { - return authentication; - } else if (mandatory) { - redirectToCas(request, response); - return Authentication.SEND_CONTINUE; - } - return Authentication.UNAUTHENTICATED; - } - - @Override - public boolean secureResponse( - final ServletRequest request, - final ServletResponse response, - final boolean mandatory, - final Authentication.User user) throws ServerAuthException { - return true; - } - - @Override - protected void doStart() throws Exception { - if (ticketValidator == null) { - throw new RuntimeException("TicketValidator cannot be null"); - } - if (serverNames == null) { - throw new RuntimeException("ServerNames cannot be null"); - } - } - - protected void clearCachedAuthentication(final String ticket) { - final WeakReference sessionRef = sessionMap.remove(ticket); - if (sessionRef != null && sessionRef.get() != null) { - sessionRef.get().removeAttribute(CACHED_AUTHN_ATTRIBUTE); - } - } - - private void cacheAuthentication(final HttpServletRequest request, final CasAuthentication authentication) { - final HttpSession session = request.getSession(true); - if (session != null) { - session.setAttribute(CACHED_AUTHN_ATTRIBUTE, authentication); - sessionMap.put(authentication.getTicket(), new WeakReference(session)); - } - } - - private CasAuthentication fetchCachedAuthentication(final HttpServletRequest request) { - final HttpSession session = request.getSession(false); - if (session != null) { - return (CasAuthentication) session.getAttribute(CACHED_AUTHN_ATTRIBUTE); - } - return null; - } - - private String serviceUrl(final HttpServletRequest request, final HttpServletResponse response) { - return CommonUtils.constructServiceUrl( - request, - response, - null, - serverNames, - protocol.getServiceParameterName(), - protocol.getArtifactParameterName(), - true); - } - - private void redirectToCas( - final HttpServletRequest request, final HttpServletResponse response) throws ServerAuthException { - try { - final String redirectUrl = CommonUtils.constructRedirectUrl( - casServerLoginUrl, protocol.getServiceParameterName(), serviceUrl(request, response), renew, false, null); - logger.debug("Redirecting to {}", redirectUrl); - response.sendRedirect(redirectUrl); - } catch (final IOException e) { - logger.debug("Redirect to CAS failed with error", e); - throw new ServerAuthException("Redirect to CAS failed", e); - } - } -} diff --git a/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasUserIdentity.java b/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasUserIdentity.java deleted file mode 100644 index 856b84857..000000000 --- a/cas-client-integration-jetty/src/main/java/org/jasig/cas/client/jetty/CasUserIdentity.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.jetty; - -import org.eclipse.jetty.server.UserIdentity; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Assertion; - -import javax.security.auth.Subject; -import java.security.Principal; -import java.util.Collection; - -/** - * CAS user identity backed by assertion data. - * - * @author Marvin S. Addison - */ -public class CasUserIdentity implements UserIdentity { - - /** CAS principal. */ - private final AttributePrincipal principal; - - /** Assertion attribute containing role data. */ - private final String roleAttribute; - - - /** - * Creates a new instance from a CAS assertion containing principal information. - * - * @param assertion CAS assertion resulting from successful ticket validation. - * @param roleAttribute Principal attribute containing role data. - */ - public CasUserIdentity(final Assertion assertion, final String roleAttribute) { - CommonUtils.assertNotNull(assertion, "Assertion cannot be null"); - this.principal = assertion.getPrincipal(); - this.roleAttribute = roleAttribute; - } - - @Override - public Subject getSubject() { - final Subject subject = new Subject(); - subject.getPrincipals().add(principal); - return subject; - } - - @Override - public Principal getUserPrincipal() { - return principal; - } - - @Override - public boolean isUserInRole(final String role, final Scope scope) { - if (roleAttribute != null) { - final Object value = principal.getAttributes().get(roleAttribute); - if (value instanceof Collection) { - return ((Collection) value).contains(role); - } else if (value instanceof String) { - return value.equals(role); - } - } - return false; - } - - @Override - public String toString() { - return principal.getName(); - } -} diff --git a/cas-client-integration-jetty/src/test/java/org/jasig/cas/client/jetty/CasAuthenticatorTest.java b/cas-client-integration-jetty/src/test/java/org/jasig/cas/client/jetty/CasAuthenticatorTest.java deleted file mode 100644 index 4efbbb4de..000000000 --- a/cas-client-integration-jetty/src/test/java/org/jasig/cas/client/jetty/CasAuthenticatorTest.java +++ /dev/null @@ -1,228 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.jetty; - -import org.apache.tomcat.InstanceManager; -import org.apache.tomcat.SimpleInstanceManager; -import org.eclipse.jetty.annotations.ServletContainerInitializersStarter; -import org.eclipse.jetty.apache.jsp.JettyJasperInitializer; -import org.eclipse.jetty.jsp.JettyJspServlet; -import org.eclipse.jetty.plus.annotation.ContainerInitializer; -import org.eclipse.jetty.security.ConstraintMapping; -import org.eclipse.jetty.security.ConstraintSecurityHandler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.webapp.WebAppContext; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.nio.CharBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.*; - -/** - * Unit test for {@link CasAuthenticator}. - * - * @author Marvin S. Addison - */ -public class CasAuthenticatorTest { - - private static final Server server = new Server(8080); - private static final CasAuthenticator authenticator = new CasAuthenticator(); - - @BeforeClass - public static void beforeClass() throws Exception { - final WebAppContext context = new WebAppContext(); - context.setContextPath("/webapp"); - String workingDir = new File(".").getAbsolutePath(); - workingDir = workingDir.substring(0, workingDir.length() - 2); - final String webappDir; - if (workingDir.endsWith("/cas-client-integration-jetty")) { - webappDir = workingDir + "/src/test/webapp"; - } else { - webappDir = workingDir + "/cas-client-integration-jetty/src/test/webapp"; - } - context.setWar(webappDir); - - - // JSP config from https://github.com/jetty-project/embedded-jetty-jsp/ - System.setProperty("org.apache.jasper.compiler.disablejsr199", "false"); - context.setAttribute("javax.servlet.context.tempdir", getScratchDir()); - context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", - ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/.*taglibs.*\\.jar$"); - context.setAttribute("org.eclipse.jetty.containerInitializers", jspInitializers()); - context.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager()); - context.addBean(new ServletContainerInitializersStarter(context), true); - context.addServlet(jspServletHolder(), "*.jsp"); - - // Wire up CAS authentication - authenticator.setServerNames("localhost:8080"); - authenticator.setTicketValidator(new Cas20ServiceTicketValidator("http://localhost:8081/cas")); - - // Configure security handling for webapp context - final ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); - final Constraint constraint = new Constraint("CasRealm", Constraint.ANY_AUTH); - constraint.setAuthenticate(true); - final ConstraintMapping secureMapping = new ConstraintMapping(); - secureMapping.setPathSpec("/secure.jsp"); - secureMapping.setConstraint(constraint); - securityHandler.addConstraintMapping(secureMapping); - securityHandler.setAuthenticator(authenticator); - context.setSecurityHandler(securityHandler); - - // Add webapp context and start the server - server.setHandler(context); - server.start(); - } - - @Test - public void testValidateRequestPublicPageNoTicket() throws Exception { - final HttpURLConnection uc = openConnection("http://localhost:8080/webapp/"); - try { - assertEquals(200, uc.getResponseCode()); - assertTrue(readOutput(uc).contains("Welcome everyone")); - } finally { - uc.disconnect(); - } - } - - @Test - public void testValidateRequestPublicPageWithTicket() throws Exception { - final HttpURLConnection uc = openConnection("http://localhost:8080/webapp/?ticket=ST-12345"); - try { - assertEquals(200, uc.getResponseCode()); - assertTrue(readOutput(uc).contains("Welcome everyone")); - } finally { - uc.disconnect(); - } - } - - @Test - public void testValidateRequestSecurePageNoTicket() throws Exception { - final HttpURLConnection uc = openConnection("http://localhost:8080/webapp/secure.jsp"); - try { - assertEquals(302, uc.getResponseCode()); - assertEquals( - "http://localhost:8081/cas/login?service=http%3A%2F%2Flocalhost%3A8080%2Fwebapp%2Fsecure.jsp", - uc.getHeaderField("Location")); - } finally { - uc.disconnect(); - } - } - - @Test - public void testValidateRequestSecurePageWithTicket() throws Exception { - final String successResponse = "" + - "" + - "bob" + - "" + - ""; - final PublicTestHttpServer server = PublicTestHttpServer.instance(8081); - server.content = successResponse.getBytes(StandardCharsets.UTF_8); - final HttpURLConnection uc = openConnection("http://localhost:8080/webapp/secure.jsp?ticket=ST-12345"); - try { - assertEquals(200, uc.getResponseCode()); - assertTrue(readOutput(uc).contains("Hello bob")); - } finally { - uc.disconnect(); - } - } - - @AfterClass - public static void afterClass() throws Exception { - server.stop(); - } - - private String readOutput(final URLConnection connection) throws IOException { - final InputStreamReader reader = new InputStreamReader(connection.getInputStream()); - final StringBuilder builder = new StringBuilder(); - final CharBuffer buffer = CharBuffer.allocate(1024); - try { - while (reader.read(buffer) > 0) { - builder.append(buffer.flip()); - buffer.clear(); - } - } finally { - reader.close(); - } - return builder.toString(); - } - - private static File getScratchDir() throws IOException - { - final File tempDir = new File(System.getProperty("java.io.tmpdir")); - final File scratchDir = new File(tempDir.toString(), "embedded-jetty-jsp"); - - if (!scratchDir.exists()) - { - if (!scratchDir.mkdirs()) - { - throw new IOException("Unable to create scratch directory: " + scratchDir); - } - } - return scratchDir; - } - - /** - * Ensure the jsp engine is initialized correctly - */ - private static List jspInitializers() - { - return Collections.singletonList(new ContainerInitializer(new JettyJasperInitializer(), null)); - } - - /** - * Create JSP Servlet (must be named "jsp") - */ - private static ServletHolder jspServletHolder() - { - final ServletHolder holderJsp = new ServletHolder("jsp", JettyJspServlet.class); - holderJsp.setInitOrder(0); - holderJsp.setInitParameter("logVerbosityLevel", "DEBUG"); - holderJsp.setInitParameter("fork", "false"); - holderJsp.setInitParameter("xpoweredBy", "false"); - holderJsp.setInitParameter("compilerTargetVM", "1.7"); - holderJsp.setInitParameter("compilerSourceVM", "1.7"); - holderJsp.setInitParameter("keepgenerated", "true"); - return holderJsp; - } - - private static HttpURLConnection openConnection(final String url) throws IOException { - final HttpURLConnection uc; - try { - uc = (HttpURLConnection) new URL(url).openConnection(); - } catch (final IOException e) { - throw new RuntimeException("Invalid URL: " + url, e); - } - uc.setInstanceFollowRedirects(false); - uc.connect(); - return uc; - } -} diff --git a/cas-client-integration-jetty/src/test/resources/jetty/context-cas2.xml b/cas-client-integration-jetty/src/test/resources/jetty/context-cas2.xml deleted file mode 100644 index ffab5b84f..000000000 --- a/cas-client-integration-jetty/src/test/resources/jetty/context-cas2.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - / - /webapps/yourapp - - - - app.example.com - - - https://cas.example.com/cas - - - - - - - diff --git a/cas-client-integration-jetty/src/test/resources/jetty/context-saml11.xml b/cas-client-integration-jetty/src/test/resources/jetty/context-saml11.xml deleted file mode 100644 index fb462aa94..000000000 --- a/cas-client-integration-jetty/src/test/resources/jetty/context-saml11.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - / - /webapps/yourapp - - - - app.example.com - memberOf - - - https://cas.example.com/cas - - - - - - - diff --git a/cas-client-integration-jetty/src/test/webapp/index.jsp b/cas-client-integration-jetty/src/test/webapp/index.jsp deleted file mode 100644 index 2c1d90637..000000000 --- a/cas-client-integration-jetty/src/test/webapp/index.jsp +++ /dev/null @@ -1,29 +0,0 @@ -<%-- - - Licensed to Apereo under one or more contributor license - agreements. See the NOTICE file distributed with this work - for additional information regarding copyright ownership. - Apereo 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 the following location: - - 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. - ---%> - - - - - Welcome Page - -

Welcome everyone

- - \ No newline at end of file diff --git a/cas-client-integration-jetty/src/test/webapp/secure.jsp b/cas-client-integration-jetty/src/test/webapp/secure.jsp deleted file mode 100644 index e9915292b..000000000 --- a/cas-client-integration-jetty/src/test/webapp/secure.jsp +++ /dev/null @@ -1,29 +0,0 @@ -<%-- - - Licensed to Apereo under one or more contributor license - agreements. See the NOTICE file distributed with this work - for additional information regarding copyright ownership. - Apereo 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 the following location: - - 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. - ---%> - - - - - Secure Page - -

Hello <%=request.getUserPrincipal()%>

- - \ No newline at end of file diff --git a/cas-client-integration-tomcat-common/NOTICE b/cas-client-integration-tomcat-common/NOTICE deleted file mode 100644 index c97792f91..000000000 --- a/cas-client-integration-tomcat-common/NOTICE +++ /dev/null @@ -1,39 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-tomcat-common/pom.xml b/cas-client-integration-tomcat-common/pom.xml deleted file mode 100644 index e30c117da..000000000 --- a/cas-client-integration-tomcat-common/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-tomcat-common - jar - Jasig CAS Client for Java - Common Tomcat Integration Support - - - - org.jasig.cas.client - cas-client-core - ${project.version} - jar - compile - - - - diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AbstractLogoutHandler.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AbstractLogoutHandler.java deleted file mode 100644 index 17a3f3e66..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AbstractLogoutHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Assertion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base class for all logout handlers. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractLogoutHandler implements LogoutHandler { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - protected String redirectUrl; - - public void setRedirectUrl(final String redirectUrl) { - this.redirectUrl = redirectUrl; - } - - /** {@inheritDoc} */ - @Override - public void logout(final HttpServletRequest request, final HttpServletResponse response) { - logger.debug("Processing logout request from CAS server."); - - final Assertion assertion; - final HttpSession httpSession = request.getSession(false); - if (httpSession != null - && (assertion = (Assertion) httpSession.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)) != null) { - httpSession.removeAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - logger.info("Successfully logged out {}", assertion.getPrincipal()); - } else { - logger.info("Session already ended."); - } - - final String redirectUrl = constructRedirectUrl(request); - if (redirectUrl != null) { - logger.debug("Redirecting to {}", redirectUrl); - CommonUtils.sendRedirect(response, redirectUrl); - } - } - - /** - * Constructs a url to redirect to. - * - * @param request the original request. - * @return the url to redirect to. CAN be NULL. - */ - protected String constructRedirectUrl(final HttpServletRequest request) { - return this.redirectUrl; - } -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AssertionCasRealmDelegate.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AssertionCasRealmDelegate.java deleted file mode 100644 index 9530c0f45..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AssertionCasRealmDelegate.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import java.security.Principal; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import org.jasig.cas.client.authentication.AttributePrincipal; -import org.jasig.cas.client.util.CommonUtils; - -/** - * {@link CasRealm} implementation with prinicpal and role data backed by the {@link org.jasig.cas.client.validation.Assertion}. - * In particular, an {@link AttributePrincipal} is expected from which the values of - * the role attribute are retrieved. The default role attribute name is "role", - * but this can be customized via {@link #setRoleAttributeName(String)}. - *

- * Authentication always succeeds and simply returns the given principal. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class AssertionCasRealmDelegate implements CasRealm { - - /** Default role attribute name */ - public static final String DEFAULT_ROLE_NAME = "role"; - - /** Name of the role attribute in the principal's attributes */ - private String roleAttributeName = DEFAULT_ROLE_NAME; - - /** - * @param name Name of the attribute in the principal that contains role data. - */ - public void setRoleAttributeName(final String name) { - this.roleAttributeName = name; - } - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - return p; - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - CommonUtils.assertTrue(p instanceof AttributePrincipal, - "Expected instance of AttributePrincipal but got " + p.getClass()); - - final Collection roles = getRoleCollection(p); - final String[] array = new String[roles.size()]; - roles.toArray(array); - return array; - } - - /** {@inheritDoc} */ - @Override - public boolean hasRole(final Principal principal, final String role) { - if ("*".equals(role)) { - return true; - } - return getRoleCollection(principal).contains(role); - } - - /** - * Retrieves the attributes for a Principal. To make life easy this should NEVER return null. - * - * @param p the principal to check. - * @return the list of attribute values that matched this role, or an empty collection if they don't. - */ - @SuppressWarnings("unchecked") - private Collection getRoleCollection(final Principal p) { - if (!(p instanceof AttributePrincipal)) { - return Collections.emptyList(); - } - - final Object attributes = ((AttributePrincipal) p).getAttributes().get(this.roleAttributeName); - - if (attributes == null) { - return Collections.emptyList(); - } - - if (attributes instanceof Collection) { - return (Collection) attributes; - } - - return Arrays.asList(attributes.toString()); - } -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AuthenticatorDelegate.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AuthenticatorDelegate.java deleted file mode 100644 index 9afdf867a..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/AuthenticatorDelegate.java +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import java.io.IOException; -import java.security.Principal; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Assertion; -import org.jasig.cas.client.validation.TicketValidationException; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Version-agnostic authenticator which encapsulates the core CAS workflow of - * redirecting to CAS for unauthenticated sessions and validating service tickets - * when found in the request. Implementations of the Tomcat Authenticator - * class are expected to be thin wrappers that delegate most if not all authentication - * logic to this class. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class AuthenticatorDelegate { - - /** Log instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private String serviceUrl; - - private String serverName; - - private String casServerLoginUrl; - - private String artifactParameterName; - - private String serviceParameterName; - - private TicketValidator ticketValidator; - - private CasRealm realm; - - /** - * Performs CAS authentication on the given request and returns the principal - * determined by the configured {@link CasRealm} on success. - * - * @param request HTTP request. - * @param response HTTP response. - * - * @return The authenticated principal on authentication success, otherwise - * null. In the case where authentication explicitly fails, either due to - * ticket validation failure or realm authentication failure, a 403 status - * code is set on the response. In cases where no existing CAS session exists, - * a 302 redirect is set on the response to redirect to the CAS server for - * authentication. - */ - public final Principal authenticate(final HttpServletRequest request, final HttpServletResponse response) { - Assertion assertion = null; - HttpSession session = request.getSession(); - if (session != null) { - assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - } - if (assertion == null) { - logger.debug("CAS assertion not found in session -- authentication required."); - final String token = request.getParameter(this.artifactParameterName); - final String service = CommonUtils.constructServiceUrl(request, response, this.serviceUrl, this.serverName, - this.serviceParameterName, this.artifactParameterName, true); - if (CommonUtils.isBlank(token)) { - final String redirectUrl = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, - this.serviceParameterName, service, false, false, null); - logger.debug("Redirecting to {}", redirectUrl); - CommonUtils.sendRedirect(response, redirectUrl); - return null; - } - try { - logger.debug("Attempting to validate {} for {}", token, service); - assertion = this.ticketValidator.validate(token, service); - logger.debug("CAS authentication succeeded."); - if (session == null) { - session = request.getSession(true); - } - session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, assertion); - } catch (final TicketValidationException e) { - setUnauthorized(response, e.getMessage()); - return null; - } - } - final Principal p = realm.authenticate(assertion.getPrincipal()); - if (p == null) { - logger.debug("{} failed to authenticate to {}", assertion.getPrincipal().getName(), realm); - setUnauthorized(response, null); - } - return p; - } - - /** - * @return the serviceUrl - */ - public String getServiceUrl() { - return serviceUrl; - } - - /** - * @param serviceUrl the serviceUrl to set - */ - public void setServiceUrl(final String serviceUrl) { - this.serviceUrl = serviceUrl; - } - - /** - * @return the serverName - */ - public String getServerName() { - return serverName; - } - - /** - * @param serverName the serverName to set - */ - public void setServerName(final String serverName) { - this.serverName = serverName; - } - - /** - * @return the casServerLoginUrl - */ - public String getCasServerLoginUrl() { - return casServerLoginUrl; - } - - /** - * @param casServerLoginUrl the casServerLoginUrl to set - */ - public void setCasServerLoginUrl(final String casServerLoginUrl) { - this.casServerLoginUrl = casServerLoginUrl; - } - - /** - * @param artifactParameterName the artifactParameterName to set - */ - public void setArtifactParameterName(final String artifactParameterName) { - this.artifactParameterName = artifactParameterName; - } - - /** - * @param serviceParameterName the serviceParameterName to set - */ - public void setServiceParameterName(final String serviceParameterName) { - this.serviceParameterName = serviceParameterName; - } - - /** - * @param ticketValidator the ticketValidator to set - */ - public void setTicketValidator(final TicketValidator ticketValidator) { - this.ticketValidator = ticketValidator; - } - - /** - * @param realm the realm to set - */ - public void setRealm(final CasRealm realm) { - this.realm = realm; - } - - private void setUnauthorized(final HttpServletResponse response, final String message) { - try { - if (message != null) { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, message); - } else { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } - } catch (final IOException e) { - throw new IllegalStateException("Error setting 403 status.", e); - } - } -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/CasRealm.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/CasRealm.java deleted file mode 100644 index 89261bb9f..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/CasRealm.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import java.security.Principal; - -/** - * Describes Tomcat Realm implementations that do not require password - * for authentication. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public interface CasRealm { - /** - * Authenticates the given principal. - * - * @param p Principal to authenticate. - * - * @return New principal. - */ - Principal authenticate(Principal p); - - /** - * Gets the roles defined for the given principal. - * - * @param p the principal to retrieve the roles for. - * @return Roles for given principal or empty array if none exist. - */ - String[] getRoles(Principal p); - - /** - * Determines whether the given principal possesses the given role. - * - * @param principal Principal to evaluate. - * @param role Role to test for possession. - * - * @return True if principal has given role, false otherwise. - */ - boolean hasRole(Principal principal, String role); -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/LogoutHandler.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/LogoutHandler.java deleted file mode 100644 index 17e1d8fef..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/LogoutHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Strategy pattern interface for ending a CAS authentication session. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public interface LogoutHandler { - /** - * Determines whether the given request is a logout request. - * - * @param request HTTP request. - * - * @return True if request is a logout request, false otherwise. - */ - boolean isLogoutRequest(HttpServletRequest request); - - /** - * Ends the current authenticated user session bound to the given request. - * The response is provided to allow the handler to customize the response - * behavior on logout as needed. - * - * @param request HTTP request. - * @param response HTTP response. - */ - void logout(HttpServletRequest request, HttpServletResponse response); -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/PropertiesCasRealmDelegate.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/PropertiesCasRealmDelegate.java deleted file mode 100644 index 529910711..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/PropertiesCasRealmDelegate.java +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.security.Principal; -import java.util.*; -import org.jasig.cas.client.util.CommonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * {@link CasRealm} implementation with users and roles defined by a properties - * file with the following format: - *

- * username1=role1,role2,role3
- * username2=role1
- * username3=role2,role3
- * 
- * User authentication succeeds if the name of the given principal exists as - * a username in the properties file. - * - * @author Middleware - * @version $Revision$ - * @since 3.1.12 - * - */ -public class PropertiesCasRealmDelegate implements CasRealm { - - /** Log instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - /** Path to backing properties file */ - private String propertiesFilePath; - - /** Map of usernames to roles */ - private Map> roleMap; - - /** - * @param path Path to properties file container username/role data. - */ - public void setPropertiesFilePath(final String path) { - propertiesFilePath = path; - } - - /** {@inheritDoc} */ - public void readProperties() { - CommonUtils.assertNotNull(propertiesFilePath, "PropertiesFilePath not set."); - File file = new File(propertiesFilePath); - if (!file.isAbsolute()) { - file = new File(System.getProperty("catalina.base"), propertiesFilePath); - } - CommonUtils.assertTrue(file.exists(), "File not found " + file); - CommonUtils.assertTrue(file.canRead(), "Cannot read " + file); - logger.debug("Loading users/roles from {}", file); - final Properties properties = new Properties(); - try { - properties.load(new BufferedInputStream(new FileInputStream(file))); - } catch (final IOException e) { - throw new IllegalStateException("Error loading users/roles from " + file, e); - } - this.roleMap = new HashMap>(properties.size()); - - for (final Object key : properties.keySet()) { - final String user = (String) key; - // Use TreeSet to sort roles - final Set roleSet = new HashSet(); - final String[] roles = properties.getProperty(user).split(",\\s*"); - roleSet.addAll(Arrays.asList(roles)); - roleMap.put(user, roleSet); - } - } - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - if (this.roleMap.containsKey(p.getName())) { - return p; - } else { - return null; - } - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - final Set roleSet = this.roleMap.get(p.getName()); - return roleSet.toArray(new String[roleSet.size()]); - } - - /** {@inheritDoc} */ - @Override - public boolean hasRole(final Principal principal, final String role) { - if ("*".equals(role)) { - return true; - } - - final Set roles = this.roleMap.get(principal.getName()); - - return roles != null && roles.contains(role); - } -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/RegexUriLogoutHandler.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/RegexUriLogoutHandler.java deleted file mode 100644 index 29c62638d..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/RegexUriLogoutHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import java.util.regex.Pattern; -import javax.servlet.http.HttpServletRequest; -import org.jasig.cas.client.util.CommonUtils; - -/** - * Performs CAS logout when the request URI matches a regular expression. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class RegexUriLogoutHandler extends AbstractLogoutHandler { - - private String logoutUriRegex; - - private Pattern logoutUriPattern; - - /** - * @param regex Logout URI regular expression. CANNOT be null. - */ - public void setLogoutUriRegex(final String regex) { - this.logoutUriRegex = regex; - } - - /** - * Initializes the component for use. - */ - public void init() { - CommonUtils.assertNotNull(this.logoutUriRegex, "A logout URI regular expression is required."); - this.logoutUriPattern = Pattern.compile(this.logoutUriRegex); - } - - /** {@inheritDoc} */ - @Override - public boolean isLogoutRequest(final HttpServletRequest request) { - return this.logoutUriPattern.matcher(request.getRequestURI()).matches(); - } -} diff --git a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/StaticUriLogoutHandler.java b/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/StaticUriLogoutHandler.java deleted file mode 100644 index cd8518bf2..000000000 --- a/cas-client-integration-tomcat-common/src/main/java/org/jasig/cas/client/tomcat/StaticUriLogoutHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import javax.servlet.http.HttpServletRequest; -import org.jasig.cas.client.util.CommonUtils; - -/** - * Performs CAS logout when the request URI matches a fixed context-relative - * URI. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class StaticUriLogoutHandler extends AbstractLogoutHandler { - - private String logoutUri; - - /** - * The logout URI to watch for logout requests. - * - * @param logoutUri Logout URI. CANNOT be null. MUST be relative and start with "/" - */ - public void setLogoutUri(final String logoutUri) { - this.logoutUri = logoutUri; - } - - /** - * Initializes the component for use. - */ - public void init() { - CommonUtils.assertNotNull(this.logoutUri, "logoutUri cannot be null."); - CommonUtils.assertTrue(this.logoutUri.startsWith("/"), "logoutUri must start with \"/\""); - } - - /** {@inheritDoc} */ - @Override - public boolean isLogoutRequest(final HttpServletRequest request) { - return this.logoutUri.equals(request.getRequestURI()); - } - -} diff --git a/cas-client-integration-tomcat-common/src/test/java/org/jasig/cas/client/tomcat/PropertiesCasRealmDelegateTests.java b/cas-client-integration-tomcat-common/src/test/java/org/jasig/cas/client/tomcat/PropertiesCasRealmDelegateTests.java deleted file mode 100644 index 1f3e97598..000000000 --- a/cas-client-integration-tomcat-common/src/test/java/org/jasig/cas/client/tomcat/PropertiesCasRealmDelegateTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat; - -import java.security.Principal; -import java.util.Arrays; -import java.util.List; -import junit.framework.TestCase; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; - -/** - * Unit test for {@link PropertiesCasRealmDelegate} class. - * - * @author Middleware - * @version $Revision$ - * - */ -public class PropertiesCasRealmDelegateTests extends TestCase { - private final PropertiesCasRealmDelegate realm = new PropertiesCasRealmDelegate(); - - /** {@inheritDoc} */ - @Override - protected void setUp() throws Exception { - super.setUp(); - realm.setPropertiesFilePath("src/test/resources/org/jasig/cas/client/tomcat/user-roles.properties"); - realm.readProperties(); - } - - public void testAuthenticate() { - final Principal p = new AttributePrincipalImpl("rosencrantz"); - assertTrue(p == realm.authenticate(p)); - } - - public void testGetRoles() { - final Principal p = new AttributePrincipalImpl("rosencrantz"); - final List expected = Arrays.asList(new String[] { "admins", "users" }); - final List actual = Arrays.asList(realm.getRoles(p)); - assertEquals(expected.size(), actual.size()); - - for (final String item : expected) { - assertTrue(actual.contains(item)); - } - } - - public void testHasRole() { - assertTrue(realm.hasRole(new AttributePrincipalImpl("rosencrantz"), "admins")); - assertTrue(realm.hasRole(new AttributePrincipalImpl("rosencrantz"), "users")); - assertTrue(realm.hasRole(new AttributePrincipalImpl("guildenstern"), "users")); - } -} diff --git a/cas-client-integration-tomcat-common/src/test/resources/org/jasig/cas/client/tomcat/user-roles.properties b/cas-client-integration-tomcat-common/src/test/resources/org/jasig/cas/client/tomcat/user-roles.properties deleted file mode 100644 index 180d5a53c..000000000 --- a/cas-client-integration-tomcat-common/src/test/resources/org/jasig/cas/client/tomcat/user-roles.properties +++ /dev/null @@ -1,21 +0,0 @@ -# -# Licensed to Apereo under one or more contributor license -# agreements. See the NOTICE file distributed with this work -# for additional information regarding copyright ownership. -# Apereo 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 the following location: -# -# 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. -# - -rosencrantz=users,admins -guildenstern=users diff --git a/cas-client-integration-tomcat-v6/NOTICE b/cas-client-integration-tomcat-v6/NOTICE deleted file mode 100644 index dc4bfcbf9..000000000 --- a/cas-client-integration-tomcat-v6/NOTICE +++ /dev/null @@ -1,44 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - catalina under Apache License, Version 2.0 - coyote under Apache License, Version 2.0 - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 6.x Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-tomcat-v6/pom.xml b/cas-client-integration-tomcat-v6/pom.xml deleted file mode 100644 index 755d924e0..000000000 --- a/cas-client-integration-tomcat-v6/pom.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-tomcat-v6 - jar - Jasig CAS Client for Java - Tomcat 6.x Integration - - - - org.jasig.cas.client - cas-client-integration-tomcat-common - ${project.version} - jar - compile - - - org.jasig.cas.client - cas-client-support-saml - ${project.version} - jar - compile - true - - - org.apache.tomcat - catalina - 6.0.53 - jar - provided - - - org.apache.tomcat - servlet-api - - - org.apache.tomcat - juli - - - org.apache.tomcat - annotations-api - - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - jar - compile - - - - diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractAuthenticator.java deleted file mode 100644 index 681537b42..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractAuthenticator.java +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import java.io.IOException; -import java.security.Principal; -import org.apache.catalina.LifecycleEvent; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.Realm; -import org.apache.catalina.authenticator.AuthenticatorBase; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.deploy.LoginConfig; -import org.jasig.cas.client.tomcat.AuthenticatorDelegate; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base authenticator for all authentication protocols supported by CAS. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractAuthenticator extends AuthenticatorBase implements LifecycleListener { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - private final AuthenticatorDelegate delegate = new AuthenticatorDelegate(); - - private String casServerUrlPrefix; - - private String encoding; - - private boolean encode; - - private boolean renew; - - protected abstract String getAuthenticationMethod(); - - /** - * Abstract method that subclasses should use to provide the name of the artifact parameter (i.e. ticket) - * - * @return the artifact parameter name. CANNOT be NULL. - */ - protected abstract String getArtifactParameterName(); - - /** - * Abstract method that subclasses should use to provide the name of the service parameter (i.e. service) - * - * @return the service parameter name. CANNOT be NULL. - */ - protected abstract String getServiceParameterName(); - - /** - * Returns the single instance of the ticket validator to use to validate tickets. Sub classes should include - * the one appropriate for the - * - * @return a fully configured ticket validator. CANNOT be NULL. - */ - protected abstract TicketValidator getTicketValidator(); - - @Override - public void start() throws LifecycleException { - super.start(); - logger.debug("{} starting.", getName()); - final Realm realm = this.context.getRealm(); - try { - CommonUtils.assertTrue(realm instanceof CasRealm, "Expected CasRealm but got " + realm.getInfo()); - CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null."); - CommonUtils.assertNotNull(this.delegate.getCasServerLoginUrl(), "casServerLoginUrl cannot be null."); - CommonUtils.assertTrue(this.delegate.getServerName() != null || this.delegate.getServiceUrl() != null, - "either serverName or serviceUrl must be set."); - this.delegate.setRealm((CasRealm) realm); - } catch (final Exception e) { - throw new LifecycleException(e); - } - // Complete delegate initialization after the component is started. - // See #lifecycleEvent() method. - addLifecycleListener(this); - } - - protected final String getCasServerUrlPrefix() { - return this.casServerUrlPrefix; - } - - public final void setCasServerUrlPrefix(final String casServerUrlPrefix) { - this.casServerUrlPrefix = casServerUrlPrefix; - } - - public final void setCasServerLoginUrl(final String casServerLoginUrl) { - this.delegate.setCasServerLoginUrl(casServerLoginUrl); - } - - public final boolean isEncode() { - return this.encode; - } - - public final void setEncode(final boolean encode) { - this.encode = encode; - } - - protected final boolean isRenew() { - return this.renew; - } - - public void setRenew(final boolean renew) { - this.renew = renew; - } - - public final void setServerName(final String serverName) { - this.delegate.setServerName(serverName); - } - - public final void setServiceUrl(final String serviceUrl) { - this.delegate.setServiceUrl(serviceUrl); - } - - protected final String getEncoding() { - return this.encoding; - } - - public final void setEncoding(final String encoding) { - this.encoding = encoding; - } - - /** {@inheritDoc} */ - @Override - public final boolean authenticate(final Request request, final Response response, final LoginConfig loginConfig) - throws IOException { - Principal principal = request.getUserPrincipal(); - boolean result = false; - if (principal == null) { - // Authentication sets the response headers for status and redirect if needed - principal = this.delegate.authenticate(request.getRequest(), response); - if (principal != null) { - register(request, response, principal, getAuthenticationMethod(), null, null); - result = true; - } - } else { - result = true; - } - return result; - } - - /** {@inheritDoc} */ - @Override - public void lifecycleEvent(final LifecycleEvent event) { - if (AFTER_START_EVENT.equals(event.getType())) { - logger.debug("{} processing lifecycle event {}", getName(), AFTER_START_EVENT); - this.delegate.setTicketValidator(getTicketValidator()); - this.delegate.setArtifactParameterName(getArtifactParameterName()); - this.delegate.setServiceParameterName(getServiceParameterName()); - } - } - - /** {@inheritDoc} */ - @Override - public String getInfo() { - return getName() + "/1.0"; - } - - /** - * @return Authenticator descriptive name. - */ - protected abstract String getName(); -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasAuthenticator.java deleted file mode 100644 index c46bf3628..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasAuthenticator.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -/** - * Base class for all CAS protocol authenticators. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractCasAuthenticator extends AbstractAuthenticator { - - private String proxyCallbackUrl; - - protected final String getProxyCallbackUrl() { - return this.proxyCallbackUrl; - } - - public final void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected final String getArtifactParameterName() { - return "ticket"; - } - - @Override - protected final String getServiceParameterName() { - return "service"; - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasRealm.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasRealm.java deleted file mode 100644 index 14f05b577..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractCasRealm.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import java.security.Principal; -import org.apache.catalina.realm.RealmBase; -import org.jasig.cas.client.tomcat.CasRealm; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base Realm implementation for all CAS realms. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractCasRealm extends RealmBase implements CasRealm { - - /** Logger instance */ - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - return getDelegate().authenticate(p); - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - return getDelegate().getRoles(p); - } - - /** {@inheritDoc} */ - @Override - public boolean hasRole(final Principal principal, final String role) { - return getDelegate().hasRole(principal, role); - } - - /** {@inheritDoc} */ - public String toString() { - return getName(); - } - - /** {@inheritDoc} */ - @Override - public String getInfo() { - return getClass().getName() + "/1.0"; - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return getClass().getSimpleName(); - } - - /** {@inheritDoc} */ - @Override - protected String getPassword(final String username) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override - protected Principal getPrincipal(final String username) { - throw new UnsupportedOperationException(); - } - - /** - * @return Delegate that all {@link CasRealm} operations are delegated to. - */ - protected abstract CasRealm getDelegate(); -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLifecycleValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLifecycleValve.java deleted file mode 100644 index 635b87be2..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLifecycleValve.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.Lifecycle; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.util.LifecycleSupport; -import org.apache.catalina.valves.ValveBase; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base Valve implementation for valves that need Catalina lifecycle - * management, including {@link #start()} and {@link #stop()} methods. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractLifecycleValve extends ValveBase implements Lifecycle { - - /** Logger instance */ - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - /** Lifecycle listeners */ - private final LifecycleSupport lifecycle = new LifecycleSupport(this); - - /** {@inheritDoc} */ - @Override - public void addLifecycleListener(final LifecycleListener listener) { - lifecycle.addLifecycleListener(listener); - } - - /** {@inheritDoc} */ - @Override - public LifecycleListener[] findLifecycleListeners() { - return lifecycle.findLifecycleListeners(); - } - - /** {@inheritDoc} */ - @Override - public void removeLifecycleListener(final LifecycleListener listener) { - lifecycle.removeLifecycleListener(listener); - } - - /** {@inheritDoc} */ - @Override - public void start() throws LifecycleException { - logger.debug("{} starting.", getName()); - } - - /** {@inheritDoc} */ - @Override - public void stop() throws LifecycleException { - logger.debug("{} stopping.", getName()); - } - - /** - * @return Descriptive valve name. - */ - protected abstract String getName(); -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLogoutValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLogoutValve.java deleted file mode 100644 index c2c38e011..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AbstractLogoutValve.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.jasig.cas.client.tomcat.LogoutHandler; - -/** - * Abstract base class for Container-managed log out. Removes the attributes - * from the session. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractLogoutValve extends AbstractLifecycleValve { - @Override - public final void invoke(final Request request, final Response response) throws IOException, ServletException { - if (getLogoutHandler().isLogoutRequest(request)) { - getLogoutHandler().logout(request, response); - // Do not proceed up valve chain - return; - } - - logger.debug("URI is not a logout request: {}", request.getRequestURI()); - getNext().invoke(request, response); - } - - protected abstract LogoutHandler getLogoutHandler(); -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AssertionCasRealm.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AssertionCasRealm.java deleted file mode 100644 index 979050f17..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/AssertionCasRealm.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.AssertionCasRealmDelegate; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Tomcat Realm that implements {@link CasRealm} for principal and - * role data backed by the CAS {@link org.jasig.cas.client.validation.Assertion}. - *

- * Authentication always succeeds and simply returns the given principal. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public class AssertionCasRealm extends AbstractCasRealm { - - private final AssertionCasRealmDelegate delegate = new AssertionCasRealmDelegate(); - - /** {@inheritDoc} */ - @Override - public void start() throws LifecycleException { - super.start(); - logger.info("Startup completed."); - } - - /** - * @param name Name of the attribute in the principal that contains role data. - */ - public void setRoleAttributeName(final String name) { - this.delegate.setRoleAttributeName(name); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return this.delegate; - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas10CasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas10CasAuthenticator.java deleted file mode 100644 index 3d22b849a..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas10CasAuthenticator.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas10TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles CAS 1.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public class Cas10CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS10"; - - private static final String NAME = Cas10CasAuthenticator.class.getName(); - - private Cas10TicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - public void start() throws LifecycleException { - super.start(); - this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix()); - lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20CasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20CasAuthenticator.java deleted file mode 100644 index f07b72970..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20CasAuthenticator.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20"; - - private static final String NAME = Cas20CasAuthenticator.class.getName(); - - private Cas20ServiceTicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - public void start() throws LifecycleException { - super.start(); - this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix()); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setRenew(isRenew()); - lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20ProxyCasAuthenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20ProxyCasAuthenticator.java deleted file mode 100644 index 15f91b03e..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Cas20ProxyCasAuthenticator.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Cas20ProxyTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol with proxying support. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20-PROXY"; - - private static final String NAME = Cas20ProxyCasAuthenticator.class.getName(); - - private Cas20ProxyTicketValidator ticketValidator; - - private boolean acceptAnyProxy; - - private String allowedProxyChains; - - public void setAcceptAnyProxy(final boolean acceptAnyProxy) { - this.acceptAnyProxy = acceptAnyProxy; - } - - public void setAllowedProxyChains(final String allowedProxyChains) { - this.allowedProxyChains = allowedProxyChains; - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - public void start() throws LifecycleException { - super.start(); - this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix()); - this.ticketValidator.setRenew(isRenew()); - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy); - this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains)); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/PropertiesCasRealm.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/PropertiesCasRealm.java deleted file mode 100644 index a851fe374..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/PropertiesCasRealm.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.tomcat.PropertiesCasRealmDelegate; - -/** - * Tomcat Realm that implements {@link CasRealm} backed by properties file - * containing usernames/and roles of the following format: - *

- * username1=role1,role2,role3
- * username2=role1
- * username3=role2,role3
- * 
- * User authentication succeeds if the name of the given principal exists as - * a username in the properties file. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class PropertiesCasRealm extends AbstractCasRealm { - - private final PropertiesCasRealmDelegate delegate = new PropertiesCasRealmDelegate(); - - /** - * @param path Path to properties file container username/role data. - */ - public void setPropertiesFilePath(final String path) { - this.delegate.setPropertiesFilePath(path); - } - - /** {@inheritDoc} */ - @Override - public void start() throws LifecycleException { - super.start(); - this.delegate.readProperties(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return this.delegate; - } - -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/ProxyCallbackValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/ProxyCallbackValve.java deleted file mode 100644 index b50a14908..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/ProxyCallbackValve.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; - -/** - * Handles watching a url for the proxy callback. - *

- * Because its tough to share state between valves, we expose the storage mechanism via a static variable. - *

- * This valve should be ordered before the authentication valves. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class ProxyCallbackValve extends AbstractLifecycleValve { - - private static final String NAME = ProxyCallbackValve.class.getName(); - - private static ProxyGrantingTicketStorage PROXY_GRANTING_TICKET_STORAGE; - - private String proxyGrantingTicketStorageClass; - - private String proxyCallbackUrl; - - public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return PROXY_GRANTING_TICKET_STORAGE; - } - - public void setProxyGrantingTicketStorageClass(final String proxyGrantingTicketStorageClass) { - this.proxyGrantingTicketStorageClass = proxyGrantingTicketStorageClass; - } - - public void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - public void start() throws LifecycleException { - super.start(); - - try { - CommonUtils.assertNotNull(this.proxyCallbackUrl, "the proxy callback url cannot be null"); - CommonUtils.assertTrue(this.proxyCallbackUrl.startsWith("/"), "proxy callback url must start with \"/\""); - - PROXY_GRANTING_TICKET_STORAGE = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); - } catch (final Exception e) { - throw new LifecycleException(e); - } - logger.info("Startup completed."); - } - - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.proxyCallbackUrl.equals(request.getRequestURI())) { - logger.debug("Processing proxy callback request."); - CommonUtils.readAndRespondToProxyReceptorRequest(request, response, PROXY_GRANTING_TICKET_STORAGE); - return; - } - - getNext().invoke(request, response); - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return NAME; - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/RegexUriLogoutValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/RegexUriLogoutValve.java deleted file mode 100644 index 4d7383f3d..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/RegexUriLogoutValve.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.RegexUriLogoutHandler; - -/** - * Performs CAS logout when the request URI matches a regular expression. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class RegexUriLogoutValve extends AbstractLogoutValve { - - private static final String NAME = RegexUriLogoutValve.class.getName(); - - private final RegexUriLogoutHandler logoutHandler = new RegexUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUriRegex(final String regex) { - this.logoutHandler.setLogoutUriRegex(regex); - } - - @Override - public void start() throws LifecycleException { - super.start(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return NAME; - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Saml11Authenticator.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Saml11Authenticator.java deleted file mode 100644 index 7eaef3da1..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/Saml11Authenticator.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Saml11TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * CAS authenticator that uses the SAML 1.1 protocol. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class Saml11Authenticator extends AbstractAuthenticator { - - public static final String AUTH_METHOD = "SAML11"; - - private static final String NAME = Saml11Authenticator.class.getName(); - - private Saml11TicketValidator ticketValidator; - - /** SAML protocol clock drift tolerance in ms */ - private int tolerance = -1; - - /** - * @param ms SAML clock drift tolerance in milliseconds. - */ - public void setTolerance(final int ms) { - this.tolerance = ms; - } - - @Override - public void start() throws LifecycleException { - super.start(); - this.ticketValidator = new Saml11TicketValidator(getCasServerUrlPrefix()); - if (this.tolerance > -1) { - this.ticketValidator.setTolerance(this.tolerance); - } - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setRenew(isRenew()); - lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); - logger.info("Startup completed."); - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - /** {@inheritDoc} */ - @Override - protected String getArtifactParameterName() { - return "SAMLart"; - } - - /** {@inheritDoc} */ - @Override - protected String getServiceParameterName() { - return "TARGET"; - } - - @Override - protected String getName() { - return NAME; - } - -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/SingleSignOutValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/SingleSignOutValve.java deleted file mode 100644 index ae0f4075d..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/SingleSignOutValve.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.Session; -import org.apache.catalina.SessionEvent; -import org.apache.catalina.SessionListener; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.jasig.cas.client.session.SessionMappingStorage; -import org.jasig.cas.client.session.SingleSignOutHandler; - -/** - * Handles logout request messages sent from the CAS server by ending the current - * HTTP session. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class SingleSignOutValve extends AbstractLifecycleValve implements SessionListener { - - private static final String NAME = SingleSignOutValve.class.getName(); - - private final SingleSignOutHandler handler = new SingleSignOutHandler(); - - public void setArtifactParameterName(final String name) { - this.handler.setArtifactParameterName(name); - } - - public void setLogoutParameterName(final String name) { - this.handler.setLogoutParameterName(name); - } - - public void setRelayStateParameterName(final String name) { - this.handler.setRelayStateParameterName(name); - } - - public void setLogoutCallbackPath(final String logoutCallbackPath) { - this.handler.setLogoutCallbackPath(logoutCallbackPath); - } - - public void setSessionMappingStorage(final SessionMappingStorage storage) { - this.handler.setSessionMappingStorage(storage); - } - - /** {@inheritDoc} */ - @Override - public void start() throws LifecycleException { - super.start(); - this.handler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.handler.process(request, response)) { - getNext().invoke(request, response); - } - } - - /** {@inheritDoc} */ - @Override - public void sessionEvent(final SessionEvent event) { - if (Session.SESSION_DESTROYED_EVENT.equals(event.getType())) { - logger.debug("Cleaning up SessionMappingStorage on destroySession event"); - this.handler.getSessionMappingStorage().removeBySessionById(event.getSession().getId()); - } - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return NAME; - } -} diff --git a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/StaticUriLogoutValve.java b/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/StaticUriLogoutValve.java deleted file mode 100644 index fd0a81172..000000000 --- a/cas-client-integration-tomcat-v6/src/main/java/org/jasig/cas/client/tomcat/v6/StaticUriLogoutValve.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v6; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.StaticUriLogoutHandler; - -/** - * Monitors a specific request URI for logout requests. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class StaticUriLogoutValve extends AbstractLogoutValve { - - private static final String NAME = StaticUriLogoutValve.class.getName(); - - private final StaticUriLogoutHandler logoutHandler = new StaticUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUri(final String logoutUri) { - this.logoutHandler.setLogoutUri(logoutUri); - } - - @Override - public void start() throws LifecycleException { - super.start(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return NAME; - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v7/NOTICE b/cas-client-integration-tomcat-v7/NOTICE deleted file mode 100644 index 40c04de7c..000000000 --- a/cas-client-integration-tomcat-v7/NOTICE +++ /dev/null @@ -1,43 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 7.x Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - tomcat-catalina under Apache License, Version 2.0 - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-tomcat-v7/pom.xml b/cas-client-integration-tomcat-v7/pom.xml deleted file mode 100644 index ff9cfbf2e..000000000 --- a/cas-client-integration-tomcat-v7/pom.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-tomcat-v7 - jar - Jasig CAS Client for Java - Tomcat 7.x Integration - - - - org.jasig.cas.client - cas-client-integration-tomcat-common - ${project.version} - jar - compile - - - org.jasig.cas.client - cas-client-support-saml - ${project.version} - jar - compile - true - - - org.apache.tomcat - tomcat-catalina - 7.0.109 - jar - provided - - - org.apache.tomcat - tomcat-servlet-api - - - org.apache.tomcat - tomcat-juli - - - org.apache.tomcat - tomcat-annotations-api - - - org.apache.tomcat - tomcat-api - - - org.apache.tomcat - tomcat-util - - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - jar - compile - - - - diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractAuthenticator.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractAuthenticator.java deleted file mode 100644 index 4ac52096f..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractAuthenticator.java +++ /dev/null @@ -1,203 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import java.io.IOException; -import java.security.Principal; -import javax.servlet.http.HttpServletResponse; -import org.apache.catalina.*; -import org.apache.catalina.authenticator.AuthenticatorBase; -import org.apache.catalina.connector.Request; -import org.apache.catalina.deploy.LoginConfig; -import org.jasig.cas.client.tomcat.AuthenticatorDelegate; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base authenticator for all authentication protocols supported by CAS. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractAuthenticator extends AuthenticatorBase implements LifecycleListener { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - private final AuthenticatorDelegate delegate = new AuthenticatorDelegate(); - - private String casServerUrlPrefix; - - private String encoding; - - private boolean encode; - - private boolean renew; - - protected abstract String getAuthenticationMethod(); - - /** - * Provided for Tomcat 7.0.8 support. - * - * @return the authentication method. - */ - @Override - protected String getAuthMethod() { - return getAuthenticationMethod(); - } - - /** - * Abstract method that subclasses should use to provide the name of the artifact parameter (i.e. ticket) - * - * @return the artifact parameter name. CANNOT be NULL. - */ - protected abstract String getArtifactParameterName(); - - /** - * Abstract method that subclasses should use to provide the name of the service parameter (i.e. service) - * - * @return the service parameter name. CANNOT be NULL. - */ - protected abstract String getServiceParameterName(); - - /** - * Returns the single instance of the ticket validator to use to validate tickets. Sub classes should include - * the one appropriate for the - * - * @return a fully configured ticket validator. CANNOT be NULL. - */ - protected abstract TicketValidator getTicketValidator(); - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.debug("{} starting.", getName()); - final Realm realm = this.context.getRealm(); - try { - CommonUtils.assertTrue(realm instanceof CasRealm, "Expected CasRealm but got " + realm.getInfo()); - CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null."); - CommonUtils.assertNotNull(this.delegate.getCasServerLoginUrl(), "casServerLoginUrl cannot be null."); - CommonUtils.assertTrue(this.delegate.getServerName() != null || this.delegate.getServiceUrl() != null, - "either serverName or serviceUrl must be set."); - this.delegate.setRealm((CasRealm) realm); - } catch (final Exception e) { - throw new LifecycleException(e); - } - // Complete delegate initialization after the component is started. - // See #lifecycleEvent() method. - addLifecycleListener(this); - } - - protected final String getCasServerUrlPrefix() { - return this.casServerUrlPrefix; - } - - public final void setCasServerUrlPrefix(final String casServerUrlPrefix) { - this.casServerUrlPrefix = casServerUrlPrefix; - } - - public final void setCasServerLoginUrl(final String casServerLoginUrl) { - this.delegate.setCasServerLoginUrl(casServerLoginUrl); - } - - public final boolean isEncode() { - return this.encode; - } - - public final void setEncode(final boolean encode) { - this.encode = encode; - } - - protected final boolean isRenew() { - return this.renew; - } - - public void setRenew(final boolean renew) { - this.renew = renew; - } - - public final void setServerName(final String serverName) { - this.delegate.setServerName(serverName); - } - - public final void setServiceUrl(final String serviceUrl) { - this.delegate.setServiceUrl(serviceUrl); - } - - protected final String getEncoding() { - return this.encoding; - } - - public final void setEncoding(final String encoding) { - this.encoding = encoding; - } - - /** {@inheritDoc} */ - @Override - public final boolean authenticate(final Request request, final HttpServletResponse response, - final LoginConfig loginConfig) throws IOException { - Principal principal = request.getUserPrincipal(); - boolean result = false; - if (principal == null) { - // Authentication sets the response headers for status and redirect if needed - principal = this.delegate.authenticate(request.getRequest(), response); - if (principal != null) { - register(request, response, principal, getAuthenticationMethod(), null, null); - result = true; - } - } else { - result = true; - } - return result; - } - - /** {@inheritDoc} */ - @Override - public void lifecycleEvent(final LifecycleEvent event) { - if (AFTER_START_EVENT.equals(event.getType())) { - logger.debug("{} processing lifecycle event {}", getName(), AFTER_START_EVENT); - this.delegate.setTicketValidator(getTicketValidator()); - this.delegate.setArtifactParameterName(getArtifactParameterName()); - this.delegate.setServiceParameterName(getServiceParameterName()); - } - } - - /** {@inheritDoc} */ - @Override - public String getInfo() { - return getName() + "/1.0"; - } - - /** {@inheritDoc} */ - @Override - protected synchronized void setState(final LifecycleState state, final Object data) throws LifecycleException { - super.setState(state, data); - if (LifecycleState.STARTED.equals(state)) { - logger.info("{} started.", getName()); - } - } - - /** - * @return Authenticator descriptive name. - */ - protected abstract String getName(); -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractCasAuthenticator.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractCasAuthenticator.java deleted file mode 100644 index 40218cef0..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractCasAuthenticator.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -/** - * Base class for all CAS protocol authenticators. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractCasAuthenticator extends AbstractAuthenticator { - - private String proxyCallbackUrl; - - protected final String getProxyCallbackUrl() { - return this.proxyCallbackUrl; - } - - public final void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected final String getArtifactParameterName() { - return "ticket"; - } - - @Override - protected final String getServiceParameterName() { - return "service"; - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractCasRealm.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractCasRealm.java deleted file mode 100644 index 366ab98b1..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractCasRealm.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import java.security.Principal; -import org.apache.catalina.Wrapper; -import org.apache.catalina.realm.RealmBase; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Base Realm implementation for all CAS realms. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractCasRealm extends RealmBase implements CasRealm { - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - return getDelegate().authenticate(p); - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - return getDelegate().getRoles(p); - } - - @Override - public boolean hasRole(final Principal principal, final String role) { - return getDelegate().hasRole(principal, role); - } - - /** - * Tomcat 7.0.8 changed their APIs so {@link #hasRole(java.security.Principal, String)} is only valid for 7.0.7 and below. - */ - @Override - public boolean hasRole(final Wrapper wrapper, final Principal principal, final String role) { - return hasRole(principal, role); - } - - /** {@inheritDoc} */ - public String toString() { - return getName(); - } - - /** {@inheritDoc} */ - @Override - public String getInfo() { - return getClass().getName() + "/1.0"; - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return getClass().getSimpleName(); - } - - /** {@inheritDoc} */ - @Override - protected String getPassword(final String userName) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override - protected Principal getPrincipal(final String userName) { - throw new UnsupportedOperationException(); - } - - /** - * @return Delegate that all {@link CasRealm} operations are delegated to. - */ - protected abstract CasRealm getDelegate(); -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractLogoutValve.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractLogoutValve.java deleted file mode 100644 index fc44a6463..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AbstractLogoutValve.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Abstract base class for Container-managed log out. Removes the attributes - * from the session. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractLogoutValve extends ValveBase { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - @Override - public final void invoke(final Request request, final Response response) throws IOException, ServletException { - if (getLogoutHandler().isLogoutRequest(request)) { - getLogoutHandler().logout(request, response); - // Do not proceed up valve chain - return; - } - - logger.debug("URI is not a logout request: {}", request.getRequestURI()); - getNext().invoke(request, response); - } - - protected abstract LogoutHandler getLogoutHandler(); -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AssertionCasRealm.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AssertionCasRealm.java deleted file mode 100644 index 202ca3a88..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/AssertionCasRealm.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.jasig.cas.client.tomcat.AssertionCasRealmDelegate; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Tomcat Realm that implements {@link CasRealm} for principal and - * role data backed by the CAS {@link org.jasig.cas.client.validation.Assertion}. - *

- * Authentication always succeeds and simply returns the given principal. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public class AssertionCasRealm extends AbstractCasRealm { - - private final AssertionCasRealmDelegate delegate = new AssertionCasRealmDelegate(); - - /** - * @param name Name of the attribute in the principal that contains role data. - */ - public void setRoleAttributeName(final String name) { - delegate.setRoleAttributeName(name); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return delegate; - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas10CasAuthenticator.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas10CasAuthenticator.java deleted file mode 100644 index 9310b1d69..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas10CasAuthenticator.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas10TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles CAS 1.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas10CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS10"; - - private static final String NAME = Cas10CasAuthenticator.class.getName(); - - private Cas10TicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix()); - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas20CasAuthenticator.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas20CasAuthenticator.java deleted file mode 100644 index be0632c34..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas20CasAuthenticator.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20"; - - private static final String NAME = Cas20CasAuthenticator.class.getName(); - - private Cas20ServiceTicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix()); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setRenew(isRenew()); - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas20ProxyCasAuthenticator.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas20ProxyCasAuthenticator.java deleted file mode 100644 index 43337f5cc..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Cas20ProxyCasAuthenticator.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Cas20ProxyTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol with proxying support. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20-PROXY"; - - private static final String NAME = Cas20ProxyCasAuthenticator.class.getName(); - - private Cas20ProxyTicketValidator ticketValidator; - - private boolean acceptAnyProxy; - - private String allowedProxyChains; - - public void setAcceptAnyProxy(final boolean acceptAnyProxy) { - this.acceptAnyProxy = acceptAnyProxy; - } - - public void setAllowedProxyChains(final String allowedProxyChains) { - this.allowedProxyChains = allowedProxyChains; - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix()); - this.ticketValidator.setRenew(isRenew()); - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy); - this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains)); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/PropertiesCasRealm.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/PropertiesCasRealm.java deleted file mode 100644 index 0263f3893..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/PropertiesCasRealm.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.tomcat.PropertiesCasRealmDelegate; - -/** - * Tomcat Realm that implements {@link CasRealm} backed by properties file - * containing usernames/and roles of the following format: - *

- * username1=role1,role2,role3
- * username2=role1
- * username3=role2,role3
- * 
- * User authentication succeeds if the name of the given principal exists as - * a username in the properties file. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class PropertiesCasRealm extends AbstractCasRealm { - - private final PropertiesCasRealmDelegate delegate = new PropertiesCasRealmDelegate(); - - /** - * @param path Path to properties file container username/role data. - */ - public void setPropertiesFilePath(final String path) { - this.delegate.setPropertiesFilePath(path); - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.delegate.readProperties(); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return this.delegate; - } - -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/ProxyCallbackValve.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/ProxyCallbackValve.java deleted file mode 100644 index 7ff3ec8ad..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/ProxyCallbackValve.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles watching a url for the proxy callback. - *

- * Because its tough to share state between valves, we expose the storage mechanism via a static variable. - *

- * This valve should be ordered before the authentication valves. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class ProxyCallbackValve extends ValveBase { - - private static ProxyGrantingTicketStorage PROXY_GRANTING_TICKET_STORAGE; - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private String proxyGrantingTicketStorageClass; - - private String proxyCallbackUrl; - - public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return PROXY_GRANTING_TICKET_STORAGE; - } - - public void setProxyGrantingTicketStorageClass(final String proxyGrantingTicketStorageClass) { - this.proxyGrantingTicketStorageClass = proxyGrantingTicketStorageClass; - } - - public void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - - try { - CommonUtils.assertNotNull(this.proxyCallbackUrl, "the proxy callback url cannot be null"); - CommonUtils.assertTrue(this.proxyCallbackUrl.startsWith("/"), "proxy callback url must start with \"/\""); - - PROXY_GRANTING_TICKET_STORAGE = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); - } catch (final Exception e) { - throw new LifecycleException(e); - } - logger.info("Startup completed."); - } - - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.proxyCallbackUrl.equals(request.getRequestURI())) { - logger.debug("Processing proxy callback request."); - CommonUtils.readAndRespondToProxyReceptorRequest(request, response, PROXY_GRANTING_TICKET_STORAGE); - return; - } - - getNext().invoke(request, response); - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/RegexUriLogoutValve.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/RegexUriLogoutValve.java deleted file mode 100644 index 191b76f0f..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/RegexUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.RegexUriLogoutHandler; - -/** - * Performs CAS logout when the request URI matches a regular expression. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class RegexUriLogoutValve extends AbstractLogoutValve { - - private final RegexUriLogoutHandler logoutHandler = new RegexUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUriRegex(final String regex) { - this.logoutHandler.setLogoutUriRegex(regex); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Saml11Authenticator.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Saml11Authenticator.java deleted file mode 100644 index d4ee9eb59..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/Saml11Authenticator.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Saml11TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * CAS authenticator that uses the SAML 1.1 protocol. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class Saml11Authenticator extends AbstractAuthenticator { - - public static final String AUTH_METHOD = "SAML11"; - - private static final String NAME = Saml11Authenticator.class.getName(); - - private Saml11TicketValidator ticketValidator; - - /** SAML protocol clock drift tolerance in ms */ - private int tolerance = -1; - - /** - * @param ms SAML clock drift tolerance in milliseconds. - */ - public void setTolerance(final int ms) { - this.tolerance = ms; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Saml11TicketValidator(getCasServerUrlPrefix()); - if (this.tolerance > -1) { - this.ticketValidator.setTolerance(this.tolerance); - } - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setRenew(isRenew()); - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - /** {@inheritDoc} */ - @Override - protected String getArtifactParameterName() { - return "SAMLart"; - } - - /** {@inheritDoc} */ - @Override - protected String getServiceParameterName() { - return "TARGET"; - } - - @Override - protected String getName() { - return NAME; - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/SingleSignOutValve.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/SingleSignOutValve.java deleted file mode 100644 index f641dc19e..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/SingleSignOutValve.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.Session; -import org.apache.catalina.SessionEvent; -import org.apache.catalina.SessionListener; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.session.SessionMappingStorage; -import org.jasig.cas.client.session.SingleSignOutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles logout request messages sent from the CAS server by ending the current - * HTTP session. - * - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - * - */ -public class SingleSignOutValve extends ValveBase implements SessionListener { - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final SingleSignOutHandler handler = new SingleSignOutHandler(); - - public void setArtifactParameterName(final String name) { - this.handler.setArtifactParameterName(name); - } - - public void setLogoutParameterName(final String name) { - this.handler.setLogoutParameterName(name); - } - - public void setRelayStateParameterName(final String name) { - this.handler.setRelayStateParameterName(name); - } - - public void setLogoutCallbackPath(final String logoutCallbackPath) { - this.handler.setLogoutCallbackPath(logoutCallbackPath); - } - - public void setSessionMappingStorage(final SessionMappingStorage storage) { - this.handler.setSessionMappingStorage(storage); - } - - /** {@inheritDoc} */ - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.handler.process(request, response)) { - getNext().invoke(request, response); - } - } - - /** {@inheritDoc} */ - @Override - public void sessionEvent(final SessionEvent event) { - if (Session.SESSION_DESTROYED_EVENT.equals(event.getType())) { - logger.debug("Cleaning up SessionMappingStorage on destroySession event"); - this.handler.getSessionMappingStorage().removeBySessionById(event.getSession().getId()); - } - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.info("Starting..."); - this.handler.init(); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/StaticUriLogoutValve.java b/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/StaticUriLogoutValve.java deleted file mode 100644 index 36aec72e5..000000000 --- a/cas-client-integration-tomcat-v7/src/main/java/org/jasig/cas/client/tomcat/v7/StaticUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v7; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.StaticUriLogoutHandler; - -/** - * Monitors a specific request URI for logout requests. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class StaticUriLogoutValve extends AbstractLogoutValve { - - private final StaticUriLogoutHandler logoutHandler = new StaticUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUri(final String logoutUri) { - this.logoutHandler.setLogoutUri(logoutUri); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v8/NOTICE b/cas-client-integration-tomcat-v8/NOTICE deleted file mode 100644 index c8946ad28..000000000 --- a/cas-client-integration-tomcat-v8/NOTICE +++ /dev/null @@ -1,49 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 8.x Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - tomcat-catalina under Apache License, Version 2.0 - tomcat-coyote under Apache License, Version 2.0 - tomcat-el-api under Apache License, Version 2.0 - tomcat-jaspic-api under Apache License, Version 2.0 - tomcat-jni under Apache License, Version 2.0 - tomcat-jsp-api under Apache License, Version 2.0 - tomcat-util-scan under Apache License, Version 2.0 - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-tomcat-v8/pom.xml b/cas-client-integration-tomcat-v8/pom.xml deleted file mode 100644 index 073c86e27..000000000 --- a/cas-client-integration-tomcat-v8/pom.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-tomcat-v8 - jar - Jasig CAS Client for Java - Tomcat 8.x Integration - - - - org.jasig.cas.client - cas-client-integration-tomcat-common - ${project.version} - jar - compile - - - org.jasig.cas.client - cas-client-support-saml - ${project.version} - jar - compile - true - - - org.apache.tomcat - tomcat-catalina - 8.5.73 - jar - provided - - - org.apache.tomcat - tomcat-servlet-api - - - org.apache.tomcat - tomcat-juli - - - org.apache.tomcat - tomcat-annotations-api - - - org.apache.tomcat - tomcat-api - - - org.apache.tomcat - tomcat-util - - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - jar - compile - - - - diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractAuthenticator.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractAuthenticator.java deleted file mode 100644 index 5280a5918..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractAuthenticator.java +++ /dev/null @@ -1,207 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletResponse; - -import org.apache.catalina.LifecycleEvent; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.LifecycleState; -import org.apache.catalina.Realm; -import org.apache.catalina.authenticator.AuthenticatorBase; -import org.apache.catalina.connector.Request; -import org.jasig.cas.client.tomcat.AuthenticatorDelegate; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base authenticator for all authentication protocols supported by CAS. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractAuthenticator extends AuthenticatorBase implements LifecycleListener { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - private final AuthenticatorDelegate delegate = new AuthenticatorDelegate(); - - private String casServerUrlPrefix; - - private String encoding; - - private boolean encode; - - private boolean renew; - - protected abstract String getAuthenticationMethod(); - - /** - * Provided for Tomcat 7.0.8 support. - * - * @return the authentication method. - */ - @Override - protected String getAuthMethod() { - return getAuthenticationMethod(); - } - - /** - * Abstract method that subclasses should use to provide the name of the artifact parameter (i.e. ticket) - * - * @return the artifact parameter name. CANNOT be NULL. - */ - protected abstract String getArtifactParameterName(); - - /** - * Abstract method that subclasses should use to provide the name of the service parameter (i.e. service) - * - * @return the service parameter name. CANNOT be NULL. - */ - protected abstract String getServiceParameterName(); - - /** - * Returns the single instance of the ticket validator to use to validate tickets. Sub classes should include - * the one appropriate for the - * - * @return a fully configured ticket validator. CANNOT be NULL. - */ - protected abstract TicketValidator getTicketValidator(); - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.debug("{} starting.", getName()); - final Realm realm = getContainer().getRealm(); - try { - CommonUtils.assertTrue(realm instanceof CasRealm, "Expected CasRealm but got " + realm.getClass()); - CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null."); - CommonUtils.assertNotNull(this.delegate.getCasServerLoginUrl(), "casServerLoginUrl cannot be null."); - CommonUtils.assertTrue(this.delegate.getServerName() != null || this.delegate.getServiceUrl() != null, - "either serverName or serviceUrl must be set."); - this.delegate.setRealm((CasRealm) realm); - } catch (final Exception e) { - throw new LifecycleException(e); - } - // Complete delegate initialization after the component is started. - // See #lifecycleEvent() method. - addLifecycleListener(this); - } - - protected final String getCasServerUrlPrefix() { - return this.casServerUrlPrefix; - } - - public final void setCasServerUrlPrefix(final String casServerUrlPrefix) { - this.casServerUrlPrefix = casServerUrlPrefix; - } - - public final void setCasServerLoginUrl(final String casServerLoginUrl) { - this.delegate.setCasServerLoginUrl(casServerLoginUrl); - } - - public final boolean isEncode() { - return this.encode; - } - - public final void setEncode(final boolean encode) { - this.encode = encode; - } - - protected final boolean isRenew() { - return this.renew; - } - - public void setRenew(final boolean renew) { - this.renew = renew; - } - - public final void setServerName(final String serverName) { - this.delegate.setServerName(serverName); - } - - public final void setServiceUrl(final String serviceUrl) { - this.delegate.setServiceUrl(serviceUrl); - } - - protected final String getEncoding() { - return this.encoding; - } - - public final void setEncoding(final String encoding) { - this.encoding = encoding; - } - - /** {@inheritDoc} */ - @Override - public final boolean doAuthenticate(final Request request, final HttpServletResponse response) throws IOException { - Principal principal = request.getUserPrincipal(); - boolean result = false; - if (principal == null) { - // Authentication sets the response headers for status and redirect if needed - principal = this.delegate.authenticate(request.getRequest(), response); - if (principal != null) { - register(request, response, principal, getAuthenticationMethod(), null, null); - result = true; - } - } else { - result = true; - } - return result; - } - - /** {@inheritDoc} */ - @Override - public void lifecycleEvent(final LifecycleEvent event) { - if (AFTER_START_EVENT.equals(event.getType())) { - logger.debug("{} processing lifecycle event {}", getName(), AFTER_START_EVENT); - this.delegate.setTicketValidator(getTicketValidator()); - this.delegate.setArtifactParameterName(getArtifactParameterName()); - this.delegate.setServiceParameterName(getServiceParameterName()); - } - } - - /** {@inheritDoc} */ - public String getInfo() { - return getName() + "/1.0"; - } - - /** {@inheritDoc} - * @throws LifecycleException */ - @Override - protected synchronized void setState(final LifecycleState state, final Object data) throws LifecycleException { - super.setState(state, data); - if (LifecycleState.STARTED.equals(state)) { - logger.info("{} started.", getName()); - } - } - - /** - * @return Authenticator descriptive name. - */ - protected abstract String getName(); -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractCasAuthenticator.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractCasAuthenticator.java deleted file mode 100644 index 9c2471a0e..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractCasAuthenticator.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -/** - * Base class for all CAS protocol authenticators. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractCasAuthenticator extends AbstractAuthenticator { - - private String proxyCallbackUrl; - - protected final String getProxyCallbackUrl() { - return this.proxyCallbackUrl; - } - - public final void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected final String getArtifactParameterName() { - return "ticket"; - } - - @Override - protected final String getServiceParameterName() { - return "service"; - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractCasRealm.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractCasRealm.java deleted file mode 100644 index 8e1250207..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractCasRealm.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import java.security.Principal; -import org.apache.catalina.Wrapper; -import org.apache.catalina.realm.RealmBase; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Base Realm implementation for all CAS realms. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractCasRealm extends RealmBase implements CasRealm { - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - return getDelegate().authenticate(p); - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - return getDelegate().getRoles(p); - } - - @Override - public boolean hasRole(final Principal principal, final String role) { - return getDelegate().hasRole(principal, role); - } - - /** - * Tomcat 7.0.8 changed their APIs so {@link #hasRole(java.security.Principal, String)} is only valid for 7.0.7 and below. - */ - @Override - public boolean hasRole(final Wrapper wrapper, final Principal principal, final String role) { - return hasRole(principal, role); - } - - /** {@inheritDoc} */ - public String toString() { - return getName(); - } - - /** {@inheritDoc} */ - public String getInfo() { - return getClass().getName() + "/1.0"; - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return getClass().getSimpleName(); - } - - /** {@inheritDoc} */ - @Override - protected String getPassword(final String userName) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override - protected Principal getPrincipal(final String userName) { - throw new UnsupportedOperationException(); - } - - /** - * @return Delegate that all {@link CasRealm} operations are delegated to. - */ - protected abstract CasRealm getDelegate(); -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractLogoutValve.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractLogoutValve.java deleted file mode 100644 index 007b69e8b..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AbstractLogoutValve.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Abstract base class for Container-managed log out. Removes the attributes - * from the session. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractLogoutValve extends ValveBase { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - @Override - public final void invoke(final Request request, final Response response) throws IOException, ServletException { - if (getLogoutHandler().isLogoutRequest(request)) { - getLogoutHandler().logout(request, response); - // Do not proceed up valve chain - return; - } - - logger.debug("URI is not a logout request: {}", request.getRequestURI()); - getNext().invoke(request, response); - } - - protected abstract LogoutHandler getLogoutHandler(); -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AssertionCasRealm.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AssertionCasRealm.java deleted file mode 100644 index 67f168eee..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/AssertionCasRealm.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.jasig.cas.client.tomcat.AssertionCasRealmDelegate; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Tomcat Realm that implements {@link CasRealm} for principal and - * role data backed by the CAS {@link org.jasig.cas.client.validation.Assertion}. - *

- * Authentication always succeeds and simply returns the given principal. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public class AssertionCasRealm extends AbstractCasRealm { - - private final AssertionCasRealmDelegate delegate = new AssertionCasRealmDelegate(); - - /** - * @param name Name of the attribute in the principal that contains role data. - */ - public void setRoleAttributeName(final String name) { - delegate.setRoleAttributeName(name); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return delegate; - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas10CasAuthenticator.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas10CasAuthenticator.java deleted file mode 100644 index b39169a36..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas10CasAuthenticator.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas10TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles CAS 1.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas10CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS10"; - - private static final String NAME = Cas10CasAuthenticator.class.getName(); - - private Cas10TicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix()); - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas20CasAuthenticator.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas20CasAuthenticator.java deleted file mode 100644 index 8c238305d..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas20CasAuthenticator.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20"; - - private static final String NAME = Cas20CasAuthenticator.class.getName(); - - private Cas20ServiceTicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix()); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setRenew(isRenew()); - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas20ProxyCasAuthenticator.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas20ProxyCasAuthenticator.java deleted file mode 100644 index a74da37c6..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Cas20ProxyCasAuthenticator.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Cas20ProxyTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol with proxying support. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20-PROXY"; - - private static final String NAME = Cas20ProxyCasAuthenticator.class.getName(); - - private Cas20ProxyTicketValidator ticketValidator; - - private boolean acceptAnyProxy; - - private String allowedProxyChains; - - public void setAcceptAnyProxy(final boolean acceptAnyProxy) { - this.acceptAnyProxy = acceptAnyProxy; - } - - public void setAllowedProxyChains(final String allowedProxyChains) { - this.allowedProxyChains = allowedProxyChains; - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix()); - this.ticketValidator.setRenew(isRenew()); - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy); - this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains)); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/PropertiesCasRealm.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/PropertiesCasRealm.java deleted file mode 100644 index 3e4892254..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/PropertiesCasRealm.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.tomcat.PropertiesCasRealmDelegate; - -/** - * Tomcat Realm that implements {@link CasRealm} backed by properties file - * containing usernames/and roles of the following format: - *

- * username1=role1,role2,role3
- * username2=role1
- * username3=role2,role3
- * 
- * User authentication succeeds if the name of the given principal exists as - * a username in the properties file. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class PropertiesCasRealm extends AbstractCasRealm { - - private final PropertiesCasRealmDelegate delegate = new PropertiesCasRealmDelegate(); - - /** - * @param path Path to properties file container username/role data. - */ - public void setPropertiesFilePath(final String path) { - this.delegate.setPropertiesFilePath(path); - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.delegate.readProperties(); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return this.delegate; - } - -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/ProxyCallbackValve.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/ProxyCallbackValve.java deleted file mode 100644 index 374d05d14..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/ProxyCallbackValve.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles watching a url for the proxy callback. - *

- * Because its tough to share state between valves, we expose the storage mechanism via a static variable. - *

- * This valve should be ordered before the authentication valves. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class ProxyCallbackValve extends ValveBase { - - private static ProxyGrantingTicketStorage PROXY_GRANTING_TICKET_STORAGE; - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private String proxyGrantingTicketStorageClass; - - private String proxyCallbackUrl; - - public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return PROXY_GRANTING_TICKET_STORAGE; - } - - public void setProxyGrantingTicketStorageClass(final String proxyGrantingTicketStorageClass) { - this.proxyGrantingTicketStorageClass = proxyGrantingTicketStorageClass; - } - - public void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - - try { - CommonUtils.assertNotNull(this.proxyCallbackUrl, "the proxy callback url cannot be null"); - CommonUtils.assertTrue(this.proxyCallbackUrl.startsWith("/"), "proxy callback url must start with \"/\""); - - PROXY_GRANTING_TICKET_STORAGE = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); - } catch (final Exception e) { - throw new LifecycleException(e); - } - logger.info("Startup completed."); - } - - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.proxyCallbackUrl.equals(request.getRequestURI())) { - logger.debug("Processing proxy callback request."); - CommonUtils.readAndRespondToProxyReceptorRequest(request, response, PROXY_GRANTING_TICKET_STORAGE); - return; - } - - getNext().invoke(request, response); - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/RegexUriLogoutValve.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/RegexUriLogoutValve.java deleted file mode 100644 index ab6a83964..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/RegexUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.RegexUriLogoutHandler; - -/** - * Performs CAS logout when the request URI matches a regular expression. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class RegexUriLogoutValve extends AbstractLogoutValve { - - private final RegexUriLogoutHandler logoutHandler = new RegexUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUriRegex(final String regex) { - this.logoutHandler.setLogoutUriRegex(regex); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Saml11Authenticator.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Saml11Authenticator.java deleted file mode 100644 index 0b25328ee..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/Saml11Authenticator.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Saml11TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * CAS authenticator that uses the SAML 1.1 protocol. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class Saml11Authenticator extends AbstractAuthenticator { - - public static final String AUTH_METHOD = "SAML11"; - - private static final String NAME = Saml11Authenticator.class.getName(); - - private Saml11TicketValidator ticketValidator; - - /** SAML protocol clock drift tolerance in ms */ - private int tolerance = -1; - - /** - * @param ms SAML clock drift tolerance in milliseconds. - */ - public void setTolerance(final int ms) { - this.tolerance = ms; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Saml11TicketValidator(getCasServerUrlPrefix()); - if (this.tolerance > -1) { - this.ticketValidator.setTolerance(this.tolerance); - } - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setRenew(isRenew()); - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - /** {@inheritDoc} */ - @Override - protected String getArtifactParameterName() { - return "SAMLart"; - } - - /** {@inheritDoc} */ - @Override - protected String getServiceParameterName() { - return "TARGET"; - } - - @Override - protected String getName() { - return NAME; - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/SingleSignOutValve.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/SingleSignOutValve.java deleted file mode 100644 index e47e38fbc..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/SingleSignOutValve.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.Session; -import org.apache.catalina.SessionEvent; -import org.apache.catalina.SessionListener; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.session.SessionMappingStorage; -import org.jasig.cas.client.session.SingleSignOutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles logout request messages sent from the CAS server by ending the current - * HTTP session. - * - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - * - */ -public class SingleSignOutValve extends ValveBase implements SessionListener { - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final SingleSignOutHandler handler = new SingleSignOutHandler(); - - public void setArtifactParameterName(final String name) { - this.handler.setArtifactParameterName(name); - } - - public void setLogoutParameterName(final String name) { - this.handler.setLogoutParameterName(name); - } - - public void setRelayStateParameterName(final String name) { - this.handler.setRelayStateParameterName(name); - } - - public void setLogoutCallbackPath(final String logoutCallbackPath) { - this.handler.setLogoutCallbackPath(logoutCallbackPath); - } - - public void setSessionMappingStorage(final SessionMappingStorage storage) { - this.handler.setSessionMappingStorage(storage); - } - - /** {@inheritDoc} */ - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.handler.process(request, response)) { - getNext().invoke(request, response); - } - } - - /** {@inheritDoc} */ - @Override - public void sessionEvent(final SessionEvent event) { - if (Session.SESSION_DESTROYED_EVENT.equals(event.getType())) { - logger.debug("Cleaning up SessionMappingStorage on destroySession event"); - this.handler.getSessionMappingStorage().removeBySessionById(event.getSession().getId()); - } - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.info("Starting..."); - this.handler.init(); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/StaticUriLogoutValve.java b/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/StaticUriLogoutValve.java deleted file mode 100644 index 23dd629d2..000000000 --- a/cas-client-integration-tomcat-v8/src/main/java/org/jasig/cas/client/tomcat/v8/StaticUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v8; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.StaticUriLogoutHandler; - -/** - * Monitors a specific request URI for logout requests. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class StaticUriLogoutValve extends AbstractLogoutValve { - - private final StaticUriLogoutHandler logoutHandler = new StaticUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUri(final String logoutUri) { - this.logoutHandler.setLogoutUri(logoutUri); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v85/NOTICE b/cas-client-integration-tomcat-v85/NOTICE deleted file mode 100644 index eafc0a8d6..000000000 --- a/cas-client-integration-tomcat-v85/NOTICE +++ /dev/null @@ -1,51 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 8.5.x Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - tomcat-annotations-api under Apache License, Version 2.0 - tomcat-catalina under Apache License, Version 2.0 - tomcat-coyote under Apache License, Version 2.0 - tomcat-el-api under Apache License, Version 2.0 - tomcat-embed-core under Apache License, Version 2.0 - tomcat-jaspic-api under Apache License, Version 2.0 - tomcat-jni under Apache License, Version 2.0 - tomcat-jsp-api under Apache License, Version 2.0 - tomcat-util-scan under Apache License, Version 2.0 - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-tomcat-v85/pom.xml b/cas-client-integration-tomcat-v85/pom.xml deleted file mode 100644 index 34ecb52bb..000000000 --- a/cas-client-integration-tomcat-v85/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-tomcat-v85 - jar - Jasig CAS Client for Java - Tomcat 8.5.x Integration - - - - org.jasig.cas.client - cas-client-integration-tomcat-common - ${project.version} - jar - compile - - - org.jasig.cas.client - cas-client-support-saml - ${project.version} - jar - compile - true - - - org.apache.tomcat.embed - tomcat-embed-core - 8.5.73 - jar - provided - - - org.apache.tomcat - tomcat-catalina - 8.5.73 - jar - provided - - - org.apache.tomcat - tomcat-servlet-api - - - org.apache.tomcat - tomcat-juli - - - org.apache.tomcat - tomcat-annotations-api - - - org.apache.tomcat - tomcat-api - - - org.apache.tomcat - tomcat-util - - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - jar - compile - - - - diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractAuthenticator.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractAuthenticator.java deleted file mode 100644 index 84431c1bf..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractAuthenticator.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletResponse; - -import org.apache.catalina.*; -import org.apache.catalina.authenticator.AuthenticatorBase; -import org.apache.catalina.connector.Request; -import org.jasig.cas.client.tomcat.AuthenticatorDelegate; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base authenticator for all authentication protocols supported by CAS. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractAuthenticator extends AuthenticatorBase implements LifecycleListener { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - private final AuthenticatorDelegate delegate = new AuthenticatorDelegate(); - - private String casServerUrlPrefix; - - private String encoding; - - private boolean encode; - - private boolean renew; - - protected abstract String getAuthenticationMethod(); - - /** - * Provided for Tomcat 7.0.8 support. - * - * @return the authentication method. - */ - @Override - protected String getAuthMethod() { - return getAuthenticationMethod(); - } - - /** - * Abstract method that subclasses should use to provide the name of the artifact parameter (i.e. ticket) - * - * @return the artifact parameter name. CANNOT be NULL. - */ - protected abstract String getArtifactParameterName(); - - /** - * Abstract method that subclasses should use to provide the name of the service parameter (i.e. service) - * - * @return the service parameter name. CANNOT be NULL. - */ - protected abstract String getServiceParameterName(); - - /** - * Returns the single instance of the ticket validator to use to validate tickets. Sub classes should include - * the one appropriate for the - * - * @return a fully configured ticket validator. CANNOT be NULL. - */ - protected abstract TicketValidator getTicketValidator(); - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.debug("{} starting.", getName()); - final Realm realm = this.context.getRealm(); - try { - CommonUtils.assertTrue(realm instanceof CasRealm, "Expected CasRealm but got " + realm.getClass()); - CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null."); - CommonUtils.assertNotNull(this.delegate.getCasServerLoginUrl(), "casServerLoginUrl cannot be null."); - CommonUtils.assertTrue(this.delegate.getServerName() != null || this.delegate.getServiceUrl() != null, - "either serverName or serviceUrl must be set."); - this.delegate.setRealm((CasRealm) realm); - } catch (final Exception e) { - throw new LifecycleException(e); - } - // Complete delegate initialization after the component is started. - // See #lifecycleEvent() method. - addLifecycleListener(this); - } - - protected final String getCasServerUrlPrefix() { - return this.casServerUrlPrefix; - } - - public final void setCasServerUrlPrefix(final String casServerUrlPrefix) { - this.casServerUrlPrefix = casServerUrlPrefix; - } - - public final void setCasServerLoginUrl(final String casServerLoginUrl) { - this.delegate.setCasServerLoginUrl(casServerLoginUrl); - } - - public final boolean isEncode() { - return this.encode; - } - - public final void setEncode(final boolean encode) { - this.encode = encode; - } - - protected final boolean isRenew() { - return this.renew; - } - - public void setRenew(final boolean renew) { - this.renew = renew; - } - - public final void setServerName(final String serverName) { - this.delegate.setServerName(serverName); - } - - public final void setServiceUrl(final String serviceUrl) { - this.delegate.setServiceUrl(serviceUrl); - } - - protected final String getEncoding() { - return this.encoding; - } - - public final void setEncoding(final String encoding) { - this.encoding = encoding; - } - - /** {@inheritDoc} */ - @Override - protected boolean doAuthenticate(final Request request, - final HttpServletResponse httpServletResponse) throws IOException { - Principal principal = request.getUserPrincipal(); - boolean result = false; - if (principal == null) { - // Authentication sets the response headers for status and redirect if needed - principal = this.delegate.authenticate(request.getRequest(), request.getResponse()); - if (principal != null) { - register(request, request.getResponse(), principal, getAuthenticationMethod(), null, null); - result = true; - } - } else { - result = true; - } - return result; - } - - /** {@inheritDoc} */ - @Override - public void lifecycleEvent(final LifecycleEvent event) { - if (AFTER_START_EVENT.equals(event.getType())) { - logger.debug("{} processing lifecycle event {}", getName(), AFTER_START_EVENT); - this.delegate.setTicketValidator(getTicketValidator()); - this.delegate.setArtifactParameterName(getArtifactParameterName()); - this.delegate.setServiceParameterName(getServiceParameterName()); - } - } - - /** {@inheritDoc} */ - public String getInfo() { - return getName() + "/1.0"; - } - - /** {@inheritDoc} - * @throws LifecycleException */ - @Override - protected synchronized void setState(final LifecycleState state, final Object data) throws LifecycleException { - super.setState(state, data); - if (LifecycleState.STARTED.equals(state)) { - logger.info("{} started.", getName()); - } - } - - /** - * @return Authenticator descriptive name. - */ - protected abstract String getName(); -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractCasAuthenticator.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractCasAuthenticator.java deleted file mode 100644 index 1f79bd356..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractCasAuthenticator.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -/** - * Base class for all CAS protocol authenticators. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractCasAuthenticator extends AbstractAuthenticator { - - private String proxyCallbackUrl; - - protected final String getProxyCallbackUrl() { - return this.proxyCallbackUrl; - } - - public final void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected final String getArtifactParameterName() { - return "ticket"; - } - - @Override - protected final String getServiceParameterName() { - return "service"; - } - - -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractCasRealm.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractCasRealm.java deleted file mode 100644 index 73b501c92..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractCasRealm.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import java.security.Principal; -import org.apache.catalina.Wrapper; -import org.apache.catalina.realm.RealmBase; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Base Realm implementation for all CAS realms. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractCasRealm extends RealmBase implements CasRealm { - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - return getDelegate().authenticate(p); - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - return getDelegate().getRoles(p); - } - - @Override - public boolean hasRole(final Principal principal, final String role) { - return getDelegate().hasRole(principal, role); - } - - /** - * Tomcat 7.0.8 changed their APIs so {@link #hasRole(java.security.Principal, String)} is only valid for 7.0.7 and below. - */ - @Override - public boolean hasRole(final Wrapper wrapper, final Principal principal, final String role) { - return hasRole(principal, role); - } - - /** {@inheritDoc} */ - public String toString() { - return getName(); - } - - /** {@inheritDoc} */ - public String getInfo() { - return getClass().getName() + "/1.0"; - } - - /** {@inheritDoc} */ - @Override - protected String getName() { - return getClass().getSimpleName(); - } - - /** {@inheritDoc} */ - @Override - protected String getPassword(final String userName) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override - protected Principal getPrincipal(final String userName) { - throw new UnsupportedOperationException(); - } - - /** - * @return Delegate that all {@link CasRealm} operations are delegated to. - */ - protected abstract CasRealm getDelegate(); -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractLogoutValve.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractLogoutValve.java deleted file mode 100644 index 500a3dcda..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AbstractLogoutValve.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Abstract base class for Container-managed log out. Removes the attributes - * from the session. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractLogoutValve extends ValveBase { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - @Override - public final void invoke(final Request request, final Response response) throws IOException, ServletException { - if (getLogoutHandler().isLogoutRequest(request)) { - getLogoutHandler().logout(request, response); - // Do not proceed up valve chain - return; - } - - logger.debug("URI is not a logout request: {}", request.getRequestURI()); - getNext().invoke(request, response); - } - - protected abstract LogoutHandler getLogoutHandler(); -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AssertionCasRealm.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AssertionCasRealm.java deleted file mode 100644 index bb78db2cf..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/AssertionCasRealm.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.jasig.cas.client.tomcat.AssertionCasRealmDelegate; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Tomcat Realm that implements {@link CasRealm} for principal and - * role data backed by the CAS {@link org.jasig.cas.client.validation.Assertion}. - *

- * Authentication always succeeds and simply returns the given principal. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public class AssertionCasRealm extends AbstractCasRealm { - - private final AssertionCasRealmDelegate delegate = new AssertionCasRealmDelegate(); - - /** - * @param name Name of the attribute in the principal that contains role data. - */ - public void setRoleAttributeName(final String name) { - delegate.setRoleAttributeName(name); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return delegate; - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas10CasAuthenticator.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas10CasAuthenticator.java deleted file mode 100644 index fa9946270..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas10CasAuthenticator.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas10TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles CAS 1.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas10CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS10"; - - private static final String NAME = Cas10CasAuthenticator.class.getName(); - - private Cas10TicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix()); - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas20CasAuthenticator.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas20CasAuthenticator.java deleted file mode 100644 index 9437e2732..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas20CasAuthenticator.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20"; - - private static final String NAME = Cas20CasAuthenticator.class.getName(); - - private Cas20ServiceTicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix()); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setRenew(isRenew()); - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas20ProxyCasAuthenticator.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas20ProxyCasAuthenticator.java deleted file mode 100644 index e49771b7b..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Cas20ProxyCasAuthenticator.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Cas20ProxyTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol with proxying support. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20-PROXY"; - - private static final String NAME = Cas20ProxyCasAuthenticator.class.getName(); - - private Cas20ProxyTicketValidator ticketValidator; - - private boolean acceptAnyProxy; - - private String allowedProxyChains; - - public void setAcceptAnyProxy(final boolean acceptAnyProxy) { - this.acceptAnyProxy = acceptAnyProxy; - } - - public void setAllowedProxyChains(final String allowedProxyChains) { - this.allowedProxyChains = allowedProxyChains; - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix()); - this.ticketValidator.setRenew(isRenew()); - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy); - this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains)); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/PropertiesCasRealm.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/PropertiesCasRealm.java deleted file mode 100644 index 4c1d3d0ea..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/PropertiesCasRealm.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.tomcat.PropertiesCasRealmDelegate; - -/** - * Tomcat Realm that implements {@link CasRealm} backed by properties file - * containing usernames/and roles of the following format: - *

- * username1=role1,role2,role3
- * username2=role1
- * username3=role2,role3
- * 
- * User authentication succeeds if the name of the given principal exists as - * a username in the properties file. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class PropertiesCasRealm extends AbstractCasRealm { - - private final PropertiesCasRealmDelegate delegate = new PropertiesCasRealmDelegate(); - - /** - * @param path Path to properties file container username/role data. - */ - public void setPropertiesFilePath(final String path) { - this.delegate.setPropertiesFilePath(path); - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.delegate.readProperties(); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return this.delegate; - } - -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/ProxyCallbackValve.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/ProxyCallbackValve.java deleted file mode 100644 index 8727946a4..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/ProxyCallbackValve.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles watching a url for the proxy callback. - *

- * Because its tough to share state between valves, we expose the storage mechanism via a static variable. - *

- * This valve should be ordered before the authentication valves. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class ProxyCallbackValve extends ValveBase { - - private static ProxyGrantingTicketStorage PROXY_GRANTING_TICKET_STORAGE; - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private String proxyGrantingTicketStorageClass; - - private String proxyCallbackUrl; - - public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return PROXY_GRANTING_TICKET_STORAGE; - } - - public void setProxyGrantingTicketStorageClass(final String proxyGrantingTicketStorageClass) { - this.proxyGrantingTicketStorageClass = proxyGrantingTicketStorageClass; - } - - public void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - - try { - CommonUtils.assertNotNull(this.proxyCallbackUrl, "the proxy callback url cannot be null"); - CommonUtils.assertTrue(this.proxyCallbackUrl.startsWith("/"), "proxy callback url must start with \"/\""); - - PROXY_GRANTING_TICKET_STORAGE = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); - } catch (final Exception e) { - throw new LifecycleException(e); - } - logger.info("Startup completed."); - } - - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.proxyCallbackUrl.equals(request.getRequestURI())) { - logger.debug("Processing proxy callback request."); - CommonUtils.readAndRespondToProxyReceptorRequest(request, response, PROXY_GRANTING_TICKET_STORAGE); - return; - } - - getNext().invoke(request, response); - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/RegexUriLogoutValve.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/RegexUriLogoutValve.java deleted file mode 100644 index df6542a3c..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/RegexUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.RegexUriLogoutHandler; - -/** - * Performs CAS logout when the request URI matches a regular expression. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class RegexUriLogoutValve extends AbstractLogoutValve { - - private final RegexUriLogoutHandler logoutHandler = new RegexUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUriRegex(final String regex) { - this.logoutHandler.setLogoutUriRegex(regex); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Saml11Authenticator.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Saml11Authenticator.java deleted file mode 100644 index 36ad345f7..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/Saml11Authenticator.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Saml11TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * CAS authenticator that uses the SAML 1.1 protocol. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class Saml11Authenticator extends AbstractAuthenticator { - - public static final String AUTH_METHOD = "SAML11"; - - private static final String NAME = Saml11Authenticator.class.getName(); - - private Saml11TicketValidator ticketValidator; - - /** SAML protocol clock drift tolerance in ms */ - private int tolerance = -1; - - /** - * @param ms SAML clock drift tolerance in milliseconds. - */ - public void setTolerance(final int ms) { - this.tolerance = ms; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Saml11TicketValidator(getCasServerUrlPrefix()); - if (this.tolerance > -1) { - this.ticketValidator.setTolerance(this.tolerance); - } - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setRenew(isRenew()); - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - /** {@inheritDoc} */ - @Override - protected String getArtifactParameterName() { - return "SAMLart"; - } - - /** {@inheritDoc} */ - @Override - protected String getServiceParameterName() { - return "TARGET"; - } - - @Override - protected String getName() { - return NAME; - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/SingleSignOutValve.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/SingleSignOutValve.java deleted file mode 100644 index 519ab3c61..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/SingleSignOutValve.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import java.io.IOException; -import javax.servlet.ServletException; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.Session; -import org.apache.catalina.SessionEvent; -import org.apache.catalina.SessionListener; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.session.SessionMappingStorage; -import org.jasig.cas.client.session.SingleSignOutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Handles logout request messages sent from the CAS server by ending the current - * HTTP session. - * - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - * - */ -public class SingleSignOutValve extends ValveBase implements SessionListener { - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final SingleSignOutHandler handler = new SingleSignOutHandler(); - - public void setArtifactParameterName(final String name) { - this.handler.setArtifactParameterName(name); - } - - public void setLogoutParameterName(final String name) { - this.handler.setLogoutParameterName(name); - } - - public void setRelayStateParameterName(final String name) { - this.handler.setRelayStateParameterName(name); - } - - public void setLogoutCallbackPath(final String logoutCallbackPath) { - this.handler.setLogoutCallbackPath(logoutCallbackPath); - } - - public void setSessionMappingStorage(final SessionMappingStorage storage) { - this.handler.setSessionMappingStorage(storage); - } - - /** {@inheritDoc} */ - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.handler.process(request, response)) { - getNext().invoke(request, response); - } - } - - /** {@inheritDoc} */ - @Override - public void sessionEvent(final SessionEvent event) { - if (Session.SESSION_DESTROYED_EVENT.equals(event.getType())) { - logger.debug("Cleaning up SessionMappingStorage on destroySession event"); - this.handler.getSessionMappingStorage().removeBySessionById(event.getSession().getId()); - } - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.info("Starting..."); - this.handler.init(); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/StaticUriLogoutValve.java b/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/StaticUriLogoutValve.java deleted file mode 100644 index dce92400a..000000000 --- a/cas-client-integration-tomcat-v85/src/main/java/org/jasig/cas/client/tomcat/v85/StaticUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v85; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.StaticUriLogoutHandler; - -/** - * Monitors a specific request URI for logout requests. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class StaticUriLogoutValve extends AbstractLogoutValve { - - private final StaticUriLogoutHandler logoutHandler = new StaticUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUri(final String logoutUri) { - this.logoutHandler.setLogoutUri(logoutUri); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v90/NOTICE b/cas-client-integration-tomcat-v90/NOTICE deleted file mode 100644 index 8d8dc1fd4..000000000 --- a/cas-client-integration-tomcat-v90/NOTICE +++ /dev/null @@ -1,51 +0,0 @@ -Licensed to Apereo under one or more contributor license -agreements. See the NOTICE file distributed with this work -for additional information regarding copyright ownership. -Apereo 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 the following location: - - 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. - -This project includes: - Apache Commons Codec under Apache License, Version 2.0 - Bouncy Castle ASN.1 Extension and Utility APIs under Bouncy Castle Licence - Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence - Bouncy Castle Provider under Bouncy Castle Licence - Hamcrest Core under New BSD License - istack common utility code runtime under CDDL 1.1 or GPL2 w/ CPE - Jackson-annotations under The Apache Software License, Version 2.0 - Jackson-core under The Apache Software License, Version 2.0 - jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Common Tomcat Integration Support under Apache License Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Tomcat 9.0.x Integration under Apache License Version 2.0 - Java Servlet API under CDDL + GPLv2 with classpath exception - JavaBeans Activation Framework API jar under CDDL/GPLv2+CE - JAXB Core under CDDL+GPL License - jaxb-api under CDDL 1.1 or GPL2 w/ CPE - JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 - JUnit under Eclipse Public License 1.0 - SLF4J API Module under MIT License - SLF4J Simple Binding under MIT License - tomcat-annotations-api under Apache License, Version 2.0 - tomcat-catalina under Apache License, Version 2.0 - tomcat-coyote under Apache License, Version 2.0 - tomcat-el-api under Apache License, Version 2.0 - tomcat-embed-core under Apache License, Version 2.0 - tomcat-jaspic-api under Apache License, Version 2.0 - tomcat-jni under Apache License, Version 2.0 - tomcat-jsp-api under Apache License, Version 2.0 - tomcat-util-scan under Apache License, Version 2.0 - TXW2 Runtime under CDDL+GPL License - diff --git a/cas-client-integration-tomcat-v90/pom.xml b/cas-client-integration-tomcat-v90/pom.xml deleted file mode 100644 index 19eca42a4..000000000 --- a/cas-client-integration-tomcat-v90/pom.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - cas-client - org.jasig.cas.client - 3.6.4 - - 4.0.0 - - cas-client-integration-tomcat-v90 - jar - Jasig CAS Client for Java - Tomcat 9.0.x Integration - - - 9.0.56 - - - - org.jasig.cas.client - cas-client-integration-tomcat-common - ${project.version} - jar - compile - - - org.jasig.cas.client - cas-client-support-saml - ${project.version} - jar - compile - true - - - org.apache.tomcat.embed - tomcat-embed-core - ${tomcat.version} - jar - provided - - - org.apache.tomcat - tomcat-catalina - ${tomcat.version} - jar - provided - - - org.apache.tomcat - tomcat-servlet-api - - - org.apache.tomcat - tomcat-juli - - - org.apache.tomcat - tomcat-annotations-api - - - org.apache.tomcat - tomcat-api - - - org.apache.tomcat - tomcat-util - - - - - - org.jasig.cas.client - cas-client-core - ${project.version} - jar - compile - - - - diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractAuthenticator.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractAuthenticator.java deleted file mode 100644 index fe8aea174..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractAuthenticator.java +++ /dev/null @@ -1,208 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleEvent; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.LifecycleListener; -import org.apache.catalina.LifecycleState; -import org.apache.catalina.Realm; -import org.apache.catalina.authenticator.AuthenticatorBase; -import org.apache.catalina.connector.Request; -import org.jasig.cas.client.tomcat.AuthenticatorDelegate; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.TicketValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.http.HttpServletResponse; - -import java.io.*; -import java.security.Principal; - -/** - * Base authenticator for all authentication protocols supported by CAS. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractAuthenticator extends AuthenticatorBase implements LifecycleListener { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - private final AuthenticatorDelegate delegate = new AuthenticatorDelegate(); - - private String casServerUrlPrefix; - - private String encoding; - - private boolean encode; - - private boolean renew; - - protected abstract String getAuthenticationMethod(); - - /** - * Provided for Tomcat 7.0.8 support. - * - * @return the authentication method. - */ - @Override - protected String getAuthMethod() { - return getAuthenticationMethod(); - } - - /** - * Abstract method that subclasses should use to provide the name of the artifact parameter (i.e. ticket) - * - * @return the artifact parameter name. CANNOT be NULL. - */ - protected abstract String getArtifactParameterName(); - - /** - * Abstract method that subclasses should use to provide the name of the service parameter (i.e. service) - * - * @return the service parameter name. CANNOT be NULL. - */ - protected abstract String getServiceParameterName(); - - /** - * Returns the single instance of the ticket validator to use to validate tickets. Sub classes should include - * the one appropriate for the - * - * @return a fully configured ticket validator. CANNOT be NULL. - */ - protected abstract TicketValidator getTicketValidator(); - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.debug("{} starting.", getName()); - final Realm realm = this.context.getRealm(); - try { - CommonUtils.assertTrue(realm instanceof CasRealm, "Expected CasRealm but got " + realm.getClass()); - CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null."); - CommonUtils.assertNotNull(this.delegate.getCasServerLoginUrl(), "casServerLoginUrl cannot be null."); - CommonUtils.assertTrue(this.delegate.getServerName() != null || this.delegate.getServiceUrl() != null, - "either serverName or serviceUrl must be set."); - this.delegate.setRealm((CasRealm) realm); - } catch (final Exception e) { - throw new LifecycleException(e); - } - // Complete delegate initialization after the component is started. - // See #lifecycleEvent() method. - addLifecycleListener(this); - } - - protected final String getCasServerUrlPrefix() { - return this.casServerUrlPrefix; - } - - public final void setCasServerUrlPrefix(final String casServerUrlPrefix) { - this.casServerUrlPrefix = casServerUrlPrefix; - } - - public final void setCasServerLoginUrl(final String casServerLoginUrl) { - this.delegate.setCasServerLoginUrl(casServerLoginUrl); - } - - public final boolean isEncode() { - return this.encode; - } - - public final void setEncode(final boolean encode) { - this.encode = encode; - } - - protected final boolean isRenew() { - return this.renew; - } - - public void setRenew(final boolean renew) { - this.renew = renew; - } - - public final void setServerName(final String serverName) { - this.delegate.setServerName(serverName); - } - - public final void setServiceUrl(final String serviceUrl) { - this.delegate.setServiceUrl(serviceUrl); - } - - protected final String getEncoding() { - return this.encoding; - } - - public final void setEncoding(final String encoding) { - this.encoding = encoding; - } - - /** {@inheritDoc} */ - @Override - protected boolean doAuthenticate(final Request request, - final HttpServletResponse httpServletResponse) throws IOException { - Principal principal = request.getUserPrincipal(); - boolean result = false; - if (principal == null) { - // Authentication sets the response headers for status and redirect if needed - principal = this.delegate.authenticate(request.getRequest(), request.getResponse()); - if (principal != null) { - register(request, request.getResponse(), principal, getAuthenticationMethod(), null, null); - result = true; - } - } else { - result = true; - } - return result; - } - - /** {@inheritDoc} */ - @Override - public void lifecycleEvent(final LifecycleEvent event) { - if (AFTER_START_EVENT.equals(event.getType())) { - logger.debug("{} processing lifecycle event {}", getName(), AFTER_START_EVENT); - this.delegate.setTicketValidator(getTicketValidator()); - this.delegate.setArtifactParameterName(getArtifactParameterName()); - this.delegate.setServiceParameterName(getServiceParameterName()); - } - } - - /** {@inheritDoc} */ - public String getInfo() { - return getName() + "/1.0"; - } - - /** {@inheritDoc} - * @throws LifecycleException */ - @Override - protected synchronized void setState(final LifecycleState state, final Object data) throws LifecycleException { - super.setState(state, data); - if (LifecycleState.STARTED.equals(state)) { - logger.info("{} started.", getName()); - } - } - - /** - * @return Authenticator descriptive name. - */ - protected abstract String getName(); -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractCasAuthenticator.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractCasAuthenticator.java deleted file mode 100644 index b29ff664b..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractCasAuthenticator.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -/** - * Base class for all CAS protocol authenticators. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractCasAuthenticator extends AbstractAuthenticator { - - private String proxyCallbackUrl; - - protected final String getProxyCallbackUrl() { - return this.proxyCallbackUrl; - } - - public final void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected final String getArtifactParameterName() { - return "ticket"; - } - - @Override - protected final String getServiceParameterName() { - return "service"; - } - - -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractCasRealm.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractCasRealm.java deleted file mode 100644 index d7f03c71e..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractCasRealm.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.Wrapper; -import org.apache.catalina.realm.RealmBase; -import org.jasig.cas.client.tomcat.CasRealm; - -import java.security.Principal; - -/** - * Base Realm implementation for all CAS realms. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public abstract class AbstractCasRealm extends RealmBase implements CasRealm { - - /** {@inheritDoc} */ - @Override - public Principal authenticate(final Principal p) { - return getDelegate().authenticate(p); - } - - /** {@inheritDoc} */ - @Override - public String[] getRoles(final Principal p) { - return getDelegate().getRoles(p); - } - - @Override - public boolean hasRole(final Principal principal, final String role) { - return getDelegate().hasRole(principal, role); - } - - @Override - public boolean hasRole(final Wrapper wrapper, final Principal principal, final String role) { - return hasRole(principal, role); - } - - public String getInfo() { - return getClass().getName() + "/1.0"; - } - - @Override - protected String getPassword(final String userName) { - throw new UnsupportedOperationException(); - } - - @Override - protected Principal getPrincipal(final String userName) { - throw new UnsupportedOperationException(); - } - - /** - * @return Delegate that all {@link CasRealm} operations are delegated to. - */ - protected abstract CasRealm getDelegate(); -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractLogoutValve.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractLogoutValve.java deleted file mode 100644 index 605735687..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AbstractLogoutValve.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletException; - -import java.io.*; - -/** - * Abstract base class for Container-managed log out. Removes the attributes - * from the session. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public abstract class AbstractLogoutValve extends ValveBase { - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - @Override - public final void invoke(final Request request, final Response response) throws IOException, ServletException { - if (getLogoutHandler().isLogoutRequest(request)) { - getLogoutHandler().logout(request, response); - // Do not proceed up valve chain - return; - } - - logger.debug("URI is not a logout request: {}", request.getRequestURI()); - getNext().invoke(request, response); - } - - protected abstract LogoutHandler getLogoutHandler(); -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AssertionCasRealm.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AssertionCasRealm.java deleted file mode 100644 index 5a8659b58..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/AssertionCasRealm.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.jasig.cas.client.tomcat.AssertionCasRealmDelegate; -import org.jasig.cas.client.tomcat.CasRealm; - -/** - * Tomcat Realm that implements {@link CasRealm} for principal and - * role data backed by the CAS {@link org.jasig.cas.client.validation.Assertion}. - *

- * Authentication always succeeds and simply returns the given principal. - * - * @author Marvin S. Addison - * @version $Revision$ - * - */ -public class AssertionCasRealm extends AbstractCasRealm { - - private final AssertionCasRealmDelegate delegate = new AssertionCasRealmDelegate(); - - /** - * @param name Name of the attribute in the principal that contains role data. - */ - public void setRoleAttributeName(final String name) { - delegate.setRoleAttributeName(name); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return delegate; - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas10CasAuthenticator.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas10CasAuthenticator.java deleted file mode 100644 index d7d68a85c..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas10CasAuthenticator.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas10TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles CAS 1.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas10CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS10"; - - private static final String NAME = Cas10CasAuthenticator.class.getName(); - - private Cas10TicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix()); - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas20CasAuthenticator.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas20CasAuthenticator.java deleted file mode 100644 index 3321f1c92..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas20CasAuthenticator.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Cas20ServiceTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20CasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20"; - - private static final String NAME = Cas20CasAuthenticator.class.getName(); - - private Cas20ServiceTicketValidator ticketValidator; - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix()); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setRenew(isRenew()); - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas20ProxyCasAuthenticator.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas20ProxyCasAuthenticator.java deleted file mode 100644 index 85a33c301..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Cas20ProxyCasAuthenticator.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.validation.Cas20ProxyTicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * Authenticator that handles the CAS 2.0 protocol with proxying support. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator { - - public static final String AUTH_METHOD = "CAS20-PROXY"; - - private static final String NAME = Cas20ProxyCasAuthenticator.class.getName(); - - private Cas20ProxyTicketValidator ticketValidator; - - private boolean acceptAnyProxy; - - private String allowedProxyChains; - - public void setAcceptAnyProxy(final boolean acceptAnyProxy) { - this.acceptAnyProxy = acceptAnyProxy; - } - - public void setAllowedProxyChains(final String allowedProxyChains) { - this.allowedProxyChains = allowedProxyChains; - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - @Override - protected String getName() { - return NAME; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix()); - this.ticketValidator.setRenew(isRenew()); - this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl()); - this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage()); - this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy); - this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains)); - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/PropertiesCasRealm.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/PropertiesCasRealm.java deleted file mode 100644 index 973f4da7d..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/PropertiesCasRealm.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.CasRealm; -import org.jasig.cas.client.tomcat.PropertiesCasRealmDelegate; - -/** - * Tomcat Realm that implements {@link CasRealm} backed by properties file - * containing usernames/and roles of the following format: - *

- * username1=role1,role2,role3
- * username2=role1
- * username3=role2,role3
- * 
- * User authentication succeeds if the name of the given principal exists as - * a username in the properties file. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public class PropertiesCasRealm extends AbstractCasRealm { - - private final PropertiesCasRealmDelegate delegate = new PropertiesCasRealmDelegate(); - - /** - * @param path Path to properties file container username/role data. - */ - public void setPropertiesFilePath(final String path) { - this.delegate.setPropertiesFilePath(path); - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.delegate.readProperties(); - } - - /** {@inheritDoc} */ - @Override - protected CasRealm getDelegate() { - return this.delegate; - } - -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/ProxyCallbackValve.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/ProxyCallbackValve.java deleted file mode 100644 index 2f1ad99a4..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/ProxyCallbackValve.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage; -import org.jasig.cas.client.util.CommonUtils; -import org.jasig.cas.client.util.ReflectUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletException; - -import java.io.*; - -/** - * Handles watching a url for the proxy callback. - *

- * Because its tough to share state between valves, we expose the storage mechanism via a static variable. - *

- * This valve should be ordered before the authentication valves. - * - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class ProxyCallbackValve extends ValveBase { - - private static ProxyGrantingTicketStorage PROXY_GRANTING_TICKET_STORAGE; - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private String proxyGrantingTicketStorageClass; - - private String proxyCallbackUrl; - - public static ProxyGrantingTicketStorage getProxyGrantingTicketStorage() { - return PROXY_GRANTING_TICKET_STORAGE; - } - - public void setProxyGrantingTicketStorageClass(final String proxyGrantingTicketStorageClass) { - this.proxyGrantingTicketStorageClass = proxyGrantingTicketStorageClass; - } - - public void setProxyCallbackUrl(final String proxyCallbackUrl) { - this.proxyCallbackUrl = proxyCallbackUrl; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - - try { - CommonUtils.assertNotNull(this.proxyCallbackUrl, "the proxy callback url cannot be null"); - CommonUtils.assertTrue(this.proxyCallbackUrl.startsWith("/"), "proxy callback url must start with \"/\""); - - PROXY_GRANTING_TICKET_STORAGE = ReflectUtils.newInstance(proxyGrantingTicketStorageClass); - } catch (final Exception e) { - throw new LifecycleException(e); - } - logger.info("Startup completed."); - } - - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.proxyCallbackUrl.equals(request.getRequestURI())) { - logger.debug("Processing proxy callback request."); - CommonUtils.readAndRespondToProxyReceptorRequest(request, response, PROXY_GRANTING_TICKET_STORAGE); - return; - } - - getNext().invoke(request, response); - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/RegexUriLogoutValve.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/RegexUriLogoutValve.java deleted file mode 100644 index 0447bbe95..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/RegexUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.RegexUriLogoutHandler; - -/** - * Performs CAS logout when the request URI matches a regular expression. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class RegexUriLogoutValve extends AbstractLogoutValve { - - private final RegexUriLogoutHandler logoutHandler = new RegexUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUriRegex(final String regex) { - this.logoutHandler.setLogoutUriRegex(regex); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Saml11Authenticator.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Saml11Authenticator.java deleted file mode 100644 index 0004e5c99..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/Saml11Authenticator.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.validation.Saml11TicketValidator; -import org.jasig.cas.client.validation.TicketValidator; - -/** - * CAS authenticator that uses the SAML 1.1 protocol. - * - * @author Marvin S. Addison - * @version $Revision$ - * @since 3.1.12 - * - */ -public final class Saml11Authenticator extends AbstractAuthenticator { - - public static final String AUTH_METHOD = "SAML11"; - - private static final String NAME = Saml11Authenticator.class.getName(); - - private Saml11TicketValidator ticketValidator; - - /** SAML protocol clock drift tolerance in ms */ - private int tolerance = -1; - - /** - * @param ms SAML clock drift tolerance in milliseconds. - */ - public void setTolerance(final int ms) { - this.tolerance = ms; - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.ticketValidator = new Saml11TicketValidator(getCasServerUrlPrefix()); - if (this.tolerance > -1) { - this.ticketValidator.setTolerance(this.tolerance); - } - if (getEncoding() != null) { - this.ticketValidator.setEncoding(getEncoding()); - } - this.ticketValidator.setRenew(isRenew()); - } - - @Override - protected TicketValidator getTicketValidator() { - return this.ticketValidator; - } - - @Override - protected String getAuthenticationMethod() { - return AUTH_METHOD; - } - - /** {@inheritDoc} */ - @Override - protected String getArtifactParameterName() { - return "SAMLart"; - } - - /** {@inheritDoc} */ - @Override - protected String getServiceParameterName() { - return "TARGET"; - } - - @Override - protected String getName() { - return NAME; - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/SingleSignOutValve.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/SingleSignOutValve.java deleted file mode 100644 index 04326f7e6..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/SingleSignOutValve.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.apache.catalina.Session; -import org.apache.catalina.SessionEvent; -import org.apache.catalina.SessionListener; -import org.apache.catalina.connector.Request; -import org.apache.catalina.connector.Response; -import org.apache.catalina.valves.ValveBase; -import org.jasig.cas.client.session.SessionMappingStorage; -import org.jasig.cas.client.session.SingleSignOutHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.ServletException; - -import java.io.*; - -/** - * Handles logout request messages sent from the CAS server by ending the current - * HTTP session. - * - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - * - */ -public class SingleSignOutValve extends ValveBase implements SessionListener { - - /** Logger instance */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final SingleSignOutHandler handler = new SingleSignOutHandler(); - - public void setArtifactParameterName(final String name) { - this.handler.setArtifactParameterName(name); - } - - public void setLogoutParameterName(final String name) { - this.handler.setLogoutParameterName(name); - } - - public void setRelayStateParameterName(final String name) { - this.handler.setRelayStateParameterName(name); - } - - public void setLogoutCallbackPath(final String logoutCallbackPath) { - this.handler.setLogoutCallbackPath(logoutCallbackPath); - } - - public void setSessionMappingStorage(final SessionMappingStorage storage) { - this.handler.setSessionMappingStorage(storage); - } - - /** {@inheritDoc} */ - @Override - public void invoke(final Request request, final Response response) throws IOException, ServletException { - if (this.handler.process(request, response)) { - getNext().invoke(request, response); - } - } - - /** {@inheritDoc} */ - @Override - public void sessionEvent(final SessionEvent event) { - if (Session.SESSION_DESTROYED_EVENT.equals(event.getType())) { - logger.debug("Cleaning up SessionMappingStorage on destroySession event"); - this.handler.getSessionMappingStorage().removeBySessionById(event.getSession().getId()); - } - } - - /** {@inheritDoc} */ - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - logger.info("Starting..."); - this.handler.init(); - logger.info("Startup completed."); - } -} diff --git a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/StaticUriLogoutValve.java b/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/StaticUriLogoutValve.java deleted file mode 100644 index 5c28fe15c..000000000 --- a/cas-client-integration-tomcat-v90/src/main/java/org/jasig/cas/client/tomcat/v90/StaticUriLogoutValve.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.tomcat.v90; - -import org.apache.catalina.LifecycleException; -import org.jasig.cas.client.tomcat.LogoutHandler; -import org.jasig.cas.client.tomcat.StaticUriLogoutHandler; - -/** - * Monitors a specific request URI for logout requests. - * - * @author Scott Battaglia - * @author Marvin S. Addison - * @version $Revision$ $Date$ - * @since 3.1.12 - */ -public final class StaticUriLogoutValve extends AbstractLogoutValve { - - private final StaticUriLogoutHandler logoutHandler = new StaticUriLogoutHandler(); - - public void setRedirectUrl(final String redirectUrl) { - this.logoutHandler.setRedirectUrl(redirectUrl); - } - - public void setLogoutUri(final String logoutUri) { - this.logoutHandler.setLogoutUri(logoutUri); - } - - @Override - protected void startInternal() throws LifecycleException { - super.startInternal(); - this.logoutHandler.init(); - logger.info("Startup completed."); - } - - /** {@inheritDoc} */ - @Override - protected LogoutHandler getLogoutHandler() { - return this.logoutHandler; - } -} diff --git a/cas-client-support-distributed-ehcache/NOTICE b/cas-client-support-distributed-ehcache/NOTICE index 7c34c982b..250038910 100644 --- a/cas-client-support-distributed-ehcache/NOTICE +++ b/cas-client-support-distributed-ehcache/NOTICE @@ -26,8 +26,8 @@ This project includes: Jackson-annotations under The Apache Software License, Version 2.0 Jackson-core under The Apache Software License, Version 2.0 jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - Distributed Proxy Storage Support: EhCache under Apache License Version 2.0 + Apereo CAS Client for Java - Core under Apache License Version 2.0 + Apereo CAS Client for Java - Distributed Proxy Storage Support: EhCache under Apache License Version 2.0 Java Servlet API under CDDL + GPLv2 with classpath exception JavaBeans Activation Framework API jar under CDDL/GPLv2+CE JAXB Core under CDDL+GPL License diff --git a/cas-client-support-distributed-ehcache/pom.xml b/cas-client-support-distributed-ehcache/pom.xml index 42c5f862b..c47ebfdc1 100644 --- a/cas-client-support-distributed-ehcache/pom.xml +++ b/cas-client-support-distributed-ehcache/pom.xml @@ -22,11 +22,11 @@ cas-client - org.jasig.cas.client - 3.6.4 + org.apereo.cas.client + 4.1.2-SNAPSHOT 4.0.0 - Jasig CAS Client for Java - Distributed Proxy Storage Support: EhCache + Apereo CAS Client for Java - Distributed Proxy Storage Support: EhCache cas-client-support-distributed-ehcache @@ -34,19 +34,35 @@ - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${project.version} jar compile + + - net.sf.ehcache - ehcache-core + org.ehcache + ehcache ${ehcache.version} compile jar + + + javax.xml.bind + jaxb-api + + + com.sun.xml.fastinfoset + FastInfoset + + + com.sun.istack + istack-commons-runtime + + diff --git a/cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java b/cas-client-support-distributed-ehcache/src/main/java/org/apereo/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java similarity index 62% rename from cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java rename to cas-client-support-distributed-ehcache/src/main/java/org/apereo/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java index a05c3066e..7b3deb840 100644 --- a/cas-client-support-distributed-ehcache/src/main/java/org/jasig/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java +++ b/cas-client-support-distributed-ehcache/src/main/java/org/apereo/cas/client/proxy/EhcacheBackedProxyGrantingTicketStorageImpl.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,12 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Element; -import net.sf.ehcache.distribution.RemoteCacheException; +import org.ehcache.Cache; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,45 +32,36 @@ */ public final class EhcacheBackedProxyGrantingTicketStorageImpl extends AbstractEncryptedProxyGrantingTicketStorageImpl { - public static final String EHCACHE_CACHE_NAME = "org.jasig.cas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl.cache"; + public static final String EHCACHE_CACHE_NAME = "org.apereocas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl.cache"; private static final Logger logger = LoggerFactory.getLogger(EhcacheBackedProxyGrantingTicketStorageImpl.class); - final Cache cache; + private final Cache cache; public EhcacheBackedProxyGrantingTicketStorageImpl() { - this(CacheManager.getInstance().getCache(EHCACHE_CACHE_NAME)); - logger.info("Created cache with name: {}", this.cache.getName()); - } - - public EhcacheBackedProxyGrantingTicketStorageImpl(final Cache cache) { - super(); - this.cache = cache; + final var cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(); + cacheManager.init(); + cache = cacheManager.createCache(EHCACHE_CACHE_NAME, + CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, + ResourcePoolsBuilder.heap(1000))); + logger.info("Created cache with name: {}", EHCACHE_CACHE_NAME); } @Override public void saveInternal(final String proxyGrantingTicketIou, final String proxyGrantingTicket) { - final Element element = new Element(proxyGrantingTicketIou, proxyGrantingTicket); try { - this.cache.put(element); - } catch (final RemoteCacheException e) { + this.cache.put(proxyGrantingTicketIou, proxyGrantingTicket); + } catch (final Exception e) { logger.warn("Exception accessing one of the remote servers: {}", e.getMessage(), e); } } @Override public String retrieveInternal(final String proxyGrantingTicketIou) { - final Element element = this.cache.get(proxyGrantingTicketIou); - - if (element == null) { - return null; - } - - return (String) element.getValue(); + return proxyGrantingTicketIou == null ? null : (String) this.cache.get(proxyGrantingTicketIou); } @Override public void cleanUp() { - // nothing to do } } diff --git a/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java b/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java index 32858854a..24f55dda1 100644 --- a/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java +++ b/cas-client-support-distributed-ehcache/src/test/java/EhCacheBackedProxyGrantingTicketStorageImplTests.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ + +import org.apereo.cas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl; +import org.apereo.cas.client.proxy.ProxyGrantingTicketStorage; + import junit.framework.TestCase; -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import org.jasig.cas.client.proxy.EhcacheBackedProxyGrantingTicketStorageImpl; /** * @author Scott Battaglia @@ -29,17 +30,12 @@ public class EhCacheBackedProxyGrantingTicketStorageImplTests extends TestCase { public void testEncryptionMechanisms() throws Exception { - final Cache ehcache = new Cache("name", 100, false, false, 500, 500); - CacheManager.getInstance().addCache(ehcache); - final EhcacheBackedProxyGrantingTicketStorageImpl cache = new EhcacheBackedProxyGrantingTicketStorageImpl( - ehcache); - // cache.setSecretKey("thismustbeatleast24charactersandcannotbelessthanthat1234"); + + final ProxyGrantingTicketStorage cache = new EhcacheBackedProxyGrantingTicketStorageImpl(); assertNull(cache.retrieve(null)); assertNull(cache.retrieve("foobar")); - cache.save("proxyGrantingTicketIou", "proxyGrantingTicket"); assertEquals("proxyGrantingTicket", cache.retrieve("proxyGrantingTicketIou")); - assertTrue("proxyGrantingTicket".equals(ehcache.get("proxyGrantingTicketIou").getValue())); } } diff --git a/cas-client-support-distributed-memcached/NOTICE b/cas-client-support-distributed-memcached/NOTICE index 3b13a4a8b..d0d05c4be 100644 --- a/cas-client-support-distributed-memcached/NOTICE +++ b/cas-client-support-distributed-memcached/NOTICE @@ -25,8 +25,8 @@ This project includes: Jackson-annotations under The Apache Software License, Version 2.0 Jackson-core under The Apache Software License, Version 2.0 jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - Distributed Proxy Storage Support: Memcached under Apache License Version 2.0 + Apereo CAS Client for Java - Core under Apache License Version 2.0 + Apereo CAS Client for Java - Distributed Proxy Storage Support: Memcached under Apache License Version 2.0 Java Servlet API under CDDL + GPLv2 with classpath exception JavaBeans Activation Framework API jar under CDDL/GPLv2+CE JAXB Core under CDDL+GPL License diff --git a/cas-client-support-distributed-memcached/pom.xml b/cas-client-support-distributed-memcached/pom.xml index 35515422d..abff92ad6 100644 --- a/cas-client-support-distributed-memcached/pom.xml +++ b/cas-client-support-distributed-memcached/pom.xml @@ -22,18 +22,18 @@ cas-client - org.jasig.cas.client - 3.6.4 + org.apereo.cas.client + 4.1.2-SNAPSHOT 4.0.0 jar cas-client-support-distributed-memcached - Jasig CAS Client for Java - Distributed Proxy Storage Support: Memcached + Apereo CAS Client for Java - Distributed Proxy Storage Support: Memcached - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${project.version} compile diff --git a/cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java b/cas-client-support-distributed-memcached/src/main/java/org/apereo/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java similarity index 74% rename from cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java rename to cas-client-support-distributed-memcached/src/main/java/org/apereo/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java index 94ae05dab..8fecf570e 100644 --- a/cas-client-support-distributed-memcached/src/main/java/org/jasig/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java +++ b/cas-client-support-distributed-memcached/src/main/java/org/apereo/cas/client/proxy/MemcachedBackedProxyGrantingTicketStorageImpl.java @@ -16,11 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.proxy; +package org.apereo.cas.client.proxy; import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -30,7 +29,7 @@ import net.spy.memcached.MemcachedClientIF; /** - * Implementation of the {@link org.jasig.cas.client.proxy.ProxyGrantingTicketStorage} interface that is backed by + * Implementation of the {@link ProxyGrantingTicketStorage} interface that is backed by * Memcache for distributed web applications. * * @author Scott Battaglia @@ -40,7 +39,7 @@ public final class MemcachedBackedProxyGrantingTicketStorageImpl extends AbstractEncryptedProxyGrantingTicketStorageImpl { - protected final MemcachedClientIF client; + private final MemcachedClientIF client; /** * Default constructor reads from the /casclient_memcached_hosts.txt in the classpath. Each line should be a host:port @@ -50,14 +49,13 @@ public MemcachedBackedProxyGrantingTicketStorageImpl() { this(getHostsFromClassPath()); } - protected static String[] getHostsFromClassPath() { - final InputStream inputStream = MemcachedBackedProxyGrantingTicketStorageImpl.class + private static String[] getHostsFromClassPath() { + final var inputStream = MemcachedBackedProxyGrantingTicketStorageImpl.class .getResourceAsStream("/cas/casclient_memcached_hosts.txt"); - final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - final List hosts = new ArrayList(); + final var hosts = new ArrayList(); String line; - try { + try (final var reader = new BufferedReader(new InputStreamReader(inputStream))) { while ((line = reader.readLine()) != null) { hosts.add(line); } @@ -65,26 +63,17 @@ protected static String[] getHostsFromClassPath() { return hosts.toArray(new String[hosts.size()]); } catch (final IOException e) { throw new RuntimeException(e); - } finally { - try { - reader.close(); - } catch (final IOException e) { - // nothing to do - } - - try { - inputStream.close(); - } catch (final IOException e) { - // do nothing - } } + // nothing to do + + // do nothing } public MemcachedBackedProxyGrantingTicketStorageImpl(final String[] hostnamesAndPorts) { - final List addresses = new ArrayList(); + final List addresses = new ArrayList<>(); - for (final String hostname : hostnamesAndPorts) { - final String[] hostPort = hostname.split(":"); + for (final var hostname : hostnamesAndPorts) { + final var hostPort = hostname.split(":"); addresses.add(new InetSocketAddress(hostPort[0], Integer.parseInt(hostPort[1]))); } @@ -110,7 +99,7 @@ public void cleanUp() { // we actually don't have anything to do here, yay! } - private void handleSynchronousRequest(final Future f) { + private static void handleSynchronousRequest(final Future f) { try { f.get(); } catch (final Exception e) { diff --git a/cas-client-support-saml/NOTICE b/cas-client-support-saml/NOTICE index f7dbce08c..88bc67990 100644 --- a/cas-client-support-saml/NOTICE +++ b/cas-client-support-saml/NOTICE @@ -25,14 +25,13 @@ This project includes: Jackson-annotations under The Apache Software License, Version 2.0 Jackson-core under The Apache Software License, Version 2.0 jackson-databind under The Apache Software License, Version 2.0 - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 + Apereo CAS Client for Java - Core under Apache License Version 2.0 + Apereo CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 Java Servlet API under CDDL + GPLv2 with classpath exception JavaBeans Activation Framework API jar under CDDL/GPLv2+CE JAXB Core under CDDL+GPL License jaxb-api under CDDL 1.1 or GPL2 w/ CPE JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 JUnit under Eclipse Public License 1.0 SLF4J API Module under MIT License SLF4J Simple Binding under MIT License diff --git a/cas-client-support-saml/pom.xml b/cas-client-support-saml/pom.xml index f858e44d4..87715f9ba 100644 --- a/cas-client-support-saml/pom.xml +++ b/cas-client-support-saml/pom.xml @@ -20,30 +20,25 @@ --> - org.jasig.cas.client - 3.6.4 + org.apereo.cas.client + 4.1.2-SNAPSHOT cas-client 4.0.0 cas-client-support-saml jar - Jasig CAS Client for Java - SAML Protocol Support + Apereo CAS Client for Java - SAML Protocol Support - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${project.version} - - joda-time - joda-time - 2.10.13 - - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${project.version} test-jar diff --git a/cas-client-support-saml/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java b/cas-client-support-saml/src/main/java/org/apereo/cas/client/authentication/Saml11AuthenticationFilter.java similarity index 93% rename from cas-client-support-saml/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java rename to cas-client-support-saml/src/main/java/org/apereo/cas/client/authentication/Saml11AuthenticationFilter.java index 0e9b481d5..a740a7a6d 100644 --- a/cas-client-support-saml/src/main/java/org/jasig/cas/client/authentication/Saml11AuthenticationFilter.java +++ b/cas-client-support-saml/src/main/java/org/apereo/cas/client/authentication/Saml11AuthenticationFilter.java @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.authentication; +package org.apereo.cas.client.authentication; -import org.jasig.cas.client.Protocol; +import org.apereo.cas.client.Protocol; /** * Extension to the default Authentication filter that sets the required SAML1.1 artifact parameter name and service parameter name. diff --git a/cas-client-support-saml/src/main/java/org/jasig/cas/client/util/SamlUtils.java b/cas-client-support-saml/src/main/java/org/apereo/cas/client/util/SamlUtils.java similarity index 54% rename from cas-client-support-saml/src/main/java/org/jasig/cas/client/util/SamlUtils.java rename to cas-client-support-saml/src/main/java/org/apereo/cas/client/util/SamlUtils.java index 1010d84ad..c6cd5e329 100644 --- a/cas-client-support-saml/src/main/java/org/jasig/cas/client/util/SamlUtils.java +++ b/cas-client-support-saml/src/main/java/org/apereo/cas/client/util/SamlUtils.java @@ -16,15 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; +package org.apereo.cas.client.util; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; import java.util.Date; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormatter; -import org.joda.time.format.ISODateTimeFormat; - /** * SAML utility class. * @@ -33,20 +32,32 @@ */ public final class SamlUtils { - private static final DateTimeFormatter ISO_FORMAT = ISODateTimeFormat.dateTimeNoMillis(); + private static final DateTimeFormatter ISO_FORMATTER_NO_MILLIS = new DateTimeFormatterBuilder() + .append(DateTimeFormatter.ofPattern("YYYY-MM-dd'T'HH:mm:ss")) + .parseLenient() + .appendOffset("+HHMM", "Z") + .parseStrict() + .toFormatter(); + private static final DateTimeFormatter ISO_PARSER_WITH_MILLIS = new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + .parseLenient() + .appendOffset("+HHMM", "Z") + .parseStrict() + .toFormatter(); private SamlUtils() { // nothing to do } public static String formatForUtcTime(final Date date) { - return ISO_FORMAT.print(new DateTime(date).withZone(DateTimeZone.UTC)); + return ISO_FORMATTER_NO_MILLIS.format(ZonedDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC)); } public static Date parseUtcDate(final String date) { if (CommonUtils.isEmpty(date)) { return null; } - return ISODateTimeFormat.dateTimeParser().parseDateTime(date).toDate(); + return Date.from(ZonedDateTime.parse(date, ISO_PARSER_WITH_MILLIS).toInstant()); } } diff --git a/cas-client-support-saml/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java b/cas-client-support-saml/src/main/java/org/apereo/cas/client/validation/Saml11TicketValidationFilter.java similarity index 78% rename from cas-client-support-saml/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java rename to cas-client-support-saml/src/main/java/org/apereo/cas/client/validation/Saml11TicketValidationFilter.java index 76fe5450f..628286926 100644 --- a/cas-client-support-saml/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidationFilter.java +++ b/cas-client-support-saml/src/main/java/org/apereo/cas/client/validation/Saml11TicketValidationFilter.java @@ -16,14 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import javax.servlet.FilterConfig; +import org.apereo.cas.client.Protocol; +import org.apereo.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.Protocol; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.ssl.HttpURLConnectionFactory; -import org.jasig.cas.client.ssl.HttpsURLConnectionFactory; +import jakarta.servlet.FilterConfig; + +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.ssl.HttpsURLConnectionFactory; /** * Implementation of TicketValidationFilter that can instanciate a SAML 1.1 Ticket Validator. @@ -44,8 +45,8 @@ public Saml11TicketValidationFilter() { @Override protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) { - final Saml11TicketValidator validator = new Saml11TicketValidator(getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX)); - final long tolerance = getLong(ConfigurationKeys.TOLERANCE); + final var validator = new Saml11TicketValidator(getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX)); + final var tolerance = getLong(ConfigurationKeys.TOLERANCE); validator.setTolerance(tolerance); validator.setRenew(getBoolean(ConfigurationKeys.RENEW)); diff --git a/cas-client-support-saml/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java b/cas-client-support-saml/src/main/java/org/apereo/cas/client/validation/Saml11TicketValidator.java similarity index 78% rename from cas-client-support-saml/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java rename to cas-client-support-saml/src/main/java/org/apereo/cas/client/validation/Saml11TicketValidator.java index 195bea3cb..a2a5a37a7 100644 --- a/cas-client-support-saml/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java +++ b/cas-client-support-saml/src/main/java/org/apereo/cas/client/validation/Saml11TicketValidator.java @@ -16,25 +16,35 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; -import java.io.*; +import org.apereo.cas.client.authentication.AttributePrincipalImpl; +import org.apereo.cas.client.util.CommonUtils; +import org.apereo.cas.client.util.IOUtils; +import org.apereo.cas.client.util.MapNamespaceContext; +import org.apereo.cas.client.util.SamlUtils; +import org.apereo.cas.client.util.ThreadLocalXPathExpression; +import org.apereo.cas.client.util.XmlUtils; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import javax.xml.namespace.NamespaceContext; + +import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.Charset; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -import java.util.*; -import org.jasig.cas.client.authentication.AttributePrincipalImpl; -import org.jasig.cas.client.util.*; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Interval; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -import javax.xml.namespace.NamespaceContext; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; /** * TicketValidator that can understand validating a SAML artifact. This includes the SOAP request/response. @@ -85,7 +95,7 @@ public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator private final Random random; - /** Class initializer. */ + /* Class initializer. */ static { try { SAML_REQUEST_TEMPLATE = IOUtils.readString( @@ -113,7 +123,7 @@ protected String getUrlSuffix() { @Override protected void populateUrlAttributeMap(final Map urlParameters) { - final String service = urlParameters.get("service"); + final var service = urlParameters.get("service"); urlParameters.remove("service"); urlParameters.remove("ticket"); urlParameters.put("TARGET", service); @@ -122,25 +132,25 @@ protected void populateUrlAttributeMap(final Map urlParameters) @Override protected Assertion parseResponseFromServer(final String response) throws TicketValidationException { try { - final Document document = XmlUtils.newDocument(response); - final Date assertionValidityStart = SamlUtils.parseUtcDate( + final var document = XmlUtils.newDocument(response); + final var assertionValidityStart = SamlUtils.parseUtcDate( XPATH_ASSERTION_DATE_START.evaluateAsString(document)); - final Date assertionValidityEnd = SamlUtils.parseUtcDate( + final var assertionValidityEnd = SamlUtils.parseUtcDate( XPATH_ASSERTION_DATE_END.evaluateAsString(document)); if (!isValidAssertion(assertionValidityStart, assertionValidityEnd)) { throw new TicketValidationException("Invalid SAML assertion"); } - final String nameId = XPATH_NAME_ID.evaluateAsString(document); + final var nameId = XPATH_NAME_ID.evaluateAsString(document); if (nameId == null) { throw new TicketValidationException("SAML assertion does not contain NameIdentifier element"); } - final String authMethod = XPATH_AUTH_METHOD.evaluateAsString(document); - final NodeList attributes = XPATH_ATTRIBUTES.evaluateAsNodeList(document); - final Map principalAttributes = new HashMap(attributes.getLength()); + final var authMethod = XPATH_AUTH_METHOD.evaluateAsString(document); + final var attributes = XPATH_ATTRIBUTES.evaluateAsNodeList(document); + final Map principalAttributes = new HashMap<>(attributes.getLength()); Element attribute; NodeList values; String name; - for (int i = 0; i < attributes.getLength(); i++) { + for (var i = 0; i < attributes.getLength(); i++) { attribute = (Element) attributes.item(i); name = attribute.getAttribute("AttributeName"); logger.trace("Processing attribute {}", name); @@ -148,8 +158,8 @@ protected Assertion parseResponseFromServer(final String response) throws Ticket if (values.getLength() == 1) { principalAttributes.put(name, values.item(0).getTextContent()); } else { - final Collection items = new ArrayList(values.getLength()); - for (int j = 0; j < values.getLength(); j++) { + final var items = new ArrayList<>(values.getLength()); + for (var j = 0; j < values.getLength(); j++) { items.add(values.item(j).getTextContent()); } principalAttributes.put(name, items); @@ -172,17 +182,17 @@ private boolean isValidAssertion(final Date notBefore, final Date notOnOrAfter) return false; } - final DateTime currentTime = new DateTime(DateTimeZone.UTC); - final Interval validityRange = new Interval( - new DateTime(notBefore).minus(this.tolerance), - new DateTime(notOnOrAfter).plus(this.tolerance)); + final var currentTime = ZonedDateTime.now(ZoneOffset.UTC); + final var startTime = ZonedDateTime.ofInstant(notBefore.toInstant().minusMillis(tolerance), ZoneOffset.UTC); + final var endTime = ZonedDateTime.ofInstant(notOnOrAfter.toInstant().plusMillis(tolerance), ZoneOffset.UTC); - if (validityRange.contains(currentTime)) { + // This is awkward, because we want to INCLUDE startTime and EXCLUDE endTime + if (!currentTime.isBefore(startTime) && endTime.isAfter(currentTime)) { logger.debug("Current time is within the interval validity."); return true; } - if (currentTime.isBefore(validityRange.getStart())) { + if (currentTime.isBefore(startTime)) { logger.debug("Assertion is not yet valid"); } else { logger.debug("Assertion is expired"); @@ -192,7 +202,7 @@ private boolean isValidAssertion(final Date notBefore, final Date notOnOrAfter) @Override protected String retrieveResponseFromServer(final URL validationUrl, final String ticket) { - final String request = String.format( + final var request = String.format( SAML_REQUEST_TEMPLATE, generateId(), SamlUtils.formatForUtcTime(new Date()), @@ -208,7 +218,7 @@ protected String retrieveResponseFromServer(final URL validationUrl, final Strin conn.setDoOutput(true); - final Charset charset = CommonUtils.isNotBlank(getEncoding()) ? + final var charset = CommonUtils.isNotBlank(getEncoding()) ? Charset.forName(getEncoding()) : IOUtils.UTF8; conn.getOutputStream().write(request.getBytes(charset)); return IOUtils.readString(conn.getInputStream(), charset); @@ -226,13 +236,13 @@ public void setTolerance(final long tolerance) { } private String generateId() { - final byte[] data = new byte[16]; + final var data = new byte[16]; random.nextBytes(data); - final StringBuilder id = new StringBuilder(33); + final var id = new StringBuilder(33); id.append('_'); - for (int i = 0; i < data.length; i++) { - id.append(HEX_CHARS.charAt((data[i] & 0xF0) >> 4)); - id.append(HEX_CHARS.charAt(data[i] & 0x0F)); + for (final byte datum : data) { + id.append(HEX_CHARS.charAt((datum & 0xF0) >> 4)); + id.append(HEX_CHARS.charAt(datum & 0x0F)); } return id.toString(); } diff --git a/cas-client-support-saml/src/test/java/org/jasig/cas/client/util/SamlUtilsTests.java b/cas-client-support-saml/src/test/java/org/apereo/cas/client/util/SamlUtilsTests.java similarity index 66% rename from cas-client-support-saml/src/test/java/org/jasig/cas/client/util/SamlUtilsTests.java rename to cas-client-support-saml/src/test/java/org/apereo/cas/client/util/SamlUtilsTests.java index 0dad61a57..c42b13266 100644 --- a/cas-client-support-saml/src/test/java/org/jasig/cas/client/util/SamlUtilsTests.java +++ b/cas-client-support-saml/src/test/java/org/apereo/cas/client/util/SamlUtilsTests.java @@ -16,13 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.util; - -import java.util.Date; +package org.apereo.cas.client.util; import org.junit.Assert; import org.junit.Test; +import java.util.Calendar; +import java.util.Date; + /** * Test cases for {@link SamlUtils}. * @@ -33,9 +34,21 @@ public class SamlUtilsTests { @Test public void testParseUtcDate() { - final Date expected = new Date(1424437961025L); + final var expected = new Date(1424437961025L); Assert.assertEquals(expected, SamlUtils.parseUtcDate("2015-02-20T08:12:41.025-0500")); - final Date expectedNoMillis = new Date(1424437961000L); + final var expectedNoMillis = new Date(1424437961000L); Assert.assertEquals(expectedNoMillis, SamlUtils.parseUtcDate("2015-02-20T08:12:41-0500")); } -} \ No newline at end of file + + @Test + public void testFormatUtcDate() { + final var calendar = Calendar.getInstance(); + final var expected = "2015-02-20T13:12:41Z"; + + calendar.setTimeInMillis(1424437961025L); + Assert.assertEquals(expected, SamlUtils.formatForUtcTime(calendar.getTime())); + + calendar.setTimeInMillis(1424437961000L); + Assert.assertEquals(expected, SamlUtils.formatForUtcTime(calendar.getTime())); + } +} diff --git a/cas-client-support-saml/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java b/cas-client-support-saml/src/test/java/org/apereo/cas/client/validation/Saml11TicketValidationFilterTests.java similarity index 80% rename from cas-client-support-saml/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java rename to cas-client-support-saml/src/test/java/org/apereo/cas/client/validation/Saml11TicketValidationFilterTests.java index 4934304f9..ce31f0d06 100644 --- a/cas-client-support-saml/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidationFilterTests.java +++ b/cas-client-support-saml/src/test/java/org/apereo/cas/client/validation/Saml11TicketValidationFilterTests.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.validation; +package org.apereo.cas.client.validation; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -25,6 +25,8 @@ import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockServletContext; +import jakarta.servlet.FilterConfig; + /** * Unit test for {@link Saml11TicketValidationFilter}. * @@ -33,8 +35,8 @@ public class Saml11TicketValidationFilterTests { @Test public void testRenewInitParamThrows() throws Exception { - final Saml11TicketValidationFilter f = new Saml11TicketValidationFilter(); - final MockFilterConfig config = new MockFilterConfig(); + final var f = new Saml11TicketValidationFilter(); + final var config = new MockFilterConfig(); config.addInitParameter("casServerUrlPrefix", "https://cas.example.com"); config.addInitParameter("renew", "true"); try { @@ -47,15 +49,15 @@ public void testRenewInitParamThrows() throws Exception { @Test public void testAllowsRenewContextParam() throws Exception { - final Saml11TicketValidationFilter f = new Saml11TicketValidationFilter(); - final MockServletContext context = new MockServletContext(); + final var f = new Saml11TicketValidationFilter(); + final var context = new MockServletContext(); context.addInitParameter("casServerUrlPrefix", "https://cas.example.com"); context.addInitParameter("renew", "true"); context.addInitParameter("service", "http://www.jasig.org"); - final MockFilterConfig config = new MockFilterConfig(context); + final FilterConfig config = new MockFilterConfig(context); f.init(config); - final TicketValidator validator = f.getTicketValidator(config); + final var validator = f.getTicketValidator(config); assertTrue(validator instanceof Saml11TicketValidator); assertTrue(((Saml11TicketValidator) validator).isRenew()); } -} \ No newline at end of file +} diff --git a/cas-client-support-saml/src/test/java/org/apereo/cas/client/validation/Saml11TicketValidatorTests.java b/cas-client-support-saml/src/test/java/org/apereo/cas/client/validation/Saml11TicketValidatorTests.java new file mode 100644 index 000000000..1e538652d --- /dev/null +++ b/cas-client-support-saml/src/test/java/org/apereo/cas/client/validation/Saml11TicketValidatorTests.java @@ -0,0 +1,212 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + * + * 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.apereo.cas.client.validation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import java.io.UnsupportedEncodingException; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Collection; +import java.util.Date; +import org.apereo.cas.client.PublicTestHttpServer; +import org.apereo.cas.client.util.SamlUtils; +import org.junit.*; + +/** + * @author Scott Battaglia + * @version $Revision$ $Date$ + * @since 3.1.3 + */ +@Ignore +public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTests { + + private Saml11TicketValidator validator; + + private static final PublicTestHttpServer server = PublicTestHttpServer.instance(9051); + + private static final long CLIENT_TOLERANCE = 5000L; + private static final long SERVER_TOLERANCE = 1000L; + + @Before + public void setUp() throws Exception { + this.validator = new Saml11TicketValidator(CONST_CAS_SERVER_URL_PREFIX + "9051"); + this.validator.setTolerance(CLIENT_TOLERANCE); + } + + /*@AfterClass + public static void cleanUp() throws Exception { + server.shutdown(); + }*/ + + @Test + public void testCompatibilityValidationFailedResponse() throws UnsupportedEncodingException { + final var RESPONSE = "Success"; + + server.content = RESPONSE.getBytes(server.encoding); + try { + this.validator.validate("test", "test"); + fail("ValidationException expected due to 'no' response"); + } catch (final TicketValidationException e) { + // expected + } + } + + @Test + public void testCompatibilityValidationSuccessWithNoAttributes() throws UnsupportedEncodingException { + final var startTime = currentTimeRangeStart(); + final var endTime = currentTimeRangeEnd(); + final var now = new Date(); + final var RESPONSE = "testtestPrincipalurn:oasis:names:tc:SAML:1.0:cm:artifact"; + server.content = RESPONSE.getBytes(server.encoding); + try { + final var a = this.validator.validate("test", "test"); + assertEquals("testPrincipal", a.getPrincipal().getName()); + } catch (final TicketValidationException e) { + fail(e.toString()); + } + } + + @Test + public void testCompatibilityValidationSuccessInsideTolerance() throws UnsupportedEncodingException { + final var addedTime = CLIENT_TOLERANCE; + final var startTime = Date.from(currentTimeRangeStart().toInstant().plusMillis(addedTime)); + final var endTime = Date.from(currentTimeRangeEnd().toInstant().plusMillis(addedTime)); + final var now = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant().plusMillis(addedTime)); + final var RESPONSE = "testtestPrincipalurn:oasis:names:tc:SAML:1.0:cm:artifact"; + server.content = RESPONSE.getBytes(server.encoding); + try { + final var a = this.validator.validate("test", "test"); + assertEquals("testPrincipal", a.getPrincipal().getName()); + } catch (final TicketValidationException e) { + fail(e.toString()); + } + } + + @Test + public void testCompatibilityValidationFailedOutsideTolerance() throws UnsupportedEncodingException { + final var addedTime = 2 * CLIENT_TOLERANCE; + final var startTime = Date.from(currentTimeRangeStart().toInstant().plusMillis(addedTime)); + final var endTime = Date.from(currentTimeRangeEnd().toInstant().plusMillis(addedTime)); + final var now = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant().plusMillis(addedTime)); + final var RESPONSE = "testtestPrincipalurn:oasis:names:tc:SAML:1.0:cm:artifact"; + server.content = RESPONSE.getBytes(server.encoding); + try { + this.validator.validate("test", "test"); + fail("ValidationException expected due to out of tolerance"); + } catch (final TicketValidationException e) { + // expected + } + } + + @Test + public void openSaml2GeneratedResponse() throws UnsupportedEncodingException { + final var startTime = currentTimeRangeStart(); + final var endTime = currentTimeRangeEnd(); + final var now = new Date(); + + final var response = "" + + "" + + "" + + "" + + "" + + "https://example.com/test-client/secure/" + + "" + + "" + + "testPrincipal" + + "urn:oasis:names:tc:SAML:1.0:cm:artifact" + + "" + + "testPrincipal" + + "urn:oasis:names:tc:SAML:1.0:cm:artifact" + + "12345" + + "" + + "ACTIVE" + + "" + + "employee" + + "staff" + + "student"; + + server.content = response.getBytes(server.encoding); + try { + final var a = this.validator.validate("test", "test"); + assertEquals( + "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport", + a.getAttributes().get(Saml11TicketValidator.AUTH_METHOD_ATTRIBUTE)); + assertEquals("testPrincipal", a.getPrincipal().getName()); + assertEquals("12345", a.getPrincipal().getAttributes().get("uid")); + assertEquals("ACTIVE", a.getPrincipal().getAttributes().get("accountState")); + assertEquals(3, ((Collection) a.getPrincipal().getAttributes().get("eduPersonAffiliation")).size()); + } catch (final TicketValidationException e) { + fail(e.toString()); + } + } + + private static ZonedDateTime currentTimeRangeStart() { + return ZonedDateTime.now(ZoneOffset.UTC).minus(SERVER_TOLERANCE, ChronoUnit.MILLIS); + } + + private static ZonedDateTime currentTimeRangeEnd() { + return ZonedDateTime.now(ZoneOffset.UTC).plus(SERVER_TOLERANCE, ChronoUnit.MILLIS); + } +} diff --git a/cas-client-support-saml/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java b/cas-client-support-saml/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java deleted file mode 100644 index a5c8091f0..000000000 --- a/cas-client-support-saml/src/test/java/org/jasig/cas/client/validation/Saml11TicketValidatorTests.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.validation; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import java.io.UnsupportedEncodingException; -import java.util.Collection; -import java.util.Date; -import org.jasig.cas.client.PublicTestHttpServer; -import org.jasig.cas.client.util.SamlUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Interval; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -/** - * @author Scott Battaglia - * @version $Revision$ $Date$ - * @since 3.1.3 - */ -@Ignore -public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTests { - - private Saml11TicketValidator validator; - - private static final PublicTestHttpServer server = PublicTestHttpServer.instance(9051); - - @Before - public void setUp() throws Exception { - this.validator = new Saml11TicketValidator(AbstractTicketValidatorTests.CONST_CAS_SERVER_URL_PREFIX + "9051"); - this.validator.setTolerance(1000L); - } - - /*@AfterClass - public static void cleanUp() throws Exception { - server.shutdown(); - }*/ - - @Test - public void testCompatibilityValidationFailedResponse() throws UnsupportedEncodingException { - final String RESPONSE = "Success"; - - server.content = RESPONSE.getBytes(server.encoding); - try { - this.validator.validate("test", "test"); - fail("ValidationException expected due to 'no' response"); - } catch (final TicketValidationException e) { - // expected - } - } - - @Test - public void testCompatibilityValidationSuccessWithNoAttributes() throws UnsupportedEncodingException { - final Interval range = currentTimeRangeInterval(); - final Date now = new Date(); - final String RESPONSE = "testtestPrincipalurn:oasis:names:tc:SAML:1.0:cm:artifact"; - server.content = RESPONSE.getBytes(server.encoding); - try { - final Assertion a = this.validator.validate("test", "test"); - assertEquals("testPrincipal", a.getPrincipal().getName()); - } catch (final TicketValidationException e) { - fail(e.toString()); - } - } - - @Test - public void openSaml2GeneratedResponse() throws UnsupportedEncodingException { - final Interval range = currentTimeRangeInterval(); - final Date now = new Date(); - - final String response = "" - + "" - + "" - + "" - + "" - + "https://example.com/test-client/secure/" - + "" - + "" - + "testPrincipal" - + "urn:oasis:names:tc:SAML:1.0:cm:artifact" - + "" - + "testPrincipal" - + "urn:oasis:names:tc:SAML:1.0:cm:artifact" - + "12345" - + "" - + "ACTIVE" - + "" - + "employee" - + "staff" - + "student"; - - server.content = response.getBytes(server.encoding); - try { - final Assertion a = this.validator.validate("test", "test"); - assertEquals( - "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport", - a.getAttributes().get(Saml11TicketValidator.AUTH_METHOD_ATTRIBUTE)); - assertEquals("testPrincipal", a.getPrincipal().getName()); - assertEquals("12345", a.getPrincipal().getAttributes().get("uid")); - assertEquals("ACTIVE", a.getPrincipal().getAttributes().get("accountState")); - assertEquals(3, ((Collection) a.getPrincipal().getAttributes().get("eduPersonAffiliation")).size()); - } catch (final TicketValidationException e) { - fail(e.toString()); - } - } - - private Interval currentTimeRangeInterval() { - return new Interval(new DateTime(DateTimeZone.UTC).minus(5000), new DateTime(DateTimeZone.UTC).plus(200000000)); - } -} \ No newline at end of file diff --git a/cas-client-support-springboot/NOTICE b/cas-client-support-springboot/NOTICE index 253d78c16..a51ad58f8 100644 --- a/cas-client-support-springboot/NOTICE +++ b/cas-client-support-springboot/NOTICE @@ -29,15 +29,14 @@ This project includes: Jackson-core under The Apache Software License, Version 2.0 jackson-databind under The Apache Software License, Version 2.0 Jakarta Annotations API under EPL 2.0 or GPL2 w/ CPE - Jasig CAS Client for Java - Core under Apache License Version 2.0 - Jasig CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 - Jasig CAS Client for Java - Spring Boot Support under Apache License Version 2.0 + Apereo CAS Client for Java - Core under Apache License Version 2.0 + Apereo CAS Client for Java - SAML Protocol Support under Apache License Version 2.0 + Apereo CAS Client for Java - Spring Boot Support under Apache License Version 2.0 Java Servlet API under CDDL + GPLv2 with classpath exception JavaBeans Activation Framework API jar under CDDL/GPLv2+CE JAXB Core under CDDL+GPL License jaxb-api under CDDL 1.1 or GPL2 w/ CPE JCL 1.2 implemented over SLF4J under Apache License, Version 2.0 - Joda-Time under Apache License, Version 2.0 JUL to SLF4J bridge under MIT License JUnit under Eclipse Public License 1.0 Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License diff --git a/cas-client-support-springboot/pom.xml b/cas-client-support-springboot/pom.xml index 299b6ab12..ceca0c4a7 100644 --- a/cas-client-support-springboot/pom.xml +++ b/cas-client-support-springboot/pom.xml @@ -20,14 +20,14 @@ --> - org.jasig.cas.client - 3.6.4 + org.apereo.cas.client + 4.1.2-SNAPSHOT cas-client 4.0.0 cas-client-support-springboot jar - Jasig CAS Client for Java - Spring Boot Support + Apereo CAS Client for Java - Spring Boot Support Library providing annotation-based configuration support for CAS Java clients. Primarily designed for super easy CASification of Spring Boot apps. @@ -46,12 +46,12 @@ - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${project.version} - org.jasig.cas.client + org.apereo.cas.client cas-client-support-saml ${project.version} @@ -80,13 +80,14 @@ org.springframework.security - spring-security-cas + spring-security-core + ${spring.security.version} provided - + - org.jasig.cas.client + org.apereo.cas.client cas-client-core ${project.version} test-jar @@ -98,8 +99,4 @@ test - - - 2.6.1 - diff --git a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfiguration.java b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfiguration.java similarity index 80% rename from cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfiguration.java rename to cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfiguration.java index 3feaeaa04..c585ed695 100644 --- a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfiguration.java +++ b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfiguration.java @@ -6,9 +6,9 @@ * 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 the following location: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * 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 @@ -16,18 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.boot.configuration; +package org.apereo.cas.client.boot.configuration; -import org.jasig.cas.client.authentication.AuthenticationFilter; -import org.jasig.cas.client.authentication.Saml11AuthenticationFilter; -import org.jasig.cas.client.configuration.ConfigurationKeys; -import org.jasig.cas.client.session.SingleSignOutFilter; -import org.jasig.cas.client.session.SingleSignOutHttpSessionListener; -import org.jasig.cas.client.util.AssertionThreadLocalFilter; -import org.jasig.cas.client.util.HttpServletRequestWrapperFilter; -import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter; -import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter; -import org.jasig.cas.client.validation.Saml11TicketValidationFilter; +import org.apereo.cas.client.authentication.AuthenticationFilter; +import org.apereo.cas.client.authentication.Saml11AuthenticationFilter; +import org.apereo.cas.client.configuration.ConfigurationKeys; +import org.apereo.cas.client.session.SingleSignOutFilter; +import org.apereo.cas.client.session.SingleSignOutHttpSessionListener; +import org.apereo.cas.client.util.AssertionThreadLocalFilter; +import org.apereo.cas.client.util.HttpServletRequestWrapperFilter; +import org.apereo.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter; +import org.apereo.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter; +import org.apereo.cas.client.validation.Saml11TicketValidationFilter; + +import jakarta.servlet.Filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -38,21 +40,17 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; -import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken; -import org.springframework.security.cas.authentication.CasAuthenticationToken; -import org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.User; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import javax.servlet.Filter; -import java.io.File; -import java.io.FileWriter; + import java.util.Collection; import java.util.EventListener; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Properties; +import java.util.stream.Collectors; /** * Configuration class providing default CAS client infrastructure filters. @@ -82,7 +80,7 @@ private static void initFilter(final FilterRegistrationBean filterRegistrationBe final Filter targetFilter, final int filterOrder, final Map initParams, - final List urlPatterns) { + final Collection urlPatterns) { filterRegistrationBean.setFilter(targetFilter); filterRegistrationBean.setOrder(filterOrder); @@ -95,7 +93,7 @@ private static void initFilter(final FilterRegistrationBean filterRegistrationBe @Bean @ConditionalOnProperty(prefix = "cas", name = "skipTicketValidation", havingValue = "false", matchIfMissing = true) public FilterRegistrationBean casValidationFilter() { - final FilterRegistrationBean validationFilter = new FilterRegistrationBean(); + final var validationFilter = new FilterRegistrationBean(); final Filter targetCasValidationFilter; switch (this.configProps.getValidationType()) { case CAS: @@ -154,10 +152,10 @@ public FilterRegistrationBean casValidationFilter() { @Bean public FilterRegistrationBean casAuthenticationFilter() { - final FilterRegistrationBean authnFilter = new FilterRegistrationBean(); + final var authnFilter = new FilterRegistrationBean(); final Filter targetCasAuthnFilter = this.configProps.getValidationType() == EnableCasClient.ValidationType.CAS - || configProps.getValidationType() == EnableCasClient.ValidationType.CAS3 + || configProps.getValidationType() == EnableCasClient.ValidationType.CAS3 ? new AuthenticationFilter() : new Saml11AuthenticationFilter(); @@ -179,7 +177,7 @@ public FilterRegistrationBean casAuthenticationFilter() { @Bean public FilterRegistrationBean casHttpServletRequestWrapperFilter() { - final FilterRegistrationBean reqWrapperFilter = new FilterRegistrationBean(); + final var reqWrapperFilter = new FilterRegistrationBean(); reqWrapperFilter.setFilter(new HttpServletRequestWrapperFilter()); if (!this.configProps.getRequestWrapperUrlPatterns().isEmpty()) { reqWrapperFilter.setUrlPatterns(this.configProps.getRequestWrapperUrlPatterns()); @@ -194,7 +192,7 @@ public FilterRegistrationBean casHttpServletRequestWrapperFilter() { @Bean public FilterRegistrationBean casAssertionThreadLocalFilter() { - final FilterRegistrationBean assertionTLFilter = new FilterRegistrationBean(); + final var assertionTLFilter = new FilterRegistrationBean(); assertionTLFilter.setFilter(new AssertionThreadLocalFilter()); if (!this.configProps.getAssertionThreadLocalUrlPatterns().isEmpty()) { assertionTLFilter.setUrlPatterns(this.configProps.getAssertionThreadLocalUrlPatterns()); @@ -214,9 +212,9 @@ void setConfigurers(final Collection configurers) { } if (configurers.size() > 1) { throw new IllegalStateException(configurers.size() + " implementations of " + - "CasClientConfigurer were found when only 1 was expected. " + - "Refactor the configuration such that CasClientConfigurer is " + - "implemented only once or not at all."); + "CasClientConfigurer were found when only 1 was expected. " + + "Refactor the configuration such that CasClientConfigurer is " + + "implemented only once or not at all."); } this.casClientConfigurer = configurers.iterator().next(); } @@ -224,7 +222,7 @@ void setConfigurers(final Collection configurers) { @Bean @ConditionalOnProperty(prefix = "cas", value = "single-logout.enabled", havingValue = "true") public FilterRegistrationBean casSingleSignOutFilter() { - final FilterRegistrationBean singleSignOutFilter = new FilterRegistrationBean(); + final var singleSignOutFilter = new FilterRegistrationBean(); singleSignOutFilter.setFilter(new SingleSignOutFilter()); final Map initParameters = new HashMap<>(1); initParameters.put(ConfigurationKeys.CAS_SERVER_URL_PREFIX.getName(), configProps.getServerUrlPrefix()); @@ -236,7 +234,7 @@ public FilterRegistrationBean casSingleSignOutFilter() { @Bean @ConditionalOnProperty(prefix = "cas", value = "single-logout.enabled", havingValue = "true") public ServletListenerRegistrationBean casSingleSignOutListener() { - ServletListenerRegistrationBean singleSignOutListener = new ServletListenerRegistrationBean<>(); + final var singleSignOutListener = new ServletListenerRegistrationBean<>(); singleSignOutListener.setListener(new SingleSignOutHttpSessionListener()); singleSignOutListener.setOrder(Ordered.HIGHEST_PRECEDENCE); return singleSignOutListener; @@ -244,14 +242,14 @@ public ServletListenerRegistrationBean casSingleSignOutListener() @Configuration @EnableConfigurationProperties(CasClientConfigurationProperties.class) - @ConditionalOnClass(CasAuthenticationToken.class) + @ConditionalOnClass(AuthenticationUserDetailsService.class) @ConditionalOnProperty(prefix = "cas", value = "use-session", havingValue = "true", matchIfMissing = true) public class SpringSecurityAssertionAutoConfiguration { @Bean @ConditionalOnMissingBean(name = "springSecurityAssertionSessionContextFilter") public FilterRegistrationBean springSecurityAssertionSessionContextFilter() { - final FilterRegistrationBean filter = new FilterRegistrationBean(); + final var filter = new FilterRegistrationBean(); filter.setFilter(new SpringSecurityAssertionSessionContextFilter(springSecurityCasUserDetailsService())); filter.setEnabled(!configProps.getAttributeAuthorities().isEmpty()); filter.setOrder(0); @@ -263,9 +261,12 @@ public FilterRegistrationBean springSecurityAssertionSessionContextFilter() { @Bean @ConditionalOnMissingBean(name = "springSecurityCasUserDetailsService") - public AuthenticationUserDetailsService springSecurityCasUserDetailsService() { - return new GrantedAuthorityFromAssertionAttributesUserDetailsService( - configProps.getAttributeAuthorities().toArray(new String[]{})); + public AuthenticationUserDetailsService springSecurityCasUserDetailsService() { + return token -> { + final var authorities = configProps.getAttributeAuthorities() + .stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()); + return new User(token.getPrincipal().toString(), null, authorities); + }; } } } diff --git a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfigurationProperties.java b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfigurationProperties.java similarity index 98% rename from cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfigurationProperties.java rename to cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfigurationProperties.java index c28495321..013c61106 100644 --- a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfigurationProperties.java +++ b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfigurationProperties.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.boot.configuration; +package org.apereo.cas.client.boot.configuration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.lang.NonNull; @@ -137,7 +137,7 @@ public boolean isEnabled() { return enabled; } - public void setEnabled(boolean enabled) { + public void setEnabled(final boolean enabled) { this.enabled = enabled; } } diff --git a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfigurer.java b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfigurer.java similarity index 97% rename from cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfigurer.java rename to cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfigurer.java index d2dd2740f..deb309d89 100644 --- a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/CasClientConfigurer.java +++ b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/CasClientConfigurer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.boot.configuration; +package org.apereo.cas.client.boot.configuration; import org.springframework.boot.web.servlet.FilterRegistrationBean; diff --git a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/EnableCasClient.java b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/EnableCasClient.java similarity index 97% rename from cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/EnableCasClient.java rename to cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/EnableCasClient.java index 0acc5501f..77f21e41f 100644 --- a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/EnableCasClient.java +++ b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/EnableCasClient.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jasig.cas.client.boot.configuration; +package org.apereo.cas.client.boot.configuration; import org.springframework.context.annotation.Import; diff --git a/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/SpringSecurityAssertionSessionContextFilter.java b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/SpringSecurityAssertionSessionContextFilter.java new file mode 100644 index 000000000..f03ca8665 --- /dev/null +++ b/cas-client-support-springboot/src/main/java/org/apereo/cas/client/boot/configuration/SpringSecurityAssertionSessionContextFilter.java @@ -0,0 +1,98 @@ +/** + * Licensed to Apereo under one or more contributor license + * agreements. See the NOTICE file distributed with this work + * for additional information regarding copyright ownership. + * Apereo 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 the following location: + *

+ * 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.apereo.cas.client.boot.configuration; + +import org.apereo.cas.client.util.AbstractCasFilter; +import org.apereo.cas.client.util.AbstractConfigurationFilter; +import org.apereo.cas.client.validation.Assertion; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; + +import java.io.IOException; +import java.io.Serial; +import java.util.ArrayList; + +/** + * Populates the Spring Security context with + * the CAS authentication fetched from assertion + * and processing roles, attributes, etc. + * + * @author Misagh Moayyed + * @since 3.6.2 + */ +public class SpringSecurityAssertionSessionContextFilter extends AbstractConfigurationFilter { + private final AuthenticationUserDetailsService userDetailsService; + + private final String[] attributes; + + public SpringSecurityAssertionSessionContextFilter( + final AuthenticationUserDetailsService userDetailsService, + final String... attributes) { + this.userDetailsService = userDetailsService; + this.attributes = attributes; + } + + @Override + public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, + final FilterChain filterChain) throws IOException, ServletException { + final var request = (HttpServletRequest) servletRequest; + final ServletResponse response = (HttpServletResponse) servletResponse; + final var session = request.getSession(); + if (session != null && session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) != null) { + final var assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); + + final var authentication = new CasAuthenticationToken(assertion); + final var userDetails = userDetailsService.loadUserDetails(authentication); + authentication.getAuthorities().addAll(userDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + filterChain.doFilter(request, response); + } + + private static class CasAuthenticationToken extends AbstractAuthenticationToken { + @Serial + private static final long serialVersionUID = -270498735829222143L; + + private final Assertion assertion; + + public CasAuthenticationToken(final Assertion assertion) { + super(new ArrayList<>()); + this.assertion = assertion; + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getPrincipal() { + return assertion.getPrincipal().getName(); + } + } +} diff --git a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/SpringSecurityAssertionSessionContextFilter.java b/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/SpringSecurityAssertionSessionContextFilter.java deleted file mode 100644 index 9e50919dc..000000000 --- a/cas-client-support-springboot/src/main/java/org/jasig/cas/client/boot/configuration/SpringSecurityAssertionSessionContextFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Licensed to Apereo under one or more contributor license - * agreements. See the NOTICE file distributed with this work - * for additional information regarding copyright ownership. - * Apereo 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 the following location: - * - * 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.jasig.cas.client.boot.configuration; - -import org.jasig.cas.client.util.AbstractCasFilter; -import org.jasig.cas.client.util.AbstractConfigurationFilter; -import org.jasig.cas.client.validation.Assertion; -import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken; -import org.springframework.security.cas.authentication.CasAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; -import org.springframework.security.core.userdetails.UserDetails; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.io.IOException; - -/** - * Populates the Spring Security context with - * the CAS authentication fetched from assertion - * and processing roles, attributes, etc. - * - * @author Misagh Moayyed - * @since 3.6.2 - */ -public class SpringSecurityAssertionSessionContextFilter extends AbstractConfigurationFilter { - private final AuthenticationUserDetailsService userDetailsService; - - private final String[] attributes; - - public SpringSecurityAssertionSessionContextFilter( - final AuthenticationUserDetailsService userDetailsService, - final String... attributes) { - this.userDetailsService = userDetailsService; - this.attributes = attributes; - } - - @Override - public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, - final FilterChain filterChain) throws IOException, ServletException { - final HttpServletRequest request = (HttpServletRequest) servletRequest; - final HttpServletResponse response = (HttpServletResponse) servletResponse; - final HttpSession session = request.getSession(); - if (session != null && session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION) != null) { - final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); - - final CasAssertionAuthenticationToken token = new CasAssertionAuthenticationToken(assertion, ""); - final UserDetails userDetails = userDetailsService.loadUserDetails(token); - final CasAuthenticationToken authentication = new CasAuthenticationToken("CasAuthenticationToken", - userDetails, - userDetails, - userDetails.getAuthorities(), - userDetails, - assertion); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - filterChain.doFilter(request, response); - } -} diff --git a/pom.xml b/pom.xml index e1eacf0cd..323481ad7 100644 --- a/pom.xml +++ b/pom.xml @@ -20,55 +20,65 @@ --> - org.jasig.parent - jasig-parent - 41 + org.sonatype.oss + oss-parent + 9 4.0.0 - org.jasig.cas.client - 3.6.4 + org.apereo.cas.client + 4.1.2-SNAPSHOT cas-client pom Apereo CAS Client for Java Apereo CAS Client for Java is the integration point for applications that want to speak with a CAS - server, either via the CAS 1.0 or CAS 2.0 protocol. + server, either via the CAS 1.0 or CAS 2.0/3.0 protocol. https://www.apereo.org/cas + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + apereo + Apereo + Apereo Foundation + https://www.apereo.org/ + + + scm:git:git@github.com:apereo/java-cas-client.git scm:git:git@github.com:apereo/java-cas-client.git https://github.com/apereo/java-cas-client - cas-client-3.6.4 + + + sonatype-releases + https://oss.sonatype.org/content/repositories/releases/ + + + spring-milestones + https://repo.spring.io/milestone + + + snapshots-snapshots + https://oss.sonatype.org/content/repositories/snapshots + false + true + + + 2006 - - - - battags - Scott Battaglia - scott.battaglia@gmail.com - http://www.scottbattaglia.com - - Project Admin - Developer - - -5 - - - serac - Marvin S. Addison - marvin.addison@gmail.com - - Developer - - -5 - - - + Apereo https://www.apereo.org @@ -76,10 +86,19 @@ + + org.sonatype.central + central-publishing-maven-plugin + ${central.publishing.plugin.version} + true + + central + + org.apache.maven.plugins maven-assembly-plugin - 3.3.0 + ${maven.assembly.plugin.version} ${basedir}/assembly.xml @@ -89,16 +108,16 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + ${maven.compiler.plugin.version} - 1.8 - 1.8 + ${project.build.sourceVersion} + ${project.build.targetVersion} org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + ${maven.surefire.plugin.version} **/*Tests* @@ -107,22 +126,10 @@ 1 - - maven-source-plugin - 3.2.1 - - - attach-sources - - jar - - - - org.apache.maven.plugins maven-enforcer-plugin - 3.0.0 + ${maven.enforcer.plugin.version} enforce-banned-dependencies @@ -134,6 +141,8 @@ commons-logging + javax.servlet-api + javax.xml.bind @@ -143,40 +152,10 @@ - - com.mycila.maven-license-plugin - maven-license-plugin - -

src/licensing/header.txt
- true - - src/licensing/header-definitions.xml - - true - - **/.idea/** - LICENSE - **/INSTALL* - **/NOTICE* - **/README* - **/readme* - **/*.log - **/*.license - **/*.txt - **/*.crt - **/*.crl - **/*.key - **/.gitignore - **/overlays/** - src/licensing/** - - - - org.apache.maven.plugins maven-javadoc-plugin - 3.3.1 + ${maven.javadoc.plugin.version} none @@ -222,13 +201,19 @@ log4j log4j test - 1.2.17 + ${log4j.version} com.fasterxml.jackson.core jackson-databind ${jackson.version} + + com.nimbusds + nimbus-jose-jwt + ${nimbus.jose.jwt.version} + true + @@ -236,7 +221,7 @@ junit junit - 4.13.2 + ${junit4.version} test @@ -248,31 +233,22 @@ commons-codec commons-codec - 1.15 + ${commons.codec.version} compile org.bouncycastle - bcpkix-jdk15on - 1.70 + bcpkix-jdk18on + ${bouncycastle.version} compile - javax.servlet - javax.servlet-api - 4.0.1 + jakarta.servlet + jakarta.servlet-api + ${javax.servlet.version} + jar provided - - javax.xml.bind - jaxb-api - 2.3.1 - - - org.glassfish.jaxb - jaxb-core - 2.3.0.1 - org.slf4j jcl-over-slf4j @@ -289,26 +265,36 @@ cas-client-core - - cas-client-integration-jboss cas-client-support-distributed-ehcache cas-client-support-distributed-memcached cas-client-support-saml cas-client-support-springboot - cas-client-integration-tomcat-common - cas-client-integration-tomcat-v6 - cas-client-integration-tomcat-v7 - cas-client-integration-tomcat-v8 - cas-client-integration-tomcat-v85 - cas-client-integration-tomcat-v90 - cas-client-integration-jetty - 5.3.14 - 2.6.11 - 3.0.2 - 1.7.32 - 2.13.0 + 4.13.2 + 7.0.8 + 3.12.0 + 2.0.18 + 2.22.1 + 6.1.0 + 1.22.0 + 1.2.17 + 1.3.0 + 1.85 + 4.1.0 + 7.1.0 + 10.9.1 + 3.15.0 + 3.6.3 + 3.5.6 + 3.8.0 + 3.12.0 + 3.3.0 + 0.11.0 + + 21 + 21 + UTF-8 diff --git a/src/licensing/header.txt b/src/licensing/header.txt index ac254285d..c0c4fbc0b 100644 --- a/src/licensing/header.txt +++ b/src/licensing/header.txt @@ -17,10 +17,10 @@ under the License. ==== -Licensed to Jasig under one or more contributor license +Licensed to Apereo under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. -Jasig licenses this file to you under the Apache License, +Apereo 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 the following location: @@ -32,4 +32,4 @@ 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. \ No newline at end of file +under the License.