Compare commits

...

430 Commits

Author SHA1 Message Date
Alexander Buntakov c516025070
Merge pull request #1 from TouchInstinct/feature/skip-internal-ip
support internal requests skip
2019-12-27 18:49:12 +03:00
Alexander Buntakov 71e71f15ff support internal requests skip 2019-12-27 17:53:03 +03:00
dependabot-preview[bot] 448b08c43c build(deps): bump jetty.version (#409)
Bumps `jetty.version` from 9.4.24.v20191120 to 9.4.25.v20191220.

Updates `jetty-security` from 9.4.24.v20191120 to 9.4.25.v20191220
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.24.v20191120...jetty-9.4.25.v20191220)

Updates `jetty-webapp` from 9.4.24.v20191120 to 9.4.25.v20191220
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.24.v20191120...jetty-9.4.25.v20191220)

Updates `jetty-plus` from 9.4.24.v20191120 to 9.4.25.v20191220
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.24.v20191120...jetty-9.4.25.v20191220)

Updates `jetty-annotations` from 9.4.24.v20191120 to 9.4.25.v20191220
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.24.v20191120...jetty-9.4.25.v20191220)

Updates `apache-jsp` from 9.4.24.v20191120 to 9.4.25.v20191220
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.24.v20191120...jetty-9.4.25.v20191220)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-24 05:46:06 +00:00
dependabot-preview[bot] 06f87f85fc build(deps): bump maven-source-plugin from 3.2.0 to 3.2.1 (#408)
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/apache/maven-source-plugin/releases)
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.0...maven-source-plugin-3.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-23 05:41:20 +00:00
renovate[bot] f2c44b7e74 renovatebot(deps): update dependency org.apache.tomcat:tomcat-catalina to v7.0.99 (#406) 2019-12-17 09:33:26 +00:00
renovate[bot] 94d81c32ba renovatebot(deps): update slf4j.version to v1.7.30 (#405) 2019-12-16 21:42:40 +00:00
renovate[bot] a96a13c630 renovatebot(deps): update dependency org.apache.tomcat:tomcat-catalina to v8.5.50 (#403) 2019-12-12 12:46:16 +00:00
renovate[bot] 06f3ebc7c2 renovatebot(deps): update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.50 (#402) 2019-12-12 12:46:08 +00:00
renovate[bot] 0dce0aa69e renovatebot(deps): update tomcat.version to v9.0.30 (#401) 2019-12-12 10:02:06 +00:00
renovate[bot] 8a665e1cb1 renovatebot(deps): update spring boot to v2.2.2.release (#400) 2019-12-06 12:42:38 +00:00
renovate[bot] dce1a94d9a renovatebot(deps): update spring core to v5.2.2.release (#399) 2019-12-03 13:17:34 +00:00
Petr Bodnar 76fb6a4f9c README.md - Only list used properties for Single Log Out (#398)
* README.md - Only list used properties for Single Log Out

Properties `casServerUrlPrefix` and `frontLogoutParameterName` are not really read by the SLO filter. Mainly the 1st one has no usage in this filter by design.

* README.md - Only list used properties for Single Log Out

Also removing unused `casServerUrlPrefix` from the code examples.
2019-11-30 12:21:06 +04:00
dependabot-preview[bot] 8d38080354 build(deps): bump jetty.version (#397)
Bumps `jetty.version` from 9.4.22.v20191022 to 9.4.24.v20191120.

Updates `jetty-security` from 9.4.22.v20191022 to 9.4.24.v20191120
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.22.v20191022...jetty-9.4.24.v20191120)

Updates `jetty-webapp` from 9.4.22.v20191022 to 9.4.24.v20191120
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.22.v20191022...jetty-9.4.24.v20191120)

Updates `jetty-plus` from 9.4.22.v20191022 to 9.4.24.v20191120
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.22.v20191022...jetty-9.4.24.v20191120)

Updates `jetty-annotations` from 9.4.22.v20191022 to 9.4.24.v20191120
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.22.v20191022...jetty-9.4.24.v20191120)

Updates `apache-jsp` from 9.4.22.v20191022 to 9.4.24.v20191120
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.22.v20191022...jetty-9.4.24.v20191120)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-22 05:38:31 +00:00
renovate[bot] be803939d8 renovatebot(deps): update dependency org.apache.tomcat:tomcat-catalina to v8.5.49 (#393) 2019-11-21 13:42:30 +00:00
renovate[bot] af1bbb2f32 renovatebot(deps): update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.49 (#392) 2019-11-21 13:42:21 +00:00
renovate[bot] c5a5a9961b renovatebot(deps): update dependency com.fasterxml.jackson.core:jackson-databind to v2.10.1 (#390) 2019-11-21 13:42:15 +00:00
renovate[bot] 6e2fbec2a4 renovatebot(deps): update tomcat.version to v9.0.29 (#394) 2019-11-21 13:39:17 +00:00
Misagh Moayyed 638c2d6fe4
fix maven jar plugin version 2019-11-21 17:31:58 +04:00
dependabot-preview[bot] efd6dbb491 Bump maven-source-plugin from 3.1.0 to 3.2.0 (#387)
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/apache/maven-source-plugin/releases)
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.1.0...maven-source-plugin-3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-07 13:22:49 +04:00
renovate[bot] 905ce61e82 renovatebot(deps): update dependency org.apache.maven.plugins:ma… (#383) 2019-11-07 13:22:32 +04:00
dependabot-preview[bot] 3ba892e482 Bump maven-jar-plugin from 3.1.1 to 3.2.0 (#385)
Bumps [maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/apache/maven-jar-plugin/releases)
- [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.1.1...maven-jar-plugin-3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-07 13:22:15 +04:00
Gahon 62cc93399f add central logout support for springboot (#388)
* add dependence to generated metadata for springboot

* add central logout support for springboot
2019-11-07 11:56:45 +04:00
renovate[bot] cd67d874a2 renovatebot(deps): update dependency org.springframework.boot:spring-boot-starter to v2.2.1.release (#389) 2019-11-07 00:58:45 +00:00
renovate[bot] 46381476e9 renovatebot(deps): update dependency org.jasig.cas.client:cas-client to v3.6.1 (#369) 2019-11-04 18:25:30 +00:00
renovate[bot] d2538f378d renovatebot(deps): update spring core to v5.2.1.release (#381) 2019-11-04 18:23:06 +00:00
dependabot-preview[bot] f14d836e03 Bump spring.version from 5.2.0.RELEASE to 5.2.1.RELEASE (#384)
Bumps `spring.version` from 5.2.0.RELEASE to 5.2.1.RELEASE.

Updates `spring-core` from 5.2.0.RELEASE to 5.2.1.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.2.0.RELEASE...v5.2.1.RELEASE)

Updates `spring-context` from 5.2.0.RELEASE to 5.2.1.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.2.0.RELEASE...v5.2.1.RELEASE)

Updates `spring-web` from 5.2.0.RELEASE to 5.2.1.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.2.0.RELEASE...v5.2.1.RELEASE)

Updates `spring-test` from 5.2.0.RELEASE to 5.2.1.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.2.0.RELEASE...v5.2.1.RELEASE)

Updates `spring-beans` from 5.2.0.RELEASE to 5.2.1.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.2.0.RELEASE...v5.2.1.RELEASE)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-04 18:23:02 +00:00
renovate[bot] e2e4ea9fa1 renovatebot(deps): update dependency org.apache.maven.plugins:ma… (#382) 2019-11-04 22:22:45 +04:00
dependabot-preview[bot] df89820368 Bump maven-assembly-plugin from 3.1.1 to 3.2.0 (#386)
Bumps [maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/apache/maven-assembly-plugin/releases)
- [Commits](https://github.com/apache/maven-assembly-plugin/compare/maven-assembly-plugin-3.1.1...maven-assembly-plugin-3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-04 22:22:26 +04:00
Misagh Moayyed 3005cc8607
Update .mergify.yml 2019-11-04 22:21:59 +04:00
renovate[bot] e0374d61ac renovatebot(deps): update dependency joda-time:joda-time to v2.1… (#378) 2019-10-31 23:37:23 +04:00
renovate[bot] 360ff59ddd renovatebot(deps): update dependency org.apache.tomcat:tomcat-ca… (#372) 2019-10-31 23:37:03 +04:00
renovate[bot] 59f42b7edf renovatebot(deps): update tomcat.version to v9.0.27 (#370) 2019-10-31 23:36:44 +04:00
dependabot-preview[bot] 409bd553ba Bump jetty.version from 9.4.21.v20190926 to 9.4.22.v20191022 (#377)
Bumps `jetty.version` from 9.4.21.v20190926 to 9.4.22.v20191022.

Updates `jetty-security` from 9.4.21.v20190926 to 9.4.22.v20191022
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.21.v20190926...jetty-9.4.22.v20191022)

Updates `jetty-webapp` from 9.4.21.v20190926 to 9.4.22.v20191022
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.21.v20190926...jetty-9.4.22.v20191022)

Updates `jetty-plus` from 9.4.21.v20190926 to 9.4.22.v20191022
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.21.v20190926...jetty-9.4.22.v20191022)

Updates `jetty-annotations` from 9.4.21.v20190926 to 9.4.22.v20191022
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.21.v20190926...jetty-9.4.22.v20191022)

Updates `apache-jsp` from 9.4.21.v20190926 to 9.4.22.v20191022
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.21.v20190926...jetty-9.4.22.v20191022)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-31 23:36:23 +04:00
dependabot-preview[bot] 3ec16e8aaf Bump joda-time from 2.10.4 to 2.10.5 (#379)
Bumps [joda-time](https://github.com/JodaOrg/joda-time) from 2.10.4 to 2.10.5.
- [Release notes](https://github.com/JodaOrg/joda-time/releases)
- [Changelog](https://github.com/JodaOrg/joda-time/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/JodaOrg/joda-time/compare/v2.10.4...v2.10.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-31 23:35:14 +04:00
renovate[bot] 08bedcf889 renovatebot(deps): update slf4j.version to v1.7.29 (#380) 2019-10-31 23:34:59 +04:00
Misagh Moayyed da7ff03cff
Update .mergify.yml 2019-10-24 19:04:44 +04:00
renovate[bot] 5aaf09b3e4 renovatebot(deps): update dependency org.apache.tomcat.embed:tom… (#371) 2019-10-24 19:04:14 +04:00
dependabot-preview[bot] fd176bc1a7 Bump spring-boot-starter from 2.1.9.RELEASE to 2.2.0.RELEASE (#376)
Bumps [spring-boot-starter](https://github.com/spring-projects/spring-boot) from 2.1.9.RELEASE to 2.2.0.RELEASE.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.9.RELEASE...v2.2.0.RELEASE)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-17 17:51:43 +04:00
renovate[bot] 9f09c15673 renovatebot(deps): update dependency org.bouncycastle:bcpkix-jdk15on to v1.64 (#373) 2019-10-12 10:20:46 +04:00
Misagh Moayyed e4c1df0280
[maven-release-plugin] prepare for next development iteration 2019-10-08 17:22:31 +04:00
Misagh Moayyed a00064d1d8
[maven-release-plugin] prepare release cas-client-3.6.1 2019-10-08 17:22:16 +04:00
Misagh Moayyed 21d5f37322
Updated: code cleanup and styling; fixes test cases 2019-10-08 17:20:43 +04:00
Misagh Moayyed 872fc49fb7
ensure API compatibility 2019-10-08 17:19:45 +04:00
Jérôme LELEU 18c79fcf00 [maven-release-plugin] prepare for next development iteration 2019-10-07 11:02:29 +02:00
Jérôme LELEU 9394a6e190 [maven-release-plugin] prepare release cas-client-3.6.0 2019-10-07 11:02:21 +02:00
LELEU Jérôme 3e99e678ca
fix notice and license issues (#368) 2019-10-07 10:25:43 +02:00
mergify[bot] 2beda557e1
Merge pull request #367 from apereo/renovate/spring-boot
renovatebot(deps): update dependency org.springframework.boot:spring-boot-starter to v2.1.9.release
2019-10-02 17:42:25 +00:00
Renovate Bot a233009f68
renovatebot(deps): update dependency org.springframework.boot:spring-boot-starter to v2.1.9.release 2019-10-02 17:29:14 +00:00
mergify[bot] e7d2c87668
Merge pull request #366 from apereo/dependabot/maven/jetty.version-9.4.21.v20190926
Bump jetty.version from 9.4.20.v20190813 to 9.4.21.v20190926
2019-10-02 06:54:38 +00:00
dependabot-preview[bot] 8a972d38e1
Bump jetty.version from 9.4.20.v20190813 to 9.4.21.v20190926
Bumps `jetty.version` from 9.4.20.v20190813 to 9.4.21.v20190926.

Updates `jetty-security` from 9.4.20.v20190813 to 9.4.21.v20190926
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.20.v20190813...jetty-9.4.21.v20190926)

Updates `jetty-webapp` from 9.4.20.v20190813 to 9.4.21.v20190926
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.20.v20190813...jetty-9.4.21.v20190926)

Updates `jetty-plus` from 9.4.20.v20190813 to 9.4.21.v20190926
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.20.v20190813...jetty-9.4.21.v20190926)

Updates `jetty-annotations` from 9.4.20.v20190813 to 9.4.21.v20190926
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.20.v20190813...jetty-9.4.21.v20190926)

Updates `apache-jsp` from 9.4.20.v20190813 to 9.4.21.v20190926
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.20.v20190813...jetty-9.4.21.v20190926)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-02 06:52:04 +00:00
mergify[bot] 2ac1e1b7a6
Merge pull request #365 from apereo/renovate/spring-core
renovatebot(deps): update spring core to v5.2.0.release
2019-09-30 11:26:29 +00:00
Renovate Bot bca6d9b830
renovatebot(deps): update spring core to v5.2.0.release 2019-09-30 10:39:50 +00:00
mergify[bot] 9e89fe960a
Merge pull request #364 from apereo/renovate/spring-core
renovatebot(deps): update spring core to v5.1.10.release
2019-09-28 14:07:13 +00:00
Renovate Bot 15567ef2a6
renovatebot(deps): update spring core to v5.1.10.release 2019-09-28 12:38:49 +00:00
mergify[bot] 5b47efa407
Merge pull request #363 from apereo/renovate/jackson.version
renovatebot(deps): update dependency com.fasterxml.jackson.core:jackson-databind to v2.10.0
2019-09-26 04:47:17 +00:00
Renovate Bot 3ff317846f
renovatebot(deps): update dependency com.fasterxml.jackson.core:jackson-databind to v2.10.0 2019-09-26 04:44:45 +00:00
mergify[bot] e39d35fbd7
Merge pull request #362 from apereo/renovate/jackson.version
renovatebot(deps): update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.10
2019-09-21 21:25:54 +00:00
Renovate Bot 0fbe33a7e5
renovatebot(deps): update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.10 2019-09-21 18:44:15 +00:00
mergify[bot] b531896715
Merge pull request #361 from apereo/renovate/joda-time-joda-time-2.x
renovatebot(deps): update dependency joda-time:joda-time to v2.10.4
2019-09-20 12:41:57 +00:00
Renovate Bot e3b109264c
renovatebot(deps): update dependency joda-time:joda-time to v2.10.4 2019-09-20 12:39:21 +00:00
mergify[bot] 81cdceca8f
Merge pull request #359 from apereo/renovate/tomcat.version
renovatebot(deps): update tomcat.version to v9.0.26
2019-09-20 01:44:36 +00:00
Renovate Bot 5b5ca68d05
renovatebot(deps): update tomcat.version to v9.0.26 2019-09-20 01:41:57 +00:00
mergify[bot] 2728f0597d
Merge pull request #358 from apereo/renovate/org.apache.tomcat-tomcat-catalina-8.x
renovatebot(deps): update dependency org.apache.tomcat:tomcat-catalina to v8.5.46
2019-09-20 01:41:32 +00:00
Renovate Bot 5bd4465298
renovatebot(deps): update dependency org.apache.tomcat:tomcat-catalina to v8.5.46 2019-09-20 00:15:58 +00:00
mergify[bot] 7d9ee60b73
Merge pull request #357 from apereo/renovate/org.apache.tomcat.embed-tomcat-embed-core-8.x
renovatebot(deps): update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.46
2019-09-20 00:15:33 +00:00
Renovate Bot 5f82143b00
renovatebot(deps): update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.46 2019-09-19 21:34:10 +00:00
mergify[bot] 1fad31d8b0
Merge pull request #356 from apereo/dependabot/maven/org.bouncycastle-bcpkix-jdk15on-1.63
Bump bcpkix-jdk15on from 1.62 to 1.63
2019-09-11 05:41:38 +00:00
dependabot-preview[bot] 3d391b62b8
Bump bcpkix-jdk15on from 1.62 to 1.63
Bumps [bcpkix-jdk15on](https://github.com/bcgit/bc-java) from 1.62 to 1.63.
- [Release notes](https://github.com/bcgit/bc-java/releases)
- [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-11 05:39:18 +00:00
mergify[bot] 913c412fba
Merge pull request #354 from apereo/renovate/spring-boot
renovatebot(deps): update dependency org.springframework.boot:spring-boot-starter to v2.1.8.release
2019-09-05 22:59:47 +00:00
Renovate Bot b355b526d6
renovatebot(deps): update dependency org.springframework.boot:spring-boot-starter to v2.1.8.release 2019-09-05 22:57:35 +00:00
mergify[bot] 858b0ca77d
Merge pull request #351 from apereo/renovate/javax.servlet-javax.servlet-api-4.x
renovatebot(deps): update dependency javax.servlet:javax.servlet-api to v4
2019-08-22 05:54:16 +00:00
Renovate Bot c00ee02f44
renovatebot(deps): update dependency javax.servlet:javax.servlet-api to v4 2019-08-22 05:52:05 +00:00
mergify[bot] 40848d251e
Merge pull request #350 from apereo/renovate/com.atlassian.user-atlassian-user-5.x
renovatebot(deps): update dependency com.atlassian.user:atlassian-user to v5
2019-08-22 05:51:40 +00:00
Renovate Bot a7b7660772
renovatebot(deps): update dependency com.atlassian.user:atlassian-user to v5 2019-08-22 05:49:27 +00:00
mergify[bot] 440f2edaa6
Merge pull request #349 from apereo/renovate/com.atlassian.seraph-atlassian-seraph-4.x
renovatebot(deps): update dependency com.atlassian.seraph:atlassian-seraph to v4
2019-08-22 05:49:00 +00:00
Renovate Bot 8667f0b946
renovatebot(deps): update dependency com.atlassian.seraph:atlassian-seraph to v4 2019-08-22 05:46:54 +00:00
renovate[bot] 60a8cb3825 Update dependency org.apache.tomcat:tomcat-catalina to v8.5.45 (#347) 2019-08-22 10:16:11 +04:30
Misagh Moayyed 11a53a6fc2
Update renovate.json 2019-08-22 10:15:46 +04:30
renovate[bot] 58a54c7372 Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.45 (#346) 2019-08-21 20:31:25 +04:30
renovate[bot] 53f34e175e Update tomcat.version to v9.0.24 (#344) 2019-08-18 08:04:29 +04:30
mergify[bot] 9279ab8d54
Merge pull request #343 from apereo/dependabot/maven/jetty.version-9.4.20.v20190813
Bump jetty.version from 9.4.18.v20190429 to 9.4.20.v20190813
2019-08-15 05:59:08 +00:00
dependabot-preview[bot] 6352b7991a
Bump jetty.version from 9.4.18.v20190429 to 9.4.20.v20190813
Bumps `jetty.version` from 9.4.18.v20190429 to 9.4.20.v20190813.

Updates `jetty-security` from 9.4.18.v20190429 to 9.4.20.v20190813
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.18.v20190429...jetty-9.4.20.v20190813)

Updates `jetty-webapp` from 9.4.18.v20190429 to 9.4.20.v20190813
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.18.v20190429...jetty-9.4.20.v20190813)

Updates `jetty-plus` from 9.4.18.v20190429 to 9.4.20.v20190813
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.18.v20190429...jetty-9.4.20.v20190813)

Updates `jetty-annotations` from 9.4.18.v20190429 to 9.4.20.v20190813
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.18.v20190429...jetty-9.4.20.v20190813)

Updates `apache-jsp` from 9.4.18.v20190429 to 9.4.20.v20190813
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.18.v20190429...jetty-9.4.20.v20190813)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-15 05:52:39 +00:00
mergify[bot] db9f0a3301
Merge pull request #342 from apereo/dependabot/maven/slf4j.version-1.7.28
Bump slf4j.version from 1.7.27 to 1.7.28
2019-08-12 07:59:51 +00:00
dependabot-preview[bot] 4c4202de24
Bump slf4j.version from 1.7.27 to 1.7.28
Bumps `slf4j.version` from 1.7.27 to 1.7.28.

Updates `slf4j-api` from 1.7.27 to 1.7.28
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.27...v_1.7.28)

Updates `jcl-over-slf4j` from 1.7.27 to 1.7.28
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.27...v_1.7.28)

Updates `slf4j-simple` from 1.7.27 to 1.7.28
- [Release notes](https://github.com/qos-ch/slf4j/releases)
- [Commits](https://github.com/qos-ch/slf4j/compare/v_1.7.27...v_1.7.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 06:52:55 +00:00
Misagh Moayyed 6f7ef142bc
add tomcat 9.0.x 2019-08-09 15:04:33 +04:30
Misagh Moayyed 7e34235578
fix license headers 2019-08-09 14:55:39 +04:30
mergify[bot] 07a700f531
Merge pull request #335 from apereo/dependabot/maven/spring.version-5.1.9.RELEASE
[Security] Bump spring.version from 3.1.3.RELEASE to 5.1.9.RELEASE
2019-08-08 19:57:20 +00:00
Misagh Moayyed 31756bd6fc
Merge branch 'master' into dependabot/maven/spring.version-5.1.9.RELEASE 2019-08-09 00:25:10 +04:30
Misagh Moayyed 95583500c0
Update dependency org.springframework.boot:spring-boot-starter t… (#338)
Update dependency org.springframework.boot:spring-boot-starter to v2.1.7.RELEASE
2019-08-08 22:22:26 +04:30
mergify[bot] c096b4c82b
Merge pull request #339 from apereo/dependabot/maven/org.springframework.boot-spring-boot-starter-2.1.7.RELEASE
Bump spring-boot-starter from 2.1.4.RELEASE to 2.1.7.RELEASE
2019-08-08 17:45:23 +00:00
dependabot-preview[bot] 63d638b452
Bump spring-boot-starter from 2.1.4.RELEASE to 2.1.7.RELEASE
Bumps [spring-boot-starter](https://github.com/spring-projects/spring-boot) from 2.1.4.RELEASE to 2.1.7.RELEASE.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.4.RELEASE...v2.1.7.RELEASE)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-08 17:43:17 +00:00
Renovate Bot ee21f2874a
Update dependency org.springframework.boot:spring-boot-starter to v2.1.7.RELEASE 2019-08-08 17:42:26 +00:00
Misagh Moayyed 24c3f92030
updated 2019-08-08 22:11:54 +04:30
Misagh Moayyed 3b312e1cff
Merge pull request #340 from apereo/boot-module-javadoc-polish
Correct `@since`
2019-08-08 20:25:56 +04:30
Dmitriy Kopylenko 7f0b42df31 Correct @since 2019-08-08 08:42:09 -04:00
Misagh Moayyed 4d84e02c5f
updated 2019-08-07 21:41:29 +04:30
Misagh Moayyed ca5e5f1f06
add springboot autocfg support 2019-08-07 21:39:44 +04:30
Misagh Moayyed 387e7249e0 Merge branch 'master' of github.com:Jasig/java-cas-client 2019-08-07 19:10:37 +04:30
Misagh Moayyed 8a7e04d7cf
updated 2019-08-07 19:09:42 +04:30
Misagh Moayyed 11d3c21889
Update slf4j.version to v1.7.27 (#337)
Update slf4j.version to v1.7.27
2019-08-06 17:45:51 +04:30
Renovate Bot a51fd8f8f8
Update slf4j.version to v1.7.27 2019-08-06 09:38:46 +00:00
Misagh Moayyed 1a6da20b3e
Merge pull request #336 from apereo/renovate/jackson.version
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9.3
2019-08-06 06:24:53 +04:30
Renovate Bot 2a3adb4ec4
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9.3 2019-08-06 01:52:43 +00:00
Misagh Moayyed a5a7d30791
Merge branch 'master' into dependabot/maven/spring.version-5.1.9.RELEASE 2019-08-05 14:34:19 +04:30
Misagh Moayyed bab29c84f4
fix compile errors 2019-08-05 14:14:59 +04:30
Misagh Moayyed 8eaec09704
disable attlassian from build - unmaintained 2019-08-05 13:54:06 +04:30
dependabot-preview[bot] da07e4815b
[Security] Bump spring.version from 3.1.3.RELEASE to 5.1.9.RELEASE
Bumps `spring.version` from 3.1.3.RELEASE to 5.1.9.RELEASE.

Updates `spring-core` from 3.1.3.RELEASE to 5.1.9.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v3.1.3.RELEASE...v5.1.9.RELEASE)

Updates `spring-context` from 3.1.3.RELEASE to 5.1.9.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v3.1.3.RELEASE...v5.1.9.RELEASE)

Updates `spring-test` from 3.1.3.RELEASE to 5.1.9.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v3.1.3.RELEASE...v5.1.9.RELEASE)

Updates `spring-beans` from 3.1.3.RELEASE to 5.1.9.RELEASE
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v3.1.3.RELEASE...v5.1.9.RELEASE)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 06:38:36 +00:00
Misagh Moayyed de1f05dc8b
Merge pull request #334 from apereo/renovate/maven-com.fasterxml.jackson.core-jackson-databind-vulnerability
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9.2 [SECURITY]
2019-08-02 05:26:25 +04:30
Renovate Bot 1300774928
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9.2 [SECURITY] 2019-08-01 20:56:04 +00:00
Misagh Moayyed f946c2845b
Update dependency org.apache.tomcat:tomcat-catalina to v7.0.96 (#333)
Update dependency org.apache.tomcat:tomcat-catalina to v7.0.96
2019-07-29 22:37:59 +04:30
Renovate Bot 3cd4e12fa9
Update dependency org.apache.tomcat:tomcat-catalina to v7.0.96 2019-07-29 18:00:07 +00:00
Misagh Moayyed 3e5eeaabe1
Merge pull request #331 from larsgrefer/gh-329
Remove the unused 'casServerUrlPrefix' parameter
2019-07-26 08:54:28 +04:30
Lars Grefer fdc948b8ec Remove the unused 'casServerUrlPrefix' parameter
fixes #329
2019-07-25 22:54:58 +02:00
Misagh Moayyed 1966a26d6f
Update dependency commons-codec:commons-codec to v1.13 (#330)
Update dependency commons-codec:commons-codec to v1.13
2019-07-23 17:46:00 +04:30
Misagh Moayyed c2886ea70c
Update dependency org.apache.tomcat.embed:tomcat-embed-core to v… (#326)
Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.43
2019-07-23 17:44:45 +04:30
Renovate Bot 850a6c0373
Update dependency commons-codec:commons-codec to v1.13 2019-07-23 12:42:59 +00:00
Misagh Moayyed 764d2220d6
Merge pull request #327 from apereo/renovate/org.apache.tomcat-tomcat-catalina-8.x
Update dependency org.apache.tomcat:tomcat-catalina to v8.5.43
2019-07-18 09:42:37 +04:30
Misagh Moayyed 77abda055b
Create FUNDING.yml 2019-07-13 23:10:19 +04:30
Renovate Bot 505160b15e
Update dependency org.apache.tomcat:tomcat-catalina to v8.5.43 2019-07-09 15:53:24 +00:00
Renovate Bot fdab7aea5b
Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.43 2019-07-09 15:53:17 +00:00
Misagh Moayyed 9e95c8a10c
Bump maven-javadoc-plugin from 3.1.0 to 3.1.1 (#325)
Bump maven-javadoc-plugin from 3.1.0 to 3.1.1
2019-07-08 11:56:02 +04:30
Misagh Moayyed f7234f9aea
Update dependency org.apache.maven.plugins:maven-javadoc-plugin… (#324)
Update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.1.1
2019-07-08 11:55:56 +04:30
Misagh Moayyed 0e4c82cc94
Merge pull request #323 from apereo/dependabot/maven/joda-time-joda-time-2.10.3
Bump joda-time from 2.10.2 to 2.10.3
2019-07-08 11:55:48 +04:30
dependabot-preview[bot] 8596db4de3
Bump maven-javadoc-plugin from 3.1.0 to 3.1.1
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.1.0...maven-javadoc-plugin-3.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-08 05:57:27 +00:00
Renovate Bot ccf8b89dee
Update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.1.1 2019-07-07 09:49:25 +00:00
Misagh Moayyed 3f45530e0e
Merge pull request #322 from apereo/renovate/joda-time-joda-time-2.x
Update dependency joda-time:joda-time to v2.10.3
2019-07-05 10:21:42 +04:30
Misagh Moayyed 46341d3e42
Merge pull request #321 from apereo/renovate/com.fasterxml.jackson.core-jackson-databind-2.x
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9.1
2019-07-05 10:21:14 +04:30
dependabot-preview[bot] 9fabd9fbf1
Bump joda-time from 2.10.2 to 2.10.3
Bumps [joda-time](https://github.com/JodaOrg/joda-time) from 2.10.2 to 2.10.3.
- [Release notes](https://github.com/JodaOrg/joda-time/releases)
- [Changelog](https://github.com/JodaOrg/joda-time/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/JodaOrg/joda-time/compare/v2.10.2...v2.10.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-05 05:49:20 +00:00
Renovate Bot be29e420c0
Update dependency joda-time:joda-time to v2.10.3 2019-07-04 15:44:58 +00:00
Renovate Bot 2734d45f3e
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9.1 2019-07-03 01:36:11 +00:00
Misagh Moayyed 601959f85c
Update .travis.yml 2019-06-26 01:54:56 -07:00
Misagh Moayyed bf4e1e60b6 Update .travis.yml 2019-06-26 01:42:56 -07:00
Misagh Moayyed 0c041d5376 Update .travis.yml 2019-06-26 01:40:02 -07:00
Misagh Moayyed a7101b6cc8 Provide for secure XML processing. (#318)
Provide for secure XML processing.
2019-06-26 13:09:36 +04:30
Marvin S. Addison 7ce4cb8aa5 Provide for secure XML processing.
Follow recommendations at https://wiki.shibboleth.net/confluence/x/XoEYAw
which are consistent with recommendations on #191 to prevent XXE vectors.

Resolves #191
See https://github.com/apereo/java-cas-client/issues/191
2019-06-25 08:01:46 -04:00
Misagh Moayyed a95a98dd9b Merge pull request #313 from apereo/renovate/org.apache.tomcat.embed-tomcat-embed-core-8.x
Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.42
2019-06-14 08:32:07 +04:30
Renovate Bot a3dbe594c3 Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.42 2019-06-07 21:33:49 +00:00
Misagh Moayyed 49f9a4e309 Merge pull request #311 from apereo/renovate/org.bouncycastle-bcpkix-jdk15on-1.x
Update dependency org.bouncycastle:bcpkix-jdk15on to v1.62
2019-06-07 07:41:38 -07:00
Misagh Moayyed fd72cb6bfc Bump bcpkix-jdk15on from 1.61 to 1.62 (#312)
Bump bcpkix-jdk15on from 1.61 to 1.62
2019-06-07 07:41:23 -07:00
dependabot-preview[bot] 78b2997c5d Bump bcpkix-jdk15on from 1.61 to 1.62
Bumps [bcpkix-jdk15on](https://github.com/bcgit/bc-java) from 1.61 to 1.62.
- [Release notes](https://github.com/bcgit/bc-java/releases)
- [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html)
- [Commits](https://github.com/bcgit/bc-java/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-07 10:33:56 +00:00
Renovate Bot cfebf0acc7 Update dependency org.bouncycastle:bcpkix-jdk15on to v1.62 2019-06-07 04:36:32 +00:00
Misagh Moayyed 874958641a Merge pull request #307 from apereo/dependabot/maven/jetty.version-9.4.18.v20190429
Bump jetty.version from 9.2.14.v20151106 to 9.4.18.v20190429
2019-06-04 06:06:54 -07:00
Misagh Moayyed 691bf12697 Merge pull request #310 from apereo/dependabot/maven/net.sf.ehcache-ehcache-core-2.6.11
Bump ehcache-core from 2.2.0 to 2.6.11
2019-06-04 06:06:17 -07:00
Misagh Moayyed 4332186ea7 Merge pull request #308 from apereo/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.1.0
Bump maven-source-plugin from 2.2.1 to 3.1.0
2019-06-04 06:04:38 -07:00
Hal Deadman 52274f828f Merge pull request #251 from inghamn/patch-1
Prioritize X-Forwarded-Host when choosing the service parameter
2019-05-29 19:15:12 -04:00
dependabot-preview[bot] 5c3d185e8d Bump ehcache-core from 2.2.0 to 2.6.11
Bumps ehcache-core from 2.2.0 to 2.6.11.
2019-05-28 10:50:55 +00:00
dependabot-preview[bot] 35d611b8e8 Bump maven-source-plugin from 2.2.1 to 3.1.0
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 2.2.1 to 3.1.0.
- [Release notes](https://github.com/apache/maven-source-plugin/releases)
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-2.2.1...maven-source-plugin-3.1.0)
2019-05-28 10:50:13 +00:00
dependabot-preview[bot] d940cfd417 Bump jetty.version from 9.2.14.v20151106 to 9.4.18.v20190429
Bumps `jetty.version` from 9.2.14.v20151106 to 9.4.18.v20190429.

Updates `jetty-security` from 9.2.14.v20151106 to 9.4.18.v20190429
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.2.14.v20151106...jetty-9.4.18.v20190429)

Updates `jetty-webapp` from 9.2.14.v20151106 to 9.4.18.v20190429
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.2.14.v20151106...jetty-9.4.18.v20190429)

Updates `jetty-plus` from 9.2.14.v20151106 to 9.4.18.v20190429
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.2.14.v20151106...jetty-9.4.18.v20190429)

Updates `jetty-annotations` from 9.2.14.v20151106 to 9.4.18.v20190429
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.2.14.v20151106...jetty-9.4.18.v20190429)

Updates `apache-jsp` from 9.2.14.v20151106 to 9.4.18.v20190429
- [Release notes](https://github.com/eclipse/jetty.project/releases)
- [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.2.14.v20151106...jetty-9.4.18.v20190429)
2019-05-27 13:32:43 +00:00
Misagh Moayyed 1d78f74b2a Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.41 (#299)
Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.41
2019-05-23 04:39:18 -07:00
Misagh Moayyed 12da0340a1 Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9 [SECURITY] (#302)
Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9 [SECURITY]
2019-05-23 04:38:44 -07:00
Renovate Bot e283a9a7a5 Update dependency com.fasterxml.jackson.core:jackson-databind to v2.9.9 [SECURITY] 2019-05-23 10:35:34 +00:00
Renovate Bot 1c29fa7ebd Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.41 2019-05-14 20:54:21 +00:00
Misagh Moayyed 7bea9bb258 Update dependency joda-time:joda-time to v2.10.2 (#297)
Update dependency joda-time:joda-time to v2.10.2
2019-05-09 09:03:56 -07:00
Renovate Bot 4ada1b1327 Update dependency joda-time:joda-time to v2.10.2 2019-05-09 14:39:32 +00:00
Misagh Moayyed 32d14893ae Merge pull request #292 from apereo/renovate/org.jasig.parent-jasig-parent-41.x
Update dependency org.jasig.parent:jasig-parent to v41
2019-05-02 20:00:06 -07:00
Misagh Moayyed 0f395b3a2c Merge pull request #294 from apereo/renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x
Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.8.1
2019-05-02 19:59:45 -07:00
Misagh Moayyed 0e750de5f5 Merge pull request #295 from apereo/renovate/org.apache.maven.plugins-maven-surefire-plugin-2.x
Update dependency org.apache.maven.plugins:maven-surefire-plugin to v2.22.2
2019-05-02 19:59:13 -07:00
Renovate Bot 26479f3d99 Update dependency org.apache.maven.plugins:maven-surefire-plugin to v2.22.2 2019-05-02 20:54:26 +00:00
Renovate Bot 11e9b543e5 Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.8.1 2019-05-02 18:54:12 +00:00
Misagh Moayyed 5c2c6b00aa Update dependency org.apache.maven.plugins:maven-assembly-plugin to v3 (#288)
Update dependency org.apache.maven.plugins:maven-assembly-plugin to v3
2019-05-02 06:44:53 -07:00
Misagh Moayyed f0bd481a13 Update dependency org.apache.maven.plugins:maven-jar-plugin to v3 (#289)
Update dependency org.apache.maven.plugins:maven-jar-plugin to v3
2019-05-02 06:44:42 -07:00
Misagh Moayyed 8fb8e9d0e4 Merge pull request #277 from apereo/renovate/org.apache.tomcat.embed-tomcat-embed-core-8.x
Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.40
2019-05-02 06:44:30 -07:00
Misagh Moayyed 3213920bff Merge pull request #278 from apereo/renovate/org.apache.tomcat-catalina-6.x
Update dependency org.apache.tomcat:catalina to v6.0.53
2019-05-02 06:44:06 -07:00
Misagh Moayyed 01812e755d Update dependency org.slf4j:slf4j-simple to v1.7.26 (#283)
Update dependency org.slf4j:slf4j-simple to v1.7.26
2019-04-30 14:27:25 -07:00
Misagh Moayyed d35172dff9 Update dependency org.slf4j:jcl-over-slf4j to v1.7.26 (#281)
Update dependency org.slf4j:jcl-over-slf4j to v1.7.26
2019-04-30 14:27:11 -07:00
Misagh Moayyed 1999bd4670 Update dependency org.slf4j:slf4j-api to v1.7.26 (#282)
Update dependency org.slf4j:slf4j-api to v1.7.26
2019-04-30 14:26:58 -07:00
Renovate Bot 4f411c4342 Update dependency org.jasig.parent:jasig-parent to v41 2019-04-30 20:56:06 +00:00
Renovate Bot c6a46da7fa Update dependency org.apache.maven.plugins:maven-jar-plugin to v3 2019-04-30 19:40:11 +00:00
Renovate Bot c8c0d844b4 Update dependency org.apache.maven.plugins:maven-assembly-plugin to v3 2019-04-30 18:34:17 +00:00
Renovate Bot cf7e09b1c4 Update dependency org.slf4j:slf4j-simple to v1.7.26 2019-04-30 16:48:14 +00:00
Renovate Bot 68a0cc0433 Update dependency org.slf4j:slf4j-api to v1.7.26 2019-04-30 15:36:57 +00:00
Renovate Bot c8eb5b4e5a Update dependency org.slf4j:jcl-over-slf4j to v1.7.26 2019-04-30 15:36:50 +00:00
Renovate Bot 0f69d262e8 Update dependency org.apache.tomcat:catalina to v6.0.53 2019-04-30 13:15:29 +00:00
Renovate Bot 748a7172f5 Update dependency org.apache.tomcat.embed:tomcat-embed-core to v8.5.40 2019-04-30 13:15:22 +00:00
Misagh Moayyed d1c3660cda Update dependency javax.servlet:javax.servlet-api to v3.1.0 (#266)
Update dependency javax.servlet:javax.servlet-api to v3.1.0
2019-04-30 06:14:59 -07:00
Misagh Moayyed 78470351f6 Update dependency joda-time:joda-time to v2.10.1 (#267)
Update dependency joda-time:joda-time to v2.10.1
2019-04-30 06:14:50 -07:00
Misagh Moayyed 9e7ad3f046 Update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.1.0 (#275)
Update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.1.0
2019-04-30 06:14:37 -07:00
Misagh Moayyed 3688949646 Update dependency org.apache.maven.plugins:maven-surefire-plugin to v2.22.1 (#276)
Update dependency org.apache.maven.plugins:maven-surefire-plugin to v2.22.1
2019-04-30 06:14:29 -07:00
Renovate Bot a091c2795b Update dependency org.apache.maven.plugins:maven-surefire-plugin to v2.22.1 2019-04-30 12:49:37 +00:00
Renovate Bot 411a105fb1 Update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.1.0 2019-04-30 12:49:30 +00:00
Renovate Bot bd7ebc11c7 Update dependency joda-time:joda-time to v2.10.1 2019-04-30 11:26:23 +00:00
Renovate Bot 61c842124e Update dependency javax.servlet:javax.servlet-api to v3.1.0 2019-04-30 11:26:17 +00:00
Misagh Moayyed bb95fd733f Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.8.0 (#273)
Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.8.0
2019-04-30 04:25:46 -07:00
Misagh Moayyed 2b61ca1df3 Update dependency org.apache.maven.plugins:maven-enforcer-plugin to v1.4.1 (#274)
Update dependency org.apache.maven.plugins:maven-enforcer-plugin to v1.4.1
2019-04-30 04:25:38 -07:00
Misagh Moayyed b61487766c Update dependency junit:junit to v4.12 (#268)
Update dependency junit:junit to v4.12
2019-04-30 04:25:28 -07:00
Renovate Bot 1f6881829b Update dependency org.apache.maven.plugins:maven-enforcer-plugin to v1.4.1 2019-04-30 11:12:13 +00:00
Renovate Bot a8ec3de36e Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.8.0 2019-04-30 11:12:07 +00:00
Renovate Bot a4cde4359e Update dependency junit:junit to v4.12 2019-04-30 11:12:01 +00:00
Misagh Moayyed 44adee82ec Update dependency net.spy:spymemcached to v2.12.3 (#271)
Update dependency net.spy:spymemcached to v2.12.3
2019-04-30 04:11:21 -07:00
Misagh Moayyed 97632483aa Update dependency org.apache.maven.plugins:maven-assembly-plugin to v2.6 (#272)
Update dependency org.apache.maven.plugins:maven-assembly-plugin to v2.6
2019-04-30 04:11:12 -07:00
Misagh Moayyed 2362481941 Update dependency log4j:log4j to v1.2.17 (#269)
Update dependency log4j:log4j to v1.2.17
2019-04-30 04:10:59 -07:00
Renovate Bot 733ce5ba5d Update dependency org.apache.maven.plugins:maven-assembly-plugin to v2.6 2019-04-30 10:51:11 +00:00
Renovate Bot 66742817cc Update dependency net.spy:spymemcached to v2.12.3 2019-04-30 10:51:01 +00:00
Renovate Bot 0e333ec040 Update dependency log4j:log4j to v1.2.17 2019-04-30 09:39:34 +00:00
Misagh Moayyed a09641b184 Update dependency commons-codec:commons-codec to v1.12 (#265)
Update dependency commons-codec:commons-codec to v1.12
2019-04-30 01:02:18 -07:00
Renovate Bot 28ffa12548 Update dependency commons-codec:commons-codec to v1.12 2019-04-30 07:46:54 +00:00
Misagh Moayyed f6f20da863 Merge pull request #262 from kmnasir/jackson-patch
Updating jackson version to 2.9.8
2019-04-30 00:46:38 -07:00
Misagh Moayyed 22e77d2d12 Configure Renovate (#263)
Configure Renovate
2019-04-30 00:46:23 -07:00
Renovate Bot 93dac9b3fe Add renovate.json 2019-04-30 07:43:52 +00:00
Misagh Moayyed db0b8f8a42 Merge pull request #261 from kberzinch/master
Add login attempt events to Atlassian integration
2019-04-11 01:16:55 -07:00
Kristaps Berzinch 1c5dee3edf Add login attempt events 2019-04-11 00:51:45 -04:00
LELEU Jérôme abacb75df2 Handle encrypted PGTs (#260)
* Handle encrypted PGTs

* add tests

* stick to Java 6 and use commons-codec for Base64

* Remove the encrypted PGT after a PGT has been retrieved

* use Bouncycastle to load PEM files

* update to latest BC dependency
2019-04-03 13:53:09 +02:00
LELEU Jérôme 96f51465a8 Merge pull request #259 from leleuj/method
Support the method parameter
2019-03-14 19:11:02 +01:00
Jérôme LELEU 58de00e34b Support the method parameter 2019-03-13 09:15:07 +01:00
Hal Deadman 8cc5ad182c Merge pull request #255 from apereo/hdeadman-patch-1
Update README.md
2019-02-01 17:24:44 -05:00
Hal Deadman e3f532acde Update README.md
Add required serverName init parameter to example for Cas10TicketValidationFilter
2019-02-01 17:22:11 -05:00
Misagh Moayyed 86b93cbb26 clean up 2019-01-31 01:43:33 -07:00
Misagh Moayyed cc756cb72d update readme; add full-regex 2019-01-31 01:39:55 -07:00
Misagh Moayyed e2798c09cb Merge pull request #253 from apereo/inlined-attributes
Extract inlined CAS attributes in protocol 3 Ticket Validator
2019-01-29 23:12:07 +03:30
tsschmidt f06895bc18 Refactored and added unit test. 2019-01-24 16:31:54 -08:00
tsschmidt 18d981efaa Refactor 2019-01-23 10:24:01 -08:00
tsschmidt 080405b4c0 Extract inlined CAS attributes in protocol 3 Ticket Validator 2019-01-23 08:26:35 -08:00
Misagh Moayyed 45d4180a7f Merge pull request #252 from alterdego/master
Fixed typos in README.md
2019-01-14 06:53:40 -06:00
Document Doctor 77c013b03b Fixed typos in README.md 2019-01-12 01:18:14 -05:00
Document Doctor 7513f94877 Fixed typos in README.md 2019-01-11 21:42:00 -05:00
Cliff Ingham 2b1b7a142a Prioritize X-Forwarded-Host when choosing the service parameter
Use X-Forwarded-Host whenever it's available.
2018-12-14 16:28:55 -05:00
Dmitriy Kopylenko ba50664582 [maven-release-plugin] prepare for next development iteration 2018-11-01 10:32:59 -04:00
Dmitriy Kopylenko bafe64e7cd [maven-release-plugin] prepare release cas-client-3.5.1 2018-11-01 10:32:53 -04:00
Misagh Moayyed b2e1643893 Update pom.xml 2018-10-20 23:08:22 +03:30
Misagh Moayyed e155261a6b Merge pull request #248 from SmithJosh/respect-path-in-servername-config
Include serverName path when constructing service url
2018-10-10 09:52:17 +03:30
Joshua Smith c39735729d Include serverName path when constructing service url
Commit be2a641 introduced a bug which overwrites the serverName path component
when constructing service urls. This makes it impossible to deploy a CAS-
protected application behind a reverse proxy with a path prefix.

Now, the path from the incoming request is appended to the serverName path
instead of overwriting it.
2018-10-02 13:29:30 -07:00
Misagh Moayyed 2a570b26f1 Merge pull request #239 from mattdrees/issue-210-preserve-entity-stream-for-non-logout-requests
Add option to prevent entity stream consumption
2018-07-25 23:47:05 +04:30
Matt Drees 1d4312b64f Rename logoutPath to logoutCallbackPath 2018-07-25 13:07:29 -06:00
Misagh Moayyed af78b8703f Merge branch 'master' into issue-210-preserve-entity-stream-for-non-logout-requests 2018-07-25 10:25:51 +04:30
Misagh Moayyed 0e943179f1 Merge pull request #241 from mattdrees/support-prefix-config-for-authentication-filter
Support casServerUrlPrefix config option for AuthenticationFilter
2018-07-25 10:24:35 +04:30
Matt Drees 72e9aa9378 Tweak logoutPath docs 2018-07-24 16:08:48 -06:00
Matt Drees c5d1b1ef84 Stop using "matches" terminology 2018-07-24 16:07:44 -06:00
Matt Drees 40dcc8b34a Move utility method to CommonUtils 2018-07-24 15:19:01 -06:00
Matt Drees ba5982e1eb Add option to prevent entity stream consumption
If someone's app cannot handle the SingleSignOutFilter's consumption of entity streams
(via a `request.getParameter()` call) on all requests,
they can use this option in conjunction with setting up a service logout URL at the CAS server.
The filter will now only consume the stream on requests to this path.

Fixes https://github.com/apereo/java-cas-client/issues/210.
2018-07-24 15:19:00 -06:00
Matt Drees b6f6b5de76 Support casServerUrlPrefix config option
`casServerUrlPrefix` is used for validation and single logout,
but before this commit it couldn't be used by the auth filter.
As a result, web.xml needed to (for the typical usecase)
contain at least two references to the cas server.

Now, only one context init-param reference is necessary,
as long as the login page is hosted at {prefix}/login
(which seems to be mandated by cas protocol spec).
2018-07-24 15:18:24 -06:00
Misagh Moayyed 93561a297f Merge pull request #178 from jalios/master
Fix #177 Every other request incorrectly gatewayed
2018-07-25 00:24:13 +04:30
Misagh Moayyed c979e64006 Merge pull request #240 from mattdrees/fix-race-condition-in-http-server-tests
Fix race condition in PublicTestHttpServer tests
2018-07-25 00:22:57 +04:30
Matt Drees 306ec75569 Fix race condition in PublicTestHttpServer tests
The previous code assumed the server would start listening on the socket before tests ran, but didn't enforce this.
2018-07-24 11:29:25 -06:00
Misagh Moayyed a061764ca1 fix tests 2018-07-17 11:50:10 +04:30
Misagh Moayyed 7fbac753ee fix tests 2018-07-17 11:42:41 +04:30
Misagh Moayyed 15100f3c39 fix tests; adjust log levels for tests 2018-07-17 11:33:03 +04:30
Misagh Moayyed 87ac085dfd Rename stale.yml to .github/stale.yml 2018-07-17 11:08:37 +04:30
Misagh Moayyed a34a397a68 Create stale.yml 2018-06-08 10:48:49 -07:00
kmnasir 94b23a7f2d Updating jackson version to 2.9.5
Due to following vulnerabilities
CVE-2017-15095
CVE-2017-17485
CVE-2018-7489
2018-05-31 12:03:47 -04:00
Misagh Moayyed c015e226ba Merge pull request #231 from Unicon/urlenc-queryparams
Handle un-encoded query strings in url parameters as embedded query strings
2018-03-08 15:58:35 +01:00
Misagh Moayyed 5d18b34159 Update .travis.yml 2018-02-02 20:15:20 +01:00
Misagh Moayyed ae50749c5f Update .travis.yml 2018-01-31 21:48:55 +03:30
Misagh Moayyed 3875c39a21 handle un-encoded query strings in url parameters 2018-01-31 14:11:00 +03:30
Dmitriy Kopylenko b208e94b93 [maven-release-plugin] prepare for next development iteration 2018-01-12 11:56:32 -05:00
Dmitriy Kopylenko c00da6bb81 [maven-release-plugin] prepare release cas-client-3.5.0 2018-01-12 11:56:28 -05:00
Dmitriy Kopylenko 486aa66587 prepare for the release 2018-01-12 11:46:12 -05:00
Dmitriy Kopylenko 527f60f334 Polishing 2018-01-11 10:41:28 -05:00
Misagh Moayyed c06facd9e1 Merge pull request #209 from tkd-yas/master
Fix missing parameter key in service url (#208)
2017-10-06 04:31:21 -07:00
Misagh Moayyed 962c8185ae Merge pull request #220 from mmoayyed/tomcat85x
Add support for tomcat 8.5.x
2017-10-06 04:30:25 -07:00
Misagh Moayyed 6280319d80 Fix travis URLs: point to apereo rather than jasig 2017-07-11 16:58:14 -07:00
Misagh Moayyed 2d6b80842b updated docs 2017-07-06 14:06:24 -07:00
Misagh Moayyed b8f2e0a32c Add support for tomcat 8.5.x 2017-07-06 14:01:21 -07:00
Scott 47efae9e92 Merge pull request #213 from lxbzmy/patch-1
Add JIRA Rest API support
2017-06-21 23:20:17 -04:00
Misagh Moayyed ef2baa8983 Fixed logging issue; returning null in case principal cannot be determined 2017-06-20 09:21:04 -07:00
Misagh Moayyed 9d57eb3655 Merge pull request #188 from eghm/master
Log an error message if CAS principal has no corresponding Confluence principal
2017-06-20 09:18:46 -07:00
Misagh Moayyed f341f50cd5 Merge pull request #212 from mmoayyed/json-validator
New Json ticket validator to accept CAS responses in JSON.
2017-06-20 09:16:37 -07:00
Scott 52edf95202 Merge pull request #214 from hdeadman/master
Improve error logging when getting response from CAS server fails
2017-06-02 12:38:55 -04:00
Hal Deadman f9202b9a8a Improve error logging when getting response fails 2017-06-02 10:59:16 -04:00
Misagh Moayyed b02a122e9d Merge pull request #156 from joeschweitzer/master
Return existing user if session is already authenticated
2017-06-01 21:06:42 -04:00
Misagh Moayyed ccf8e718b2 Apply changes after code review by @serac 2017-06-01 21:03:51 -04:00
Alex Lei 雷 91dd394a08 Add JIRA Rest API support
new JIRA 6 has rest api begin with url /rest when I use cas authentication filter which skip filter /rest ,there will be thrown exception:

java.lang.NullPointerException
    at com.atlassian.jira.security.login.JiraSeraphAuthenticator.getUserFromBasicAuthentication(JiraSeraphAuthenticator.java:149) 
    at com.atlassian.seraph.auth.DefaultAuthenticator.getUser(DefaultAuthenticator.java:339) [atlassian-seraph-3.0.3.jar:?]
    at org.jasig.cas.client.integration.atlassian.Jira44CasAuthenticator.getUser(Jira44CasAuthenticator.java:76) [cas-client-integration-atlassian-3.4.1.jar:3.4.1] 
    at com.atlassian.seraph.auth.AbstractAuthenticator.getUser(AbstractAuthenticator.java:45) [atlassian-seraph-3.0.3.jar:?]
    at com.atlassian.seraph.filter.BaseLoginFilter$SecurityHttpRequestWrapper.getUserPrincipal(BaseLoginFilter.java:238) [atlassian-seraph-3.0.3.jar:?]
    at com.atlassian.seraph.filter.BaseLoginFilter$SecurityHttpRequestWrapper.getRemoteUser(BaseLoginFilter.java:225) [atlassian-seraph-3.0.3.jar:?]
    at javax.servlet.http.HttpServletRequestWrapper.getRemoteUser(HttpServletRequestWrapper.java:168) [servlet-api.jar:?]
    at com.atlassian.jira.web.filters.accesslog.AccessLogFilter.preFilterCallStep(AccessLogFilter.java:175) [classes/:?]
    at com.atlassian.jira.web.filters.accesslog.AccessLogFilter.executeRequest(AccessLogFilter.java:86) [classes/:?]
    at com.atlassian.jira.web.filters.accesslog.AccessLogFilter.doFilter(AccessLogFilter.java:78) [classes/:?]

After hard debug work I found key program flow different from default authenitcator  :

in `com.atlassian.seraph.filter.BaseLoginFilter#SecurityHttpRequestWrapper#getUserPrincipal()`

public Principal getUserPrincipal() {
            return BaseLoginFilter.this.getAuthenticator().getClass().isAnnotationPresent(AuthenticationContextAwareAuthenticator.class)?BaseLoginFilter.this.getAuthenticationContext().getUser():BaseLoginFilter.this.getAuthenticator().getUser(this.delegateHttpServletRequest);
        }

The `AuthenticationContextAwareAuthenticator` annotation cause different flow.

So, add `AuthenticationContextAwareAuthenticator` annotation can slow problem.
2017-05-27 11:13:09 +08:00
Misagh Moayyed 6468166c40 Merge pull request #124 from leleuj/casc-121
Upgrade to Java 6
2017-05-24 09:23:51 -04:00
leleuj 6f84cc2356 merge with master 2017-05-24 08:36:57 +02:00
Misagh Moayyed f5a0ee6987 Merge pull request #187 from Unicon/Frontchannel-slo
Handle front-channel SLO
2017-05-22 12:25:15 -04:00
Misagh Moayyed e56e0d2aa0 Exclude transaction dependency 2017-05-22 09:19:54 -07:00
Misagh Moayyed dfb13e5397 add test cases 2017-05-18 14:09:11 -07:00
Misagh Moayyed 552b9f9fac Fix test cases with attribute encoding 2017-05-18 12:31:44 -07:00
Misagh Moayyed 1e1a0ec5e8 update readme 2017-05-17 16:50:13 -07:00
Misagh Moayyed 24f1f9c814 clean up JIRA dependencies so project can compile 2017-05-17 16:42:09 -07:00
Misagh Moayyed 059ec7d527 clean up JIRA dependencies so project can compile 2017-05-17 16:31:50 -07:00
Misagh Moayyed f2ea4129bd allow extension points for JSON validation parsing. add filter and validator 2017-05-17 16:13:46 -07:00
Misagh Moayyed 88789ef358 allow extension points for JSON validation parsing. add filter and validator 2017-05-17 16:00:24 -07:00
Misagh Moayyed 5152f40be9 allow extension points for JSON validation parsing. add filter and validator 2017-05-17 15:59:20 -07:00
Misagh Moayyed 1fc896c458 allow extension points for JSON validation parsing. add filter and validator 2017-05-17 15:04:42 -07:00
Misagh Moayyed 1561da75ad Fix formatting issues with the markdown title 2017-04-25 09:28:10 -07:00
Yasuhiro Takada 834531c7a6 fix test faiiure 2017-04-17 20:36:40 +09:00
Yasuhiro Takada 2f7729a892 fix missing parameter key in service url when parameter value not provided. 2017-04-17 19:22:41 +09:00
Misagh Moayyed f998bb07c3 Merge pull request #200 from zhixiangli/master
add setter to ignoreUrlPatternMatcherStrategyClass
2017-01-05 19:29:56 +03:30
lizhixiang 47fb9c0fbb add setter to ignoreUrlPatternMatcherStrategyClass, with purpose of
injecting UrlPatternMatcherStrategy to AuthenticationFilter by Spring
IOC
2017-01-05 12:16:16 +08:00
Misagh Moayyed 4d1d62bd62 Merge pull request #184 from Unicon/Skew-assertion-date
Handle date equality when checking for assertion validity
2016-09-23 10:24:02 +03:30
eghm bad68332a6 Use parameterized log statement when logging CAS only principle. 2016-09-19 10:14:22 -10:00
eghm 2ae54e8d98 Log an error message if CAS principle has no corresponding Confluence principle. 2016-09-15 13:57:11 -10:00
Misagh Moayyed 6be07281d5 Fixed test cases 2016-09-09 16:22:32 +04:30
Misagh Moayyed 7db200e8c6 Updated front-channel SLO handling 2016-09-09 16:14:06 +04:30
Misagh Moayyed 527f0c6d28 Merge pull request #181 from Unicon/Tostring
Let ConfigurationKey toString() the name
2016-09-07 20:53:38 +04:30
Misagh Moayyed 7d5a9bc124 Merge pull request #185 from Unicon/Redundant-GroupId
Remove redundant groupId from POM defns
2016-09-07 20:53:21 +04:30
Misagh Moayyed 92371f794a Remove redundant groupId from POM defns 2016-09-07 16:12:34 +04:30
Misagh Moayyed 9e95ee5825 Handle date equality when checking for saml assertion validity 2016-09-07 16:10:16 +04:30
Scott 86a8f7395b Merge pull request #182 from Unicon/Refact
Minor code adjustments to CommonUtils to use String.isEmpty()
2016-09-07 07:30:43 -04:00
Misagh Moayyed 9d4cafd2c9 Let assertion validity checks to be more flexible
when comparing dates.
2016-09-07 15:47:04 +04:30
Misagh Moayyed 745fda6113 Minor code adjustments to CommonUtils to use String.isEmpty() 2016-09-07 15:38:46 +04:30
Misagh Moayyed aa6cab7d8d Merge pull request #180 from serac/logpt
Log proxy ticket returned from /proxy protocol endpoint.
2016-09-07 15:32:49 +04:30
Misagh Moayyed 9b71825e1a Let config keys log the name 2016-09-07 15:31:39 +04:30
Marvin S. Addison 2e27e09f3b Log proxy ticket returned from /proxy protocol endpoint. 2016-09-01 13:22:01 -04:00
Olivier Jaquemet b4d9570bdc Fix #177 Every other request incorrectly gatewayed
- ensure behavior of gateway is predictable (reentrant)
2016-08-09 10:27:27 +02:00
Marvin S. Addison 7cb5380e75 Issue #152 Jetty integration docs. 2016-05-24 07:53:15 -04:00
Scott e7292c78a0 Merge pull request #167 from geojs/issue-167
Wrong Maven groupId in README.md for Components
2016-05-16 12:54:07 -04:00
cobolgis 771288475f Recommended fix for #167. 2016-05-16 16:04:12 +02:00
Misagh Moayyed ee4a05d409 Merge pull request #166 from ceharris/patch-1
change git clone URL in README to reflect new org slug
2016-05-13 09:04:00 -07:00
Carl Harris f1cd2441ca change git clone URL to reflect new org slug 2016-05-13 11:03:11 -04:00
Scott 95c5d8ee73 Merge pull request #158 from BernhardLenz/cas-client-integration-tomcat-v8
Added Tomcat client v8 to readme and notice files
2016-04-01 00:05:51 -04:00
BernhardLenz f1908ba5fc Added Tomcat client v8 to readme and notice files 2016-03-28 09:02:46 -04:00
Joe Schweitzer 8e1a7789b1 Return existing user if session is already authenticated 2016-03-17 12:03:11 -04:00
Scott b20d4d241c Merge pull request #153 from serac/jetty
CAS Jetty Container Authentication Support
2016-03-08 07:20:51 -05:00
Marvin S. Addison bc586d7b4b Merge branch 'master' into jetty 2016-03-08 07:15:22 -05:00
Marvin S. Addison 06b566e2d6 Issue #152 Simplify ticket lookup. 2016-03-07 07:51:25 -05:00
Marvin S. Addison 3f0a1c6883 Issue #152 Fix javadoc typo. 2016-03-07 07:45:50 -05:00
Marvin S. Addison 812198b6a5 Issue #152 Use CommonUtils for null checks. 2016-03-07 07:45:26 -05:00
Scott 88d847102c Merge pull request #151 from BernhardLenz/cas-client-integration-tomcat-v8
Added cas-client-integration-tomcat-v8
2016-03-04 21:52:20 -05:00
Marvin S. Addison 40291a4478 Issue #152 Log authentication success at INFO. 2016-02-19 10:43:15 -05:00
Marvin S. Addison 184868b296 Issue #152 Add working Jetty context config files. 2016-02-12 16:40:05 -05:00
Marvin S. Addison 5a68c92268 Issue #152 Prevent dupe ticket validations.
The ticket parameter can linger in the URL after authentication.
Don't attempt ticket validation if we are already authenticated.
Fixes ticket validation failures on refresh and similar cases.
2016-02-12 16:20:56 -05:00
Marvin S. Addison f09ee1c0e7 Issue #152 Fix multiple ticket validation attempt. 2016-02-12 15:34:19 -05:00
Marvin S. Addison 971d4b4854 Issue #152 Remove unused jetty-maven-plugin. 2016-02-11 15:12:39 -05:00
Marvin S. Addison f04dedd9bb Issue #152 Use WeakReference to avoid resource leak.
We don't want to hold a reference to HttpSession objects in the
ticket-to-session mapping that would prevent orphaned or expired sessions
from being purged. WeakReference ensures that won't happen.
2016-02-11 15:08:00 -05:00
Marvin S. Addison 53dbb48882 Issue #152 Jetty container-based authn. 2016-02-11 14:53:14 -05:00
BernhardLenz 61bd0eeb86 Added cas-client-integration-tomcat-v8 2016-02-04 18:45:03 -05:00
Scott e4b767700a Merge pull request #143 from battags/CASC-127
CASC-127 Remove Commons Codec Dependency
2015-11-19 21:02:57 -05:00
Scott 346374ebc8 CASC-127 Remove Commons Codec Dependency
Problem: We rely on Commons Codec for some simple Base64 decoding/encoding, most of which is available in Java 1.6+
Solution: Set minimum version to Java 1.6 and rely on provided methods.

QA Notes: Unit tests pass
2015-11-18 21:58:06 -05:00
Misagh Moayyed 4b63e06418 updated docs on SSOFilter and ErrorRedirectFilter 2015-11-08 13:54:31 -07:00
Misagh Moayyed 32963967d4 updated docs on SSOFilter and ErrorRedirectFilter 2015-11-08 13:53:33 -07:00
Scott 9d9e5cad72 Merge pull request #142 from serac/issue-141-remove-content-length
Issue-141 Remove redundant Content-Length header.
2015-11-05 20:43:56 -05:00
Marvin S. Addison 598fb02dda Issue-141 Remove redundant Content-Length header. 2015-11-05 16:44:05 -05:00
Misagh Moayyed a417f78521 Fix badge link for maven version 2015-09-13 08:16:18 -07:00
Scott a5e2b8ae61 [maven-release-plugin] prepare for next development iteration 2015-09-13 00:23:55 -04:00
Scott 650cee05bc [maven-release-plugin] prepare release cas-client-3.4.1 2015-09-13 00:19:52 -04:00
Scott e5f933754b [maven-release-plugin] rollback the release of cas-client-3.4.1 2015-09-13 00:18:34 -04:00
Scott 1bdc456bf4 [maven-release-plugin] prepare for next development iteration 2015-09-13 00:13:20 -04:00
Scott 8067714256 Added missing license headers. 2015-09-13 00:11:09 -04:00
Scott 85b0454e8d Merge pull request #133 from battags/131
Issue #131 - ConfigurationStrategyName does not Properly Resolve Cust…
2015-09-10 09:27:08 -04:00
Scott 2eb132c0b4 Issue #131 - ConfigurationStrategyName does not Properly Resolve Custom classes
Problem: The assignable check was reversed, always resulting in a false return value.
Solution: Add test to confirm failure and then swap check.  Unit tests pass.
2015-09-09 23:30:53 -04:00
Scott 0022c622e1 Merge pull request #130 from mmoayyed/serviceurl-construction-method
Overload constructServiceUrl to keep backward compatibility
2015-08-19 22:28:58 -04:00
Misagh Moayyed ab105cdcfa initialize service parameter names once, statically 2015-08-19 08:51:28 -07:00
Misagh Moayyed 1f3a745ec8 overload constructServiceUrl to keep backward compatibility 2015-08-19 02:28:20 -07:00
Scott ba47157062 Merge pull request #128 from mmoayyed/uribuilder-tests
URIBuilder test cases
2015-08-13 07:37:08 -04:00
Misagh Moayyed 4f746b3b58 Update .travis.yml 2015-08-13 03:00:26 -07:00
Misagh Moayyed d7538dfd61 Update .travis.yml 2015-08-13 02:59:36 -07:00
LELEU Jérôme 335d3f3a3e Update .travis.yml 2015-08-13 11:36:24 +02:00
Misagh Moayyed 618a99a245 URIBuilder test cases 2015-08-12 12:36:50 -07:00
LELEU Jérôme 0d2740ec0c Merge pull request #125 from xuhuisheng/master
URIBuilder throws UnsupportedOperationException on adding/setting parameters
2015-08-10 10:35:13 +02:00
Xu Huisheng 69bba0c21a When serverName contains schema, the URIBuilder will throw an UnsupportedOperationException while adding a parameter. 2015-08-04 18:20:31 +08:00
Jérôme LELEU f0047eb8eb upgrade version to 3.5.0-SNAPSHOT 2015-08-03 12:53:19 +02:00
Jérôme LELEU 60b8ad70f8 Upgrade to Java 6 2015-07-31 17:02:21 +02:00
LELEU Jérôme d46e3c6220 Merge pull request #122 from leleuj/casc-119
Deploy SNAPSHOTs to Sonatype
2015-07-31 10:37:29 +02:00
Jérôme LELEU 8ff374b949 Revert "using the old Travis infrastructure (no container)"
This reverts commit ce06a4fd91.
2015-07-30 11:23:47 +02:00
Jérôme LELEU e9b79194d7 using the old Travis infrastructure (no container) 2015-07-30 11:05:12 +02:00
LELEU Jérôme 72685767f7 Merge pull request #123 from leleuj/casc-120
Update README with 3.4 features
2015-07-29 11:13:52 +02:00
Jérôme LELEU bb11bfa7c8 Update README with 3.4 features 2015-07-28 09:29:27 +02:00
Jérôme LELEU bdecba6431 Deploy SNAPSHOTs to Sonatype 2015-07-28 08:42:33 +02:00
Scott 67b4b26819 [maven-release-plugin] prepare for next development iteration 2015-07-21 22:57:28 -04:00
Scott f3d7156482 [maven-release-plugin] prepare release cas-client-3.4.0 2015-07-21 22:57:26 -04:00
Scott 8bab6d1f4e Fixed licenses 2015-07-21 22:42:41 -04:00
Scott 76ba57a541 Added missing license headers 2015-07-21 22:19:00 -04:00
Scott ec744b2c9f Updated NOTICE generation. 2015-07-21 22:16:53 -04:00
Misagh Moayyed 4db9948c19 Moved build to the new travis environment 2015-07-10 08:34:46 -07:00
Scott 0a7ffac846 Merge pull request #66 from Unicon/CASC-210
CASC-210: Added support for having regex expressions in the proxy (chaining) list.
2015-07-07 17:10:05 -04:00
Scott c8e50905bb Merge pull request #116 from Unicon/remove-lang
removed commons-lang dependency
2015-07-03 11:27:00 -04:00
Scott eaee34b361 Merge pull request #105 from mmoayyed/removing-service-param
Added uri builder to construct query params
2015-07-03 11:13:31 -04:00
Scott 6ce10daea0 Merge pull request #117 from lathspell/master
Add filter-mapping to web.xml filter examples
2015-07-03 09:22:29 -04:00
John Gasper f98e776869 casc-210: Merge branch 'master' of https://github.com/jasig/java-cas-client into CASC-210
Resolved Conflicts:
	cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java
2015-06-16 12:09:37 -07:00
Christian Brunotte df07758a89 missing "<" in example 2015-06-16 19:30:49 +02:00
Christian Brunotte 302822f361 Added <filter-mapping> to all web.xml <filter> examples. 2015-06-16 19:29:16 +02:00
Misagh Moayyed e1e12a5f3f removed since tags 2015-06-10 20:09:15 -07:00
Misagh Moayyed 8c77fc4eaf removed commons-lang dep 2015-06-10 20:04:12 -07:00
Scott 607d53a2aa Merge pull request #113 from Unicon/commons-lang3
Upgrade to commons-lang3
2015-06-08 22:56:07 -04:00
Misagh Moayyed 70b8aa8032 Merge pull request #112 from Unicon/depc-const
Deprecated unused DISABLE_XML_SCHEMA_VALIDATION
2015-06-07 20:48:35 -07:00
Misagh Moayyed 806672e525 Merge pull request #114 from Unicon/proxying-log-warn
Added additional logs to proxy validation
2015-06-07 20:48:26 -07:00
Misagh Moayyed 853450a8a6 added additional logs to proxy validation 2015-06-07 17:05:47 -07:00
Misagh Moayyed 05873137dc Update README.md 2015-06-07 13:29:05 -07:00
Misagh Moayyed 8bc89e648a Create .travis.yml 2015-06-07 13:27:32 -07:00
Misagh Moayyed f1ac21943d upgrade to commons-lang3 v3.4 2015-06-07 13:24:12 -07:00
Misagh Moayyed c6c106c375 deprecated unused const 2015-06-07 13:18:19 -07:00
Misagh Moayyed 0a6ce18150 updated param building 2015-06-05 15:17:04 -07:00
Misagh Moayyed 73e2a63a5b Merge branch 'master' into removing-service-param 2015-06-05 15:14:29 -07:00
Misagh Moayyed 77e5340c3c Update README.md 2015-05-24 18:59:20 +04:00
Misagh Moayyed 573976cda9 Update README.md 2015-05-23 23:09:30 +04:00
Misagh Moayyed dc028a6652 Update README.md 2015-05-23 23:08:50 +04:00
Misagh Moayyed 50fc28034d Update README.md 2015-05-23 22:50:52 +04:00
Misagh Moayyed 3c40922847 Update README.md 2015-05-23 22:50:09 +04:00
Misagh Moayyed d72913b53a Update README.md 2015-05-23 22:01:48 +04:00
Misagh Moayyed a31979920b Update README.md 2015-05-23 21:50:09 +04:00
Misagh Moayyed 8ec71aa2c6 Update README.md 2015-05-23 16:41:15 +04:00
Misagh Moayyed 74f0a209dd Update README.md 2015-05-23 16:40:15 +04:00
Misagh Moayyed f8f5b908d0 Create README.md 2015-05-23 02:46:17 +04:00
Misagh Moayyed d3ba9c0ae7 Delete README.txt 2015-05-23 02:45:28 +04:00
Misagh Moayyed f68281d0e4 added uri builder to construct query params 2015-05-13 03:44:13 -07:00
Marvin S. Addison 863038605f Merge pull request #101 from Jasig/no-opensaml
Remove OpenSAML and consolidate SAML components in support module
2015-05-12 09:29:02 -04:00
Marvin S. Addison f5b2275913 Issue #100 Bump minor version due to refactoring. 2015-05-11 12:09:00 -04:00
Marvin S. Addison 1edef62ecb Issue #100 Isolate JodaTime to SAML module. 2015-05-11 12:01:48 -04:00
Marvin S. Addison 7c58629958 Issue 100 Restore configuration key for backward compatibility. 2015-05-04 16:10:56 -04:00
Marvin S. Addison 70ed5fd8bb Add Marvin to SAML validator component authorship. 2015-05-04 16:07:47 -04:00
Marvin S. Addison 6e261e7251 Issue #100 Respond to code review feedback. 2015-04-20 10:34:28 -04:00
Scott 0652f4ee23 Merge pull request #93 from leleuj/CASC-217
CASC-217: Update the ticket validators to point to the new endpoint
2015-04-20 06:54:48 -04:00
Marvin S. Addison d8980535b7 Move SAML components into separate module. 2015-04-14 16:19:12 -04:00
Marvin S. Addison dd0818b84f Fix @since version. 2015-02-20 10:35:05 -05:00
Marvin S. Addison 4527671568 Sensible XPath processing optimizations. 2015-02-20 10:26:01 -05:00
Marvin S. Addison e998985732 SAML validation with XPath instead of OpenSAML. 2015-02-20 09:18:05 -05:00
Scott 6f7fe61780 Merge pull request #97 from battags/CASC-239
CASC-239 Saml11AuthenticationFilter Constructor was Private instead of Public
2015-01-25 19:11:28 -05:00
Scott db3610123f CASC-239 Saml11AuthenticationFilter Constructor was Private instead of Public. 2015-01-24 23:58:51 -05:00
Scott 380585d391 Merge pull request #96 from Jasig/conditional-opensaml-init
CASC-237 Make OpenSAML bootstrap conditional.
2015-01-20 08:34:08 -05:00
Marvin S. Addison 4aef368057 CASC-237 Make OpenSAML bootstrap conditional. 2015-01-17 11:25:03 -05:00
Scott 6de80009cf Merge pull request #94 from leleuj/casc-91
Issue-91: Introduce system properties configuration option
2015-01-07 08:48:41 -05:00
LELEU Jerome bec0e6bb2e Issue-91: Introduce system properties configuration option
First commit
2015-01-05 17:19:40 +01:00
LELEU Jerome 2a98556daa CASC-217: Update the ticket validators to point to the new endpoint
First commit
2015-01-05 15:55:33 +01:00
Scott f49c08ce93 Merge pull request #88 from battags/CASC-231
CASC-231 HttpsURLConnectonFactory is Not Serializable
2014-12-22 23:56:48 -05:00
Scott ec92d97518 Added license headers 2014-12-22 23:55:23 -05:00
Scott 34458db530 Merge branch 'master' into CASC-231 2014-12-22 23:54:46 -05:00
Scott 0b220c6f55 Merge pull request #89 from battags/CASC-200
CASC-200 Introduce Properties File Configuration Option
2014-12-22 22:10:50 -05:00
Scott 39f0f29dd9 CASC-200 Introduce Properties File Configuration Option
Problem: We can configure via JNDI, WebXML (or both) but not by properties file.
Solution: Introduce a method to use property files.
2014-12-07 14:14:08 -05:00
Scott d1da02f457 CASC-231 HttpsURLConnectonFactory is Not Serializable
Problem: THe HttpsURLConnectionFactory is not serializable, causing problems for clients that must serialize
the principal (which depends on a ProxyRetriever).

Solution: Make the HttpsURLConnectionFactory serializable.

QA Notes: added unit test to confirm serialize-deserialize
2014-12-07 13:32:14 -05:00
Scott d7ca6a098e Merge pull request #87 from battags/CASC-233
CASC-233 ErrorRedirectFilter Can throw Null Pointer Exception
2014-12-07 12:13:27 -05:00
Scott f17c4d6087 Merge pull request #86 from battags/CASC-200-rebasefail
CASC-200 Introduce Mechanism to Indicate Method of Configuration
2014-12-07 12:12:56 -05:00
Scott a780e39ab9 Merge branch 'master' into CASC-200-rebasefail
Conflicts:
	cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java
2014-12-07 12:11:42 -05:00
Scott Battaglia bef2a88603 Updated try/catch loop to log when a class is not found. 2014-11-30 17:09:09 -05:00
Scott Battaglia 3af5683dc1 Addressed formatting feedback as well as reserved keywords. 2014-11-26 22:58:12 -05:00
Scott Battaglia 5109132df3 Per feedback, scoped catch block to Exception instead of Throwable 2014-11-26 22:31:01 -05:00
Scott Battaglia 51a9192792 CASC-233 ErrorRedirectFilter Can throw Null Pointer Exception
Problem: the ErrorRedirectFilter assumes there is a root cause and will null pointer if there is not.
Solution: Only use the root cause if there is one, otherwise use the original exception.

QA Notes: Added unit test to confirm non-root cause error.
2014-11-20 16:29:29 -05:00
Scott Battaglia c7e66d7df2 Unused reference to Mockito 2014-11-20 16:03:19 -05:00
Scott Battaglia d011f5e64a Removed unused mockito dependency 2014-11-20 16:01:02 -05:00
Scott Battaglia 17f887595f Added missing javadoc for Protocol enumeration 2014-11-20 15:58:52 -05:00
Scott Battaglia 324b0919b6 Added additional keys that were new from the single signout refactor. 2014-11-20 15:31:31 -05:00
Scott Battaglia 461cdcd8fc CASC-200 Create a ConfigurationStrategy to allow for pluggable configurations.
Problem: The lookup strategy for configuration is hard-coded into the filter, making it impossible to replace or expand.
Solution: Pull the strategies into their own classees and make it configurable.  Default to the previous strategy.

QA Notes: The current unit tests work.  New unit tests for the configuration will have to be added once the design is approved.
2014-11-20 15:30:38 -05:00
Marvin S. Addison 4e3f761efe [maven-release-plugin] prepare for next development iteration 2014-08-15 08:52:01 -04:00
John Gasper c61dea96bf Formatting clean-up 2014-04-15 12:56:46 -07:00
John Gasper 99763ab2b6 Using Misagh's PatternMatcherStrategy to optimize proxy chain checks 2014-04-14 08:45:21 -07:00
John Gasper 7ac4c7afb7 Merge branch 'master' of https://github.com/jasig/java-cas-client into CASC-210 2014-04-11 15:17:29 -07:00
John Gasper 0ef575ae84 Refactored the match logic and cache the regex patterns. 2014-03-07 16:11:00 -08:00
John Gasper 887da3bffd no message 2014-03-05 10:54:34 -08:00
John Gasper 90ccc41db3 Minor corrections. 2014-03-05 10:45:35 -08:00
John Gasper 80ff9857f0 Added support for having regex expressions in the proxy (chaining) list. 2014-03-05 10:17:59 -08:00
281 changed files with 15751 additions and 3293 deletions

20
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,20 @@
#
# 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.
#
custom: ['https://www.apereo.org/content/apereo-membership']

11
.github/renovate.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"extends": [
"config:base",
":preserveSemverRanges",
":rebaseStalePrs",
":disableRateLimiting",
":semanticCommits",
":semanticCommitTypeAll(renovatebot)"
],
"labels": ["dependencies", "bot"]
}

73
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,73 @@
#
# 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.
#
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 7
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Label to use when marking as stale
staleLabel: Pending
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This patch has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This patch has been automatically closed because it has not had
recent activity. If you wish to resume work, please re-open the pull request
and continue as usual. Thank you for your contributions.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
# only: pulls
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

44
.mergify.yml Normal file
View File

@ -0,0 +1,44 @@
#
# 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 by dependabot
conditions:
- status-success=continuous-integration/travis-ci/pr
- status-success=WIP
- "#changes-requested-reviews-by=0"
- base=master
- label=dependencies
actions:
merge:
method: squash
strict: false
delete_head_branch:
- name: automatic merge by renovate
conditions:
- status-success=continuous-integration/travis-ci/pr
- status-success=WIP
- "#changes-requested-reviews-by=0"
- base=master
- label=dependencies
actions:
merge:
method: squash
strict: false
delete_head_branch:

38
.travis.yml Normal file
View File

@ -0,0 +1,38 @@
#
# 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

129
NOTICE
View File

@ -1,80 +1,101 @@
Copyright 2010, JA-SIG, Inc.
This project includes software developed by Jasig.
http://www.jasig.org/
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:
Licensed 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:
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
KIND, either express or implied. See the License for the
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:
"Java Concurrency in Practice" book annotations under Creative Commons Attribution License
AOP alliance under Public Domain
Apache Commons Codec under Apache License, Version 2.0
Apache Log4j under The Apache Software License, Version 2.0
Apache Santuario under The Apache Software License, Version 2.0
Apache Velocity under The Apache Software License, Version 2.0
Apache Log4j API under Apache License, Version 2.0
Apache Log4j to SLF4J Adapter under Apache License, Version 2.0
Apache XML Security under The Apache Software License, Version 2.0
Apereo CAS Client for Java under Apache License Version 2.0
asm under BSD
asm-analysis under BSD
asm-commons under BSD
asm-tree under BSD
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
Codec under The Apache Software License, Version 2.0
com.atlassian.confluence:confluence under Atlassian End User License
com.atlassian.event:atlassian-event under Atlassian End User License
com.atlassian.jira:jira-core under Atlassian End User License
com.atlassian.osuser:atlassian-osuser under Atlassian End User License
com.atlassian.seraph:atlassian-seraph under Atlassian End User License
Commons Codec under The Apache Software License, Version 2.0
commons-collections under Apache License, Version 2.0
coyote under Apache License, Version 2.0
Eclipse Compiler for Java(TM) under Eclipse Public License - v 2.0
Ehcache Core under The Apache Software License, Version 2.0
ESAPI 2.0 under BSD or Creative Commons 3.0 BY-SA
Google Collections Library under The Apache Software License, Version 2.0
HttpClient under Apache License
Jasig CAS Client for Java under Apache License Version 2.0
Jasig CAS Client for Java - Atlassian Integration under Apache License Version 2.0
Hamcrest Core under New BSD License
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 - Distributed Proxy Storage Support:
Memcached 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
Java Servlet API under CDDL + GPLv2 with classpath exception
JavaBeans Activation Framework (JAF) under Common Development and Distribution License (CDDL) v1.0
JavaMail API under Common Development and Distribution License (CDDL) v1.0
javax.annotation API under CDDL + GPLv2 with classpath exception
JBoss Application Server Tomcat under lgpl
JCL 1.1.1 implemented over SLF4J under MIT License
Joda time under Apache 2
JCL 1.2 implemented over SLF4J under MIT License
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 :: 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 Common Public License Version 1.0
Lang under The Apache Software License, Version 2.0
Log4j Implemented Over SLF4J under Apache Software Licenses
Not Yet Commons SSL under Apache License v2
OpenSAML-J under Apache 2
OpenWS under Apache 2
JUnit under Eclipse Public License 1.0
Logback Classic Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License
Logback Core Module under Eclipse Public License - v 1.0 or GNU Lesser General Public License
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
Spring Framework: Context under The Apache Software License, Version 2.0
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
spring-test under The Apache Software License, Version 2.0
SnakeYAML under Apache License, Version 2.0
Spring AOP under Apache License, Version 2.0
Spring Beans under Apache License, Version 2.0
Spring Boot under Apache License, Version 2.0
Spring Boot AutoConfigure under Apache License, Version 2.0
Spring Boot Logging Starter under Apache License, Version 2.0
Spring Boot Starter under Apache License, Version 2.0
Spring Commons Logging Bridge under Apache License, Version 2.0
Spring Context under Apache License, Version 2.0
Spring Core under Apache License, Version 2.0
Spring Expression Language (SpEL) under Apache License, Version 2.0
Spring TestContext Framework under Apache License, Version 2.0
Spring Web under Apache License, Version 2.0
Spymemcached under The Apache Software License, Version 2.0
tomcat-annotations-api under Apache License, Version 2.0
tomcat-catalina under Apache License, Version 2.0
Xalan Java under The Apache Software License, Version 2.0
Xalan Java Serializer under The Apache Software License, Version 2.0
Xerces2-j under The Apache Software License, Version 2.0
XML Commons External Components XML APIs under The Apache Software License, Version 2.0 or The SAX License or The W3C License
XML Commons Resolver Component under The Apache Software License, Version 2.0
XMLTooling-J under Apache 2
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

1504
README.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
BUILDING THE CAS CLIENT FOR JAVA
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.

View File

@ -1,9 +1,9 @@
<!--
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:

View File

@ -1,18 +1,18 @@
====
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:
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
KIND, either express or implied. See the License for the
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.
====

View File

@ -1,58 +1,42 @@
Copyright 2010, JA-SIG, Inc.
This project includes software developed by Jasig.
http://www.jasig.org/
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:
Licensed 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:
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
KIND, either express or implied. See the License for the
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:
"Java Concurrency in Practice" book annotations under Creative Commons Attribution License
AOP alliance under Public Domain
Apache Commons Codec under Apache License, Version 2.0
Apache Log4j under The Apache Software License, Version 2.0
Apache Santuario under The Apache Software License, Version 2.0
Apache Velocity under The Apache Software License, Version 2.0
Apache XML Security under The Apache Software License, Version 2.0
Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs under Bouncy Castle Licence
Bouncy Castle Provider under Bouncy Castle Licence
Commons Codec under The Apache Software License, Version 2.0
commons-collections under Apache License, Version 2.0
ESAPI 2.0 under BSD or Creative Commons 3.0 BY-SA
HttpClient under Apache License
Hamcrest Core under New BSD License
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
Java Servlet API under CDDL + GPLv2 with classpath exception
JavaBeans Activation Framework (JAF) under Common Development and Distribution License (CDDL) v1.0
JavaMail API under Common Development and Distribution License (CDDL) v1.0
JCL 1.1.1 implemented over SLF4J under MIT License
Joda time under Apache 2
JUL to SLF4J bridge under MIT License
JUnit under Common Public License Version 1.0
Lang under The Apache Software License, Version 2.0
Log4j Implemented Over SLF4J under Apache Software Licenses
Not Yet Commons SSL under Apache License v2
OpenSAML-J under Apache 2
OpenWS under Apache 2
JCL 1.2 implemented over SLF4J under MIT License
JUnit under Eclipse Public License 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
spring-test under The Apache Software License, Version 2.0
Xalan Java under The Apache Software License, Version 2.0
Xalan Java Serializer under The Apache Software License, Version 2.0
Xerces2-j under The Apache Software License, Version 2.0
XML Commons External Components XML APIs under The Apache Software License, Version 2.0 or The SAX License or The W3C License
XML Commons Resolver Component under The Apache Software License, Version 2.0
XMLTooling-J under Apache 2
Spring AOP under Apache License, Version 2.0
Spring Beans under Apache License, Version 2.0
Spring Commons Logging Bridge under Apache License, Version 2.0
Spring Context under Apache License, Version 2.0
Spring Core under Apache License, Version 2.0
Spring Expression Language (SpEL) under Apache License, Version 2.0
Spring TestContext Framework under Apache License, Version 2.0
Spring Web under Apache License, Version 2.0

View File

@ -1,15 +1,51 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.jasig.cas.client</groupId>
<version>3.3.3</version>
<version>3.6.2-SNAPSHOT</version>
<artifactId>cas-client</artifactId>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<packaging>jar</packaging>
<name>Jasig CAS Client for Java - Core</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>xml-security</groupId>
@ -20,27 +56,10 @@
</dependency>
<dependency>
<groupId>org.opensaml</groupId>
<artifactId>opensaml</artifactId>
<version>${opensaml.version}</version>
<type>jar</type>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
@ -48,30 +67,27 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
@ -79,7 +95,7 @@
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>test</scope>
<version>1.2.15</version>
<version>1.2.17</version>
<exclusions>
<exclusion>
<artifactId>jmxri</artifactId>
@ -97,8 +113,4 @@
</dependency>
</dependencies>
<properties>
<spring.version>3.1.3.RELEASE</spring.version>
<opensaml.version>2.5.1-1</opensaml.version>
</properties>
</project>

View File

@ -0,0 +1,51 @@
/**
* 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;
/**
* Simple enumeration to hold/capture some of the standard request parameters used by the various protocols.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public enum Protocol {
CAS1("ticket", "service"), CAS2(CAS1), CAS3(CAS2), SAML11("SAMLart", "TARGET");
private final String artifactParameterName;
private final String serviceParameterName;
private Protocol(final String artifactParameterName, final String serviceParameterName) {
this.artifactParameterName = artifactParameterName;
this.serviceParameterName = serviceParameterName;
}
private Protocol(final Protocol protocol) {
this(protocol.getArtifactParameterName(), protocol.getServiceParameterName());
}
public String getArtifactParameterName() {
return this.artifactParameterName;
}
public String getServiceParameterName() {
return this.serviceParameterName;
}
}

View File

@ -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 the following location:

View File

@ -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 the following location:
@ -96,11 +96,13 @@ public class AttributePrincipalImpl extends SimplePrincipal implements Attribute
CommonUtils.assertNotNull(this.attributes, "attributes cannot be null.");
}
@Override
public Map<String, Object> getAttributes() {
return this.attributes;
}
public String getProxyTicketFor(String service) {
@Override
public String getProxyTicketFor(final String service) {
if (proxyGrantingTicket != null) {
return this.proxyRetriever.getProxyTicketIdFor(this.proxyGrantingTicket, service);
}

View File

@ -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 the following location:
@ -18,20 +18,25 @@
*/
package org.jasig.cas.client.authentication;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.*;
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.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;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Filter implementation to intercept all requests and attempt to authenticate
* the user by redirecting them to CAS (unless the user has a ticket).
@ -41,6 +46,7 @@ import org.jasig.cas.client.validation.Assertion;
* <li><code>casServerLoginUrl</code> - the url to log into CAS, i.e. https://cas.rutgers.edu/login</li>
* <li><code>renew</code> - true/false on whether to use renew or not.</li>
* <li><code>gateway</code> - true/false on whether to use gateway or not.</li>
* <li><code>method</code> - the method used by the CAS server to send the user back to the application (redirect or post).</li>
* </ul>
*
* <p>Please see AbstractCasFilter for additional properties.</p>
@ -65,37 +71,59 @@ public class AuthenticationFilter extends AbstractCasFilter {
*/
private boolean gateway = false;
/**
* The method used by the CAS server to send the user back to the application.
*/
private String method;
private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();
private AuthenticationRedirectStrategy authenticationRedirectStrategy = new DefaultAuthenticationRedirectStrategy();
private UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass = null;
private String internalIp = null;
private static final String X_REAL_IP = "x-real-ip";
private static final Map<String, Class<? extends UrlPatternMatcherStrategy>> PATTERN_MATCHER_TYPES =
new HashMap<String, Class<? extends UrlPatternMatcherStrategy>>();
new HashMap<String, Class<? extends UrlPatternMatcherStrategy>>();
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);
}
protected AuthenticationFilter(final Protocol protocol) {
super(protocol);
}
@Override
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
if (!isIgnoreInitConfiguration()) {
super.initInternal(filterConfig);
setCasServerLoginUrl(getPropertyFromInitParams(filterConfig, "casServerLoginUrl", null));
logger.trace("Loaded CasServerLoginUrl parameter: {}", this.casServerLoginUrl);
setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
logger.trace("Loaded renew parameter: {}", this.renew);
setGateway(parseBoolean(getPropertyFromInitParams(filterConfig, "gateway", "false")));
logger.trace("Loaded gateway parameter: {}", this.gateway);
final String ignorePattern = getPropertyFromInitParams(filterConfig, "ignorePattern", null);
logger.trace("Loaded ignorePattern parameter: {}", ignorePattern);
final String ignoreUrlPatternType = getPropertyFromInitParams(filterConfig, "ignoreUrlPatternType", "REGEX");
logger.trace("Loaded ignoreUrlPatternType parameter: {}", ignoreUrlPatternType);
final String loginUrl = getString(ConfigurationKeys.CAS_SERVER_LOGIN_URL);
if (loginUrl != null) {
setCasServerLoginUrl(loginUrl);
} else {
setCasServerUrlPrefix(getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX));
}
setRenew(getBoolean(ConfigurationKeys.RENEW));
setGateway(getBoolean(ConfigurationKeys.GATEWAY));
setMethod(getString(ConfigurationKeys.METHOD));
setInternalIp(getString(ConfigurationKeys.INTERNAL_IP));
final String ignorePattern = getString(ConfigurationKeys.IGNORE_PATTERN);
final String ignoreUrlPatternType = getString(ConfigurationKeys.IGNORE_URL_PATTERN_TYPE);
if (ignorePattern != null) {
final Class<? extends UrlPatternMatcherStrategy> ignoreUrlMatcherClass = PATTERN_MATCHER_TYPES.get(ignoreUrlPatternType);
if (ignoreUrlMatcherClass != null) {
@ -112,15 +140,14 @@ public class AuthenticationFilter extends AbstractCasFilter {
this.ignoreUrlPatternMatcherStrategyClass.setPattern(ignorePattern);
}
}
final String gatewayStorageClass = getPropertyFromInitParams(filterConfig, "gatewayStorageClass", null);
final Class<? extends GatewayResolver> gatewayStorageClass = getClass(ConfigurationKeys.GATEWAY_STORAGE_CLASS);
if (gatewayStorageClass != null) {
this.gatewayStorage = ReflectUtils.newInstance(gatewayStorageClass);
setGatewayStorage(ReflectUtils.newInstance(gatewayStorageClass));
}
final String authenticationRedirectStrategyClass = getPropertyFromInitParams(filterConfig,
"authenticationRedirectStrategyClass", null);
final Class<? extends AuthenticationRedirectStrategy> authenticationRedirectStrategyClass = getClass(ConfigurationKeys.AUTHENTICATION_REDIRECT_STRATEGY_CLASS);
if (authenticationRedirectStrategyClass != null) {
this.authenticationRedirectStrategy = ReflectUtils.newInstance(authenticationRedirectStrategyClass);
@ -128,23 +155,37 @@ public class AuthenticationFilter extends AbstractCasFilter {
}
}
@Override
public void init() {
super.init();
CommonUtils.assertNotNull(this.casServerLoginUrl, "casServerLoginUrl cannot be null.");
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 FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
if (isInternalRequest(request)) {
logger.debug("Request is ignored [internal].");
filterChain.doFilter(request, response);
return;
}
if (isRequestUrlExcluded(request)) {
logger.debug("Request is ignored.");
filterChain.doFilter(request, response);
return;
}
final HttpSession session = request.getSession(false);
final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
@ -175,7 +216,7 @@ public class AuthenticationFilter extends AbstractCasFilter {
logger.debug("Constructed service url: {}", modifiedServiceUrl);
final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl,
getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
getProtocol().getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway, this.method);
logger.debug("redirecting to \"{}\"", urlToRedirectTo);
this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);
@ -189,19 +230,41 @@ public class AuthenticationFilter extends AbstractCasFilter {
this.gateway = gateway;
}
public void setMethod(final String method) {
this.method = method;
}
public final void setCasServerUrlPrefix(final String casServerUrlPrefix) {
setCasServerLoginUrl(CommonUtils.addTrailingSlash(casServerUrlPrefix) + "login");
}
public final void setCasServerLoginUrl(final String casServerLoginUrl) {
this.casServerLoginUrl = casServerLoginUrl;
}
public void setInternalIp(String internalIp) {
this.internalIp = internalIp;
}
public final void setGatewayStorage(final GatewayResolver gatewayStorage) {
this.gatewayStorage = gatewayStorage;
}
private boolean isInternalRequest(final HttpServletRequest request) {
if (this.internalIp == null) {
return false;
}
String realIp = request.getHeader(X_REAL_IP);
return this.internalIp.equals(realIp);
}
private boolean isRequestUrlExcluded(final HttpServletRequest request) {
if (this.ignoreUrlPatternMatcherStrategyClass == null) {
return false;
}
final StringBuffer urlBuffer = request.getRequestURL();
if (request.getQueryString() != null) {
urlBuffer.append("?").append(request.getQueryString());
@ -209,4 +272,10 @@ public class AuthenticationFilter extends AbstractCasFilter {
final String requestUri = urlBuffer.toString();
return this.ignoreUrlPatternMatcherStrategyClass.matches(requestUri);
}
public final void setIgnoreUrlPatternMatcherStrategyClass(
final UrlPatternMatcherStrategy ignoreUrlPatternMatcherStrategyClass) {
this.ignoreUrlPatternMatcherStrategyClass = ignoreUrlPatternMatcherStrategyClass;
}
}

View File

@ -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 the following location:

View File

@ -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 the following location:
@ -28,10 +28,12 @@ public final class ContainsPatternUrlPatternMatcherStrategy implements UrlPatter
private String pattern;
@Override
public boolean matches(final String url) {
return url.contains(this.pattern);
}
@Override
public void setPattern(final String pattern) {
this.pattern = pattern;
}

View File

@ -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 the following location:
@ -30,8 +30,9 @@ import javax.servlet.http.HttpServletResponse;
*/
public final class DefaultAuthenticationRedirectStrategy implements AuthenticationRedirectStrategy {
@Override
public void redirect(final HttpServletRequest request, final HttpServletResponse response,
final String potentialRedirectUrl) throws IOException {
final String potentialRedirectUrl) throws IOException {
response.sendRedirect(potentialRedirectUrl);
}
}

View File

@ -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 the following location:
@ -25,6 +25,7 @@ public final class DefaultGatewayResolverImpl implements GatewayResolver {
public static final String CONST_CAS_GATEWAY = "_const_cas_gateway_";
@Override
public boolean hasGatewayedAlready(final HttpServletRequest request, final String serviceUrl) {
final HttpSession session = request.getSession(false);
@ -33,10 +34,10 @@ public final class DefaultGatewayResolverImpl implements GatewayResolver {
}
final boolean result = session.getAttribute(CONST_CAS_GATEWAY) != null;
session.removeAttribute(CONST_CAS_GATEWAY);
return result;
}
@Override
public String storeGatewayInformation(final HttpServletRequest request, final String serviceUrl) {
request.getSession(true).setAttribute(CONST_CAS_GATEWAY, "yes");
return serviceUrl;

View File

@ -0,0 +1,53 @@
/**
* 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.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A pattern matcher that looks inside the url to find the pattern, that
* is assumed to have been specified via regular expressions syntax.
* The match behavior is based on {@link Matcher#matches()}:
* Attempts to match the entire region against the pattern.
*
* @author Misagh Moayyed
* @since 3.5
*/
public final class EntireRegionRegexUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy {
private Pattern pattern;
public EntireRegionRegexUrlPatternMatcherStrategy() {
}
public EntireRegionRegexUrlPatternMatcherStrategy(final String pattern) {
this.setPattern(pattern);
}
@Override
public boolean matches(final String url) {
return this.pattern.matcher(url).matches();
}
@Override
public void setPattern(final String pattern) {
this.pattern = Pattern.compile(pattern);
}
}

View File

@ -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 the following location:
@ -28,11 +28,19 @@ package org.jasig.cas.client.authentication;
public final class ExactUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy {
private String pattern;
public ExactUrlPatternMatcherStrategy() {}
public ExactUrlPatternMatcherStrategy(final String pattern) {
this.setPattern(pattern);
}
@Override
public boolean matches(final String url) {
return url.equals(this.pattern);
}
@Override
public void setPattern(final String pattern) {
this.pattern = pattern;
}

View File

@ -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 the following location:
@ -34,8 +34,9 @@ public final class FacesCompatibleAuthenticationRedirectStrategy implements Auth
private static final String FACES_PARTIAL_AJAX_PARAMETER = "javax.faces.partial.ajax";
@Override
public void redirect(final HttpServletRequest request, final HttpServletResponse response,
final String potentialRedirectUrl) throws IOException {
final String potentialRedirectUrl) throws IOException {
if (CommonUtils.isNotBlank(request.getParameter(FACES_PARTIAL_AJAX_PARAMETER))) {
// this is an ajax request - redirect ajaxly

View File

@ -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 the following location:

View File

@ -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 the following location:
@ -18,23 +18,39 @@
*/
package org.jasig.cas.client.authentication;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A pattern matcher that looks inside the url to find the pattern,. that
* A pattern matcher that looks inside the url to find the pattern, that
* is assumed to have been specified via regular expressions syntax.
*
* The match behavior is based on {@link Matcher#find()}:
* Attempts to find the next subsequence of the input sequence that matches
* the pattern. This method starts at the beginning of this matcher's region, or, if
* a previous invocation of the method was successful and the matcher has
* not since been reset, at the first character not matched by the previous
* match.
*
* @author Misagh Moayyed
* @since 3.3.1
*/
public final class RegexUrlPatternMatcherStrategy implements UrlPatternMatcherStrategy {
private Pattern pattern;
public RegexUrlPatternMatcherStrategy() {
}
public RegexUrlPatternMatcherStrategy(final String pattern) {
this.setPattern(pattern);
}
@Override
public boolean matches(final String url) {
return this.pattern.matcher(url).find();
}
@Override
public void setPattern(final String pattern) {
this.pattern = Pattern.compile(pattern);
}

View File

@ -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 the following location:
@ -49,18 +49,22 @@ public final class SimpleGroup extends SimplePrincipal implements Group {
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<? extends Principal> members() {
return Collections.enumeration(this.members);
}
@Override
public boolean removeMember(final Principal user) {
return this.members.remove(user);
}

View File

@ -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 the following location:
@ -47,6 +47,7 @@ public class SimplePrincipal implements Principal, Serializable {
CommonUtils.assertNotNull(this.name, "name cannot be null.");
}
@Override
public final String getName() {
return this.name;
}

View File

@ -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 the following location:

View File

@ -0,0 +1,121 @@
/**
* 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.util.CommonUtils;
import org.jasig.cas.client.util.ReflectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base class to provide most of the boiler-plate code (i.e. checking for proper values, returning defaults, etc.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public abstract class BaseConfigurationStrategy implements ConfigurationStrategy {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public final boolean getBoolean(final ConfigurationKey<Boolean> configurationKey) {
return getValue(configurationKey, new Parser<Boolean>() {
@Override
public Boolean parse(final String value) {
return CommonUtils.toBoolean(value);
}
});
}
@Override
public final long getLong(final ConfigurationKey<Long> configurationKey) {
return getValue(configurationKey, new Parser<Long>() {
@Override
public Long parse(final String value) {
return CommonUtils.toLong(value, configurationKey.getDefaultValue());
}
});
}
@Override
public final int getInt(final ConfigurationKey<Integer> configurationKey) {
return getValue(configurationKey, new Parser<Integer>() {
@Override
public Integer parse(final String value) {
return CommonUtils.toInt(value, configurationKey.getDefaultValue());
}
});
}
@Override
public final String getString(final ConfigurationKey<String> configurationKey) {
return getValue(configurationKey, new Parser<String>() {
@Override
public String parse(final String value) {
return value;
}
});
}
@Override
public <T> Class<? extends T> getClass(final ConfigurationKey<Class<? extends T>> configurationKey) {
return getValue(configurationKey, new Parser<Class<? extends T>>() {
@Override
public Class<? extends T> parse(final String value) {
try {
return ReflectUtils.loadClass(value);
} catch (final IllegalArgumentException e) {
return configurationKey.getDefaultValue();
}
}
});
}
private <T> T getValue(final ConfigurationKey<T> configurationKey, final Parser<T> parser) {
final String value = getWithCheck(configurationKey);
if (CommonUtils.isBlank(value)) {
logger.trace("No value found for property {}, returning default {}", configurationKey.getName(), configurationKey.getDefaultValue());
return configurationKey.getDefaultValue();
} else {
logger.trace("Loaded property {} with value {}", configurationKey.getName(), configurationKey.getDefaultValue());
}
return parser.parse(value);
}
private String getWithCheck(final ConfigurationKey configurationKey) {
CommonUtils.assertNotNull(configurationKey, "configurationKey cannot be null");
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> {
T parse(String value);
}
}

View File

@ -0,0 +1,68 @@
/**
* 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.util.CommonUtils;
/**
* Holder class to represent a particular configuration key and its optional default value.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class ConfigurationKey<E> {
private final String name;
private final E defaultValue;
public ConfigurationKey(final String name) {
this(name, null);
}
public ConfigurationKey(final String name, final E defaultValue) {
CommonUtils.assertNotNull(name, "name must not be null.");
this.name = name;
this.defaultValue = defaultValue;
}
/**
* The referencing name of the configuration key (i.e. what you would use to look it up in your configuration strategy)
*
* @return the name. MUST NOT BE NULL.
*/
public String getName() {
return this.name;
}
/**
* The (optional) default value to use when this configuration key is not set. If a value is provided it should be used. A <code>null</code> value indicates that there is no default.
*
* @return the default value or null.
*/
public E getDefaultValue() {
return this.defaultValue;
}
@Override
public String toString() {
return getName();
}
}

View File

@ -0,0 +1,86 @@
/**
* 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<String> ARTIFACT_PARAMETER_NAME = new ConfigurationKey<String>("artifactParameterName", Protocol.CAS2.getArtifactParameterName());
ConfigurationKey<String> SERVER_NAME = new ConfigurationKey<String>("serverName", null);
ConfigurationKey<String> SERVICE = new ConfigurationKey<String>("service");
ConfigurationKey<Boolean> RENEW = new ConfigurationKey<Boolean>("renew", Boolean.FALSE);
ConfigurationKey<String> LOGOUT_PARAMETER_NAME = new ConfigurationKey<String>("logoutParameterName", "logoutRequest");
ConfigurationKey<Boolean> ARTIFACT_PARAMETER_OVER_POST = new ConfigurationKey<Boolean>("artifactParameterOverPost", Boolean.FALSE);
ConfigurationKey<Boolean> EAGERLY_CREATE_SESSIONS = new ConfigurationKey<Boolean>("eagerlyCreateSessions", Boolean.TRUE);
ConfigurationKey<Boolean> ENCODE_SERVICE_URL = new ConfigurationKey<Boolean>("encodeServiceUrl", Boolean.TRUE);
ConfigurationKey<String> SSL_CONFIG_FILE = new ConfigurationKey<String>("sslConfigFile", null);
ConfigurationKey<String> ROLE_ATTRIBUTE = new ConfigurationKey<String>("roleAttribute", null);
ConfigurationKey<Boolean> IGNORE_CASE = new ConfigurationKey<Boolean>("ignoreCase", Boolean.FALSE);
ConfigurationKey<String> CAS_SERVER_LOGIN_URL = new ConfigurationKey<String>("casServerLoginUrl", null);
ConfigurationKey<Boolean> GATEWAY = new ConfigurationKey<Boolean>("gateway", Boolean.FALSE);
ConfigurationKey<String> METHOD = new ConfigurationKey<String>("method", null);
ConfigurationKey<Class<? extends AuthenticationRedirectStrategy>> AUTHENTICATION_REDIRECT_STRATEGY_CLASS = new ConfigurationKey<Class<? extends AuthenticationRedirectStrategy>>("authenticationRedirectStrategyClass", null);
ConfigurationKey<Class<? extends GatewayResolver>> GATEWAY_STORAGE_CLASS = new ConfigurationKey<Class<? extends GatewayResolver>>("gatewayStorageClass", DefaultGatewayResolverImpl.class);
ConfigurationKey<String> CAS_SERVER_URL_PREFIX = new ConfigurationKey<String>("casServerUrlPrefix", null);
ConfigurationKey<String> ENCODING = new ConfigurationKey<String>("encoding", null);
ConfigurationKey<Long> TOLERANCE = new ConfigurationKey<Long>("tolerance", 1000L);
ConfigurationKey<String> PRIVATE_KEY_PATH = new ConfigurationKey<String>("privateKeyPath", null);
ConfigurationKey<String> PRIVATE_KEY_ALGORITHM = new ConfigurationKey<String>("privateKeyAlgorithm", "RSA");
/**
* @deprecated As of 3.4. This constant is not used by the client and will
* be removed in future versions.
*/
@Deprecated
ConfigurationKey<Boolean> DISABLE_XML_SCHEMA_VALIDATION = new ConfigurationKey<Boolean>("disableXmlSchemaValidation", Boolean.FALSE);
ConfigurationKey<String> INTERNAL_IP = new ConfigurationKey<String>("internalIp", null);
ConfigurationKey<String> IGNORE_PATTERN = new ConfigurationKey<String>("ignorePattern", null);
ConfigurationKey<String> IGNORE_URL_PATTERN_TYPE = new ConfigurationKey<String>("ignoreUrlPatternType", "REGEX");
ConfigurationKey<Class<? extends HostnameVerifier>> HOSTNAME_VERIFIER = new ConfigurationKey<Class<? extends HostnameVerifier>>("hostnameVerifier", null);
ConfigurationKey<String> HOSTNAME_VERIFIER_CONFIG = new ConfigurationKey<String>("hostnameVerifierConfig", null);
ConfigurationKey<Boolean> EXCEPTION_ON_VALIDATION_FAILURE = new ConfigurationKey<Boolean>("exceptionOnValidationFailure", Boolean.TRUE);
ConfigurationKey<Boolean> REDIRECT_AFTER_VALIDATION = new ConfigurationKey<Boolean>("redirectAfterValidation", Boolean.TRUE);
ConfigurationKey<Boolean> USE_SESSION = new ConfigurationKey<Boolean>("useSession", Boolean.TRUE);
ConfigurationKey<String> SECRET_KEY = new ConfigurationKey<String>("secretKey", null);
ConfigurationKey<String> CIPHER_ALGORITHM = new ConfigurationKey<String>("cipherAlgorithm", "DESede");
ConfigurationKey<String> PROXY_RECEPTOR_URL = new ConfigurationKey<String>("proxyReceptorUrl", null);
ConfigurationKey<Class<? extends ProxyGrantingTicketStorage>> PROXY_GRANTING_TICKET_STORAGE_CLASS = new ConfigurationKey<Class<? extends ProxyGrantingTicketStorage>>("proxyGrantingTicketStorageClass", ProxyGrantingTicketStorageImpl.class);
ConfigurationKey<Integer> MILLIS_BETWEEN_CLEAN_UPS = new ConfigurationKey<Integer>("millisBetweenCleanUps", 60000);
ConfigurationKey<Boolean> ACCEPT_ANY_PROXY = new ConfigurationKey<Boolean>("acceptAnyProxy", Boolean.FALSE);
ConfigurationKey<String> ALLOWED_PROXY_CHAINS = new ConfigurationKey<String>("allowedProxyChains", null);
ConfigurationKey<Class<? extends Cas20ServiceTicketValidator>> TICKET_VALIDATOR_CLASS = new ConfigurationKey<Class<? extends Cas20ServiceTicketValidator>>("ticketValidatorClass", null);
ConfigurationKey<String> PROXY_CALLBACK_URL = new ConfigurationKey<String>("proxyCallbackUrl", null);
ConfigurationKey<String> RELAY_STATE_PARAMETER_NAME = new ConfigurationKey<String>("relayStateParameterName", "RelayState");
ConfigurationKey<String> LOGOUT_CALLBACK_PATH = new ConfigurationKey<String>("logoutCallbackPath", null);
}

View File

@ -0,0 +1,79 @@
/**
* 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 javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Abstraction to allow for pluggable methods for retrieving filter configuration.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public interface ConfigurationStrategy {
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
boolean getBoolean(ConfigurationKey<Boolean> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
String getString(ConfigurationKey<String> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
long getLong(ConfigurationKey<Long> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
int getInt(ConfigurationKey<Integer> configurationKey);
/**
* Retrieves the value for the provided {@param configurationKey}, falling back to the {@param configurationKey}'s {@link ConfigurationKey#getDefaultValue()} if nothing can be found.
*
* @param configurationKey the configuration key. MUST NOT BE NULL.
* @return the configured value, or the default value.
*/
<T> Class<? extends T> getClass(ConfigurationKey<Class<? extends T>> configurationKey);
/**
* Initializes the strategy. This must be called before calling any of the "get" methods.
*
* @param filterConfig the filter configuration object.
* @param filterClazz the filter
*/
void init(FilterConfig filterConfig, Class<? extends Filter> filterClazz);
}

View File

@ -0,0 +1,74 @@
/**
* 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.util.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Enumeration to map simple names to the underlying classes so that deployers can reference the simple name in the
* <code>web.xml</code> instead of the fully qualified class name.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public enum ConfigurationStrategyName {
DEFAULT(LegacyConfigurationStrategyImpl.class), JNDI(JndiConfigurationStrategyImpl.class), WEB_XML(WebXmlConfigurationStrategyImpl.class),
PROPERTY_FILE(PropertiesConfigurationStrategyImpl.class), SYSTEM_PROPERTIES(SystemPropertiesConfigurationStrategyImpl.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationStrategyName.class);
private final Class<? extends ConfigurationStrategy> configurationStrategyClass;
private ConfigurationStrategyName(final Class<? extends ConfigurationStrategy> configurationStrategyClass) {
this.configurationStrategyClass = configurationStrategyClass;
}
/**
* Static helper method that will resolve a simple string to either an enum value or a {@link org.jasig.cas.client.configuration.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).
*/
public static Class<? extends ConfigurationStrategy> resolveToConfigurationStrategy(final String value) {
if (CommonUtils.isBlank(value)) {
return DEFAULT.configurationStrategyClass;
}
for (final ConfigurationStrategyName csn : values()) {
if (csn.name().equalsIgnoreCase(value)) {
return csn.configurationStrategyClass;
}
}
try {
final Class<?> clazz = Class.forName(value);
if (ConfigurationStrategy.class.isAssignableFrom(clazz)) {
return (Class<? extends ConfigurationStrategy>) clazz;
}
} catch (final ClassNotFoundException e) {
LOGGER.error("Unable to locate strategy {} by name or class name. Using default strategy instead.", value, e);
}
return DEFAULT.configurationStrategyClass;
}
}

View File

@ -0,0 +1,94 @@
/**
* 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.util.CommonUtils;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Loads configuration information from JNDI, using the <code>defaultValue</code> if it can't.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public class JndiConfigurationStrategyImpl extends BaseConfigurationStrategy {
private static final String ENVIRONMENT_PREFIX = "java:comp/env/cas/";
private final String environmentPrefix;
private InitialContext context;
private String simpleFilterName;
public JndiConfigurationStrategyImpl() {
this(ENVIRONMENT_PREFIX);
}
public JndiConfigurationStrategyImpl(final String environmentPrefix) {
this.environmentPrefix = environmentPrefix;
}
@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);
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);
if (CommonUtils.isNotBlank(rootValue)) {
logger.info("Property [{}] loaded from JNDI with value [{}]", propertyName, rootValue);
return rootValue;
}
return null;
}
private 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<? extends Filter> 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);
}
}
}

View File

@ -0,0 +1,55 @@
/**
* 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.util.CommonUtils;
import javax.servlet.Filter;
import javax.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 <code>defaultValue</code>.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class LegacyConfigurationStrategyImpl extends BaseConfigurationStrategy {
private final WebXmlConfigurationStrategyImpl webXmlConfigurationStrategy = new WebXmlConfigurationStrategyImpl();
private final JndiConfigurationStrategyImpl jndiConfigurationStrategy = new JndiConfigurationStrategyImpl();
@Override
public void init(final FilterConfig filterConfig, final Class<? extends Filter> filterClazz) {
this.webXmlConfigurationStrategy.init(filterConfig, filterClazz);
this.jndiConfigurationStrategy.init(filterConfig, filterClazz);
}
@Override
protected String get(final ConfigurationKey key) {
final String value1 = this.webXmlConfigurationStrategy.get(key);
if (CommonUtils.isNotBlank(value1)) {
return value1;
}
return this.jndiConfigurationStrategy.get(key);
}
}

View File

@ -0,0 +1,101 @@
/**
* 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.util.CommonUtils;
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;
/**
* @author Scott Battaglia
* @since 3.4.0
*/
public final class PropertiesConfigurationStrategyImpl extends BaseConfigurationStrategy {
/**
* Property name we'll use in the {@link javax.servlet.FilterConfig} and {@link javax.servlet.ServletConfig} to try and find where
* you stored the configuration file.
*/
private static final String CONFIGURATION_FILE_LOCATION = "configFileLocation";
/**
* Default location of the configuration file. Mostly for testing/demo. You will most likely want to configure an alternative location.
*/
private static final String DEFAULT_CONFIGURATION_FILE_LOCATION = "/etc/java-cas-client.properties";
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);
}
@Override
public void init(final FilterConfig filterConfig, final Class<? extends Filter> filterClazz) {
this.simpleFilterName = filterClazz.getSimpleName();
final String fileLocationFromFilterConfig = filterConfig.getInitParameter(CONFIGURATION_FILE_LOCATION);
final boolean filterConfigFileLoad = loadPropertiesFromFile(fileLocationFromFilterConfig);
if (!filterConfigFileLoad) {
final String fileLocationFromServletConfig = filterConfig.getServletContext().getInitParameter(CONFIGURATION_FILE_LOCATION);
final boolean servletContextFileLoad = loadPropertiesFromFile(fileLocationFromServletConfig);
if (!servletContextFileLoad) {
final boolean defaultConfigFileLoaded = loadPropertiesFromFile(DEFAULT_CONFIGURATION_FILE_LOCATION);
CommonUtils.assertTrue(defaultConfigFileLoaded, "unable to load properties to configure CAS client");
}
}
}
private boolean loadPropertiesFromFile(final String file) {
if (CommonUtils.isEmpty(file)) {
return false;
}
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
this.properties.load(fis);
return true;
} catch (final IOException e) {
LOGGER.warn("Unable to load properties for file {}", file, e);
return false;
} finally {
CommonUtils.closeQuietly(fis);
}
}
}

View File

@ -0,0 +1,40 @@
/**
* 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 javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Load all configuration from system properties.
*
* @author Jerome Leleu
* @since 3.4.0
*/
public class SystemPropertiesConfigurationStrategyImpl extends BaseConfigurationStrategy {
@Override
public void init(final FilterConfig filterConfig, final Class<? extends Filter> filterClazz) {
}
@Override
protected String get(final ConfigurationKey configurationKey) {
return System.getProperty(configurationKey.getName());
}
}

View File

@ -0,0 +1,62 @@
/**
* 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.util.CommonUtils;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
/**
* Implementation of the {@link org.jasig.cas.client.configuration.ConfigurationStrategy} that first checks the {@link javax.servlet.FilterConfig} and
* then checks the {@link javax.servlet.ServletContext}, ultimately falling back to the <code>defaultValue</code>.
*
* @author Scott Battaglia
* @since 3.4.0
*/
public final class WebXmlConfigurationStrategyImpl extends BaseConfigurationStrategy {
private FilterConfig filterConfig;
@Override
protected String get(final ConfigurationKey configurationKey) {
final String 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.");
logger.info("Property [{}] loaded from FilterConfig.getInitParameter with value [{}]", configurationKey, value);
return value;
}
final String value2 = filterConfig.getServletContext().getInitParameter(configurationKey.getName());
if (CommonUtils.isNotBlank(value2)) {
logger.info("Property [{}] loaded from ServletContext.getInitParameter with value [{}]", configurationKey,
value2);
return value2;
}
return null;
}
@Override
public void init(final FilterConfig filterConfig, final Class<? extends Filter> clazz) {
this.filterConfig = filterConfig;
}
}

View File

@ -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 the following location:
@ -36,7 +36,7 @@ public class AssertionPrincipal extends SimplePrincipal implements Serializable
private static final long serialVersionUID = 2288520214366461693L;
/** CAS assertion describing authenticated state */
private Assertion assertion;
private final Assertion assertion;
/**
* Creates a new principal containing the CAS assertion.

View File

@ -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 the following location:
@ -162,7 +162,7 @@ public class CasLoginModule implements LoginModule {
protected String[] defaultRoles;
/** Names of attributes in the CAS assertion that should be used for role data */
protected Set<String> roleAttributeNames = new HashSet<String>();
protected final Set<String> roleAttributeNames = new HashSet<String>();
/** Name of JAAS Group containing caller principal */
protected String principalGroupName = DEFAULT_PRINCIPAL_GROUP_NAME;
@ -203,8 +203,9 @@ public class CasLoginModule implements LoginModule {
* names, e.g. DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS. Default unit is MINUTES.</li>
* </ul>
*/
@Override
public final void initialize(final Subject subject, final CallbackHandler handler, final Map<String, ?> state,
final Map<String, ?> options) {
final Map<String, ?> options) {
this.assertion = null;
this.callbackHandler = handler;
@ -277,6 +278,7 @@ public class CasLoginModule implements LoginModule {
// template method
}
@Override
public final boolean login() throws LoginException {
logger.debug("Performing login.");
@ -292,10 +294,10 @@ public class CasLoginModule implements LoginModule {
try {
this.callbackHandler.handle(new Callback[] { ticketCallback, serviceCallback });
} catch (final IOException e) {
logger.info("Login failed due to IO exception in callback handler: {}", 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);
logger.info("Login failed due to unsupported callback", e);
throw (LoginException) new LoginException(
"Callback handler does not support PasswordCallback and TextInputCallback.").initCause(e);
}
@ -325,7 +327,7 @@ public class CasLoginModule implements LoginModule {
this.assertion = this.ticketValidator.validate(this.ticket.getName(), service);
} catch (final Exception e) {
logger.info("Login failed due to CAS ticket validation failure: {}", e);
logger.info("Login failed due to CAS ticket validation failure", e);
throw (LoginException) new LoginException("CAS ticket validation failed: " + e).initCause(e);
}
}
@ -341,6 +343,7 @@ public class CasLoginModule implements LoginModule {
return result;
}
@Override
public final boolean abort() throws LoginException {
if (this.ticket != null) {
this.ticket = null;
@ -369,6 +372,7 @@ public class CasLoginModule implements LoginModule {
// template method
}
@Override
public final boolean commit() throws LoginException {
if (!preCommit()) {
@ -439,6 +443,7 @@ public class CasLoginModule implements LoginModule {
return result;
}
@Override
public final boolean logout() throws LoginException {
logger.debug("Performing logout.");

View File

@ -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 the following location:
@ -50,6 +50,7 @@ public class ServiceAndTicketCallbackHandler implements CallbackHandler {
this.ticket = ticket;
}
@Override
public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (final Callback callback : callbacks) {
if (callback instanceof NameCallback) {

View File

@ -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 the following location:
@ -29,6 +29,7 @@ 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.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
@ -50,12 +51,17 @@ import org.jasig.cas.client.util.CommonUtils;
*/
public final class Servlet3AuthenticationFilter extends AbstractCasFilter {
public Servlet3AuthenticationFilter() {
super(Protocol.CAS2);
}
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain chain) throws IOException, ServletException {
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, getArtifactParameterName());
final String ticket = CommonUtils.safeGetParameter(request, getProtocol().getArtifactParameterName());
if (session != null && session.getAttribute(CONST_CAS_ASSERTION) == null && ticket != null) {
try {

View File

@ -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 the following location:
@ -34,7 +34,7 @@ public final class TicketCredential implements Principal {
private static final int HASHCODE_SEED = 17;
/** Ticket ID string */
private String ticket;
private final String ticket;
/**
* Creates a new instance that wraps the given ticket.
@ -44,6 +44,7 @@ public final class TicketCredential implements Principal {
this.ticket = ticket;
}
@Override
public String getName() {
return this.ticket;
}
@ -52,7 +53,7 @@ public final class TicketCredential implements Principal {
return this.ticket;
}
public boolean equals(Object o) {
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())

View File

@ -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 the following location:
@ -18,6 +18,8 @@
*/
package org.jasig.cas.client.proxy;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
@ -36,11 +38,9 @@ import javax.crypto.spec.DESedeKeySpec;
*/
public abstract class AbstractEncryptedProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage {
public static final String DEFAULT_ENCRYPTION_ALGORITHM = "DESede";
private Key key;
private String cipherAlgorithm = DEFAULT_ENCRYPTION_ALGORITHM;
private String cipherAlgorithm = ConfigurationKeys.CIPHER_ALGORITHM.getDefaultValue();
public final void setSecretKey(final String key) throws NoSuchAlgorithmException, InvalidKeyException,
InvalidKeySpecException {
@ -60,10 +60,12 @@ public abstract class AbstractEncryptedProxyGrantingTicketStorageImpl implements
this.cipherAlgorithm = cipherAlgorithm;
}
@Override
public final void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) {
saveInternal(proxyGrantingTicketIou, encrypt(proxyGrantingTicket));
}
@Override
public final String retrieve(final String proxyGrantingTicketIou) {
return decrypt(retrieveInternal(proxyGrantingTicketIou));
}

View File

@ -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 the following location:
@ -75,6 +75,7 @@ public final class Cas20ProxyRetriever implements ProxyRetriever {
this.urlConnectionFactory = urlFactory;
}
@Override
public String getProxyTicketIdFor(final String proxyGrantingTicketId, final String targetService) {
CommonUtils.assertNotNull(proxyGrantingTicketId, "proxyGrantingTicketId cannot be null.");
CommonUtils.assertNotNull(targetService, "targetService cannot be null.");
@ -94,7 +95,9 @@ public final class Cas20ProxyRetriever implements ProxyRetriever {
return null;
}
return XmlUtils.getTextForElement(response, "proxyTicket");
final String ticket = XmlUtils.getTextForElement(response, "proxyTicket");
logger.debug("Got proxy ticket {}", ticket);
return ticket;
}
private URL constructUrl(final String proxyGrantingTicketId, final String targetService) {

View File

@ -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 the following location:
@ -39,6 +39,7 @@ public final class CleanUpTimerTask extends TimerTask {
this.proxyGrantingTicketStorage = proxyGrantingTicketStorage;
}
@Override
public void run() {
this.proxyGrantingTicketStorage.cleanUp();
}

View File

@ -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 the following location:
@ -23,7 +23,6 @@ package org.jasig.cas.client.proxy;
* them to a specific ProxyGrantingTicketIou.
*
* @author Scott Battaglia
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public interface ProxyGrantingTicketStorage {

View File

@ -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 the following location:
@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
*
* @author Scott Battaglia
* @author Brad Cupit (brad [at] lsu {dot} edu)
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public final class ProxyGrantingTicketStorageImpl implements ProxyGrantingTicketStorage {
@ -57,7 +56,7 @@ public final class ProxyGrantingTicketStorageImpl implements ProxyGrantingTicket
*
* @see ProxyGrantingTicketStorageImpl#DEFAULT_TIMEOUT
*/
private long timeout;
private final long timeout;
/**
* Constructor set the timeout to the default value.
@ -80,6 +79,7 @@ public final class ProxyGrantingTicketStorageImpl implements ProxyGrantingTicket
* NOTE: you can only retrieve a ProxyGrantingTicket once with this method.
* Its removed after retrieval.
*/
@Override
public String retrieve(final String proxyGrantingTicketIou) {
if (CommonUtils.isBlank(proxyGrantingTicketIou)) {
return null;
@ -98,6 +98,7 @@ public final class ProxyGrantingTicketStorageImpl implements ProxyGrantingTicket
return holder.getProxyGrantingTicket();
}
@Override
public void save(final String proxyGrantingTicketIou, final String proxyGrantingTicket) {
final ProxyGrantingTicketHolder holder = new ProxyGrantingTicketHolder(proxyGrantingTicket);
@ -110,6 +111,7 @@ public final class ProxyGrantingTicketStorageImpl implements ProxyGrantingTicket
* 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<String, ProxyGrantingTicketHolder> holder : this.cache.entrySet()) {
if (holder.getValue().isExpired(this.timeout)) {

View File

@ -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 the following location:
@ -25,7 +25,6 @@ import java.io.Serializable;
* implementation a black box to the client.
*
* @author Scott Battaglia
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public interface ProxyRetriever extends Serializable {

View File

@ -1,9 +1,9 @@
<!--
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:

View File

@ -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 the following location:
@ -46,12 +46,14 @@ public final class HashMapBackedSessionMappingStorage implements SessionMappingS
private final Logger logger = LoggerFactory.getLogger(getClass());
public synchronized void addSessionById(String mappingId, HttpSession session) {
@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);
}
@Override
public synchronized void removeBySessionById(final String sessionId) {
logger.debug("Attempting to remove Session=[{}]", sessionId);
@ -68,7 +70,8 @@ public final class HashMapBackedSessionMappingStorage implements SessionMappingS
ID_TO_SESSION_KEY_MAPPING.remove(sessionId);
}
public synchronized HttpSession removeSessionByMappingId(String mappingId) {
@Override
public synchronized HttpSession removeSessionByMappingId(final String mappingId) {
final HttpSession session = MANAGED_SESSIONS.get(mappingId);
if (session != null) {

View File

@ -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 the following location:

View File

@ -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 the following location:
@ -22,8 +22,10 @@ import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jasig.cas.client.configuration.ConfigurationKeys;
import org.jasig.cas.client.util.AbstractConfigurationFilter;
/**
@ -37,23 +39,18 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter {
private static final SingleSignOutHandler HANDLER = new SingleSignOutHandler();
private AtomicBoolean handlerInitialized = new AtomicBoolean(false);
private final AtomicBoolean handlerInitialized = new AtomicBoolean(false);
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
if (!isIgnoreInitConfiguration()) {
HANDLER.setArtifactParameterName(getPropertyFromInitParams(filterConfig, "artifactParameterName",
SingleSignOutHandler.DEFAULT_ARTIFACT_PARAMETER_NAME));
HANDLER.setLogoutParameterName(getPropertyFromInitParams(filterConfig, "logoutParameterName",
SingleSignOutHandler.DEFAULT_LOGOUT_PARAMETER_NAME));
HANDLER.setFrontLogoutParameterName(getPropertyFromInitParams(filterConfig, "frontLogoutParameterName",
SingleSignOutHandler.DEFAULT_FRONT_LOGOUT_PARAMETER_NAME));
HANDLER.setRelayStateParameterName(getPropertyFromInitParams(filterConfig, "relayStateParameterName",
SingleSignOutHandler.DEFAULT_RELAY_STATE_PARAMETER_NAME));
HANDLER.setCasServerUrlPrefix(getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", ""));
HANDLER.setArtifactParameterOverPost(parseBoolean(getPropertyFromInitParams(filterConfig,
"artifactParameterOverPost", "false")));
HANDLER.setEagerlyCreateSessions(parseBoolean(getPropertyFromInitParams(filterConfig,
"eagerlyCreateSessions", "true")));
setArtifactParameterName(getString(ConfigurationKeys.ARTIFACT_PARAMETER_NAME));
setLogoutParameterName(getString(ConfigurationKeys.LOGOUT_PARAMETER_NAME));
setRelayStateParameterName(getString(ConfigurationKeys.RELAY_STATE_PARAMETER_NAME));
setLogoutCallbackPath(getString(ConfigurationKeys.LOGOUT_CALLBACK_PATH));
HANDLER.setArtifactParameterOverPost(getBoolean(ConfigurationKeys.ARTIFACT_PARAMETER_OVER_POST));
HANDLER.setEagerlyCreateSessions(getBoolean(ConfigurationKeys.EAGERLY_CREATE_SESSIONS));
}
HANDLER.init();
handlerInitialized.set(true);
@ -66,25 +63,22 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter {
public void setLogoutParameterName(final String name) {
HANDLER.setLogoutParameterName(name);
}
public void setFrontLogoutParameterName(final String name) {
HANDLER.setFrontLogoutParameterName(name);
}
public void setRelayStateParameterName(final String name) {
HANDLER.setRelayStateParameterName(name);
}
public void setCasServerUrlPrefix(final String casServerUrlPrefix) {
HANDLER.setCasServerUrlPrefix(casServerUrlPrefix);
public void setLogoutCallbackPath(final String logoutCallbackPath) {
HANDLER.setLogoutCallbackPath(logoutCallbackPath);
}
public 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 FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
@ -101,6 +95,7 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter {
}
}
@Override
public void destroy() {
// nothing to do
}

View File

@ -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 the following location:
@ -19,6 +19,7 @@
package org.jasig.cas.client.session;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.zip.Inflater;
@ -26,9 +27,10 @@ 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 org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
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;
@ -44,11 +46,6 @@ import org.slf4j.LoggerFactory;
*/
public final class SingleSignOutHandler {
public final static String DEFAULT_ARTIFACT_PARAMETER_NAME = "ticket";
public final static String DEFAULT_LOGOUT_PARAMETER_NAME = "logoutRequest";
public final static String DEFAULT_FRONT_LOGOUT_PARAMETER_NAME = "SAMLRequest";
public final static String DEFAULT_RELAY_STATE_PARAMETER_NAME = "RelayState";
private final static int DECOMPRESSION_FACTOR = 10;
/** Logger instance */
@ -58,19 +55,16 @@ public final class SingleSignOutHandler {
private SessionMappingStorage sessionMappingStorage = new HashMapBackedSessionMappingStorage();
/** The name of the artifact parameter. This is used to capture the session identifier. */
private String artifactParameterName = DEFAULT_ARTIFACT_PARAMETER_NAME;
private String artifactParameterName = Protocol.CAS2.getArtifactParameterName();
/** Parameter name that stores logout request for back channel SLO */
private String logoutParameterName = DEFAULT_LOGOUT_PARAMETER_NAME;
/** Parameter name that stores logout request for front channel SLO */
private String frontLogoutParameterName = DEFAULT_FRONT_LOGOUT_PARAMETER_NAME;
/** Parameter name that stores the state of the CAS server webflow for the callback */
private String relayStateParameterName = DEFAULT_RELAY_STATE_PARAMETER_NAME;
/** Parameter name that stores logout request for SLO */
private String logoutParameterName = ConfigurationKeys.LOGOUT_PARAMETER_NAME.getDefaultValue();
/** The prefix url of the CAS server */
private String casServerUrlPrefix = "";
/** Parameter name that stores the state of the CAS server webflow for the callback */
private String relayStateParameterName = ConfigurationKeys.RELAY_STATE_PARAMETER_NAME.getDefaultValue();
/** The logout callback path configured at the CAS server, if there is one */
private String logoutCallbackPath;
private boolean artifactParameterOverPost = false;
@ -78,7 +72,7 @@ public final class SingleSignOutHandler {
private List<String> safeParameters;
private LogoutStrategy logoutStrategy = isServlet30() ? new Servlet30LogoutStrategy() : new Servlet25LogoutStrategy();
private final LogoutStrategy logoutStrategy = isServlet30() ? new Servlet30LogoutStrategy() : new Servlet25LogoutStrategy();
public void setSessionMappingStorage(final SessionMappingStorage storage) {
this.sessionMappingStorage = storage;
@ -100,24 +94,17 @@ public final class SingleSignOutHandler {
}
/**
* @param name Name of parameter containing CAS logout request message for back channel SLO.
* @param name Name of parameter containing CAS logout request message for SLO.
*/
public void setLogoutParameterName(final String name) {
this.logoutParameterName = name;
}
/**
* @param casServerUrlPrefix The prefix url of the CAS server.
* @param logoutCallbackPath The logout callback path configured at the CAS server.
*/
public void setCasServerUrlPrefix(final String casServerUrlPrefix) {
this.casServerUrlPrefix = casServerUrlPrefix;
}
/**
* @param name Name of parameter containing CAS logout request message for front channel SLO.
*/
public void setFrontLogoutParameterName(final String name) {
this.frontLogoutParameterName = name;
public void setLogoutCallbackPath(final String logoutCallbackPath) {
this.logoutCallbackPath = logoutCallbackPath;
}
/**
@ -138,19 +125,13 @@ public final class SingleSignOutHandler {
if (this.safeParameters == null) {
CommonUtils.assertNotNull(this.artifactParameterName, "artifactParameterName cannot be null.");
CommonUtils.assertNotNull(this.logoutParameterName, "logoutParameterName cannot be null.");
CommonUtils.assertNotNull(this.frontLogoutParameterName, "frontLogoutParameterName cannot be null.");
CommonUtils.assertNotNull(this.sessionMappingStorage, "sessionMappingStorage cannot be null.");
CommonUtils.assertNotNull(this.relayStateParameterName, "relayStateParameterName cannot be null.");
CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null.");
if (CommonUtils.isBlank(this.casServerUrlPrefix)) {
logger.warn("Front Channel single sign out redirects are disabled when the 'casServerUrlPrefix' value is not set.");
}
if (this.artifactParameterOverPost) {
this.safeParameters = Arrays.asList(this.logoutParameterName, this.artifactParameterName);
} else {
this.safeParameters = Arrays.asList(this.logoutParameterName);
this.safeParameters = Collections.singletonList(this.logoutParameterName);
}
}
}
@ -168,30 +149,32 @@ public final class SingleSignOutHandler {
}
/**
* Determines whether the given request is a CAS back channel logout request.
* Determines whether the given request is a CAS logout request.
*
* @param request HTTP request.
*
* @return True if request is logout request, false otherwise.
*/
private boolean isBackChannelLogoutRequest(final HttpServletRequest request) {
return "POST".equals(request.getMethod())
&& !isMultipartRequest(request)
&& CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName,
this.safeParameters));
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));
}
if ("GET".equalsIgnoreCase(request.getMethod())) {
return CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters));
}
return false;
}
/**
* Determines whether the given request is a CAS front channel logout request. Front Channel log out requests are only supported
* when the 'casServerUrlPrefix' value is set.
*
* @param request HTTP request.
*
* @return True if request is logout request, false otherwise.
*/
private boolean isFrontChannelLogoutRequest(final HttpServletRequest request) {
return "GET".equals(request.getMethod()) && CommonUtils.isNotBlank(this.casServerUrlPrefix)
&& CommonUtils.isNotBlank(CommonUtils.safeGetParameter(request, this.frontLogoutParameterName));
private boolean pathEligibleForLogout(final HttpServletRequest request) {
return logoutCallbackPath == null || logoutCallbackPath.equals(getPath(request));
}
private String getPath(final HttpServletRequest request) {
return request.getServletPath() + CommonUtils.nullToEmpty(request.getPathInfo());
}
/**
@ -206,26 +189,15 @@ public final class SingleSignOutHandler {
logger.trace("Received a token request");
recordSession(request);
return true;
} else if (isBackChannelLogoutRequest(request)) {
logger.trace("Received a back channel logout request");
}
if (isLogoutRequest(request)) {
logger.trace("Received a logout request");
destroySession(request);
return false;
} else if (isFrontChannelLogoutRequest(request)) {
logger.trace("Received a front channel logout request");
destroySession(request);
// redirection url to the CAS server
final String redirectionUrl = computeRedirectionToServer(request);
if (redirectionUrl != null) {
CommonUtils.sendRedirect(response, redirectionUrl);
}
return false;
} else {
logger.trace("Ignoring URI for logout: {}", request.getRequestURI());
return true;
}
}
logger.trace("Ignoring URI for logout: {}", request.getRequestURI());
return true;
}
/**
@ -248,7 +220,7 @@ public final class SingleSignOutHandler {
try {
this.sessionMappingStorage.removeBySessionById(session.getId());
} catch (final Exception e) {
// ignore if the session is already marked as invalid. Nothing we can do!
// ignore if the session is already marked as invalid. Nothing we can do!
}
sessionMappingStorage.addSessionById(token, session);
}
@ -260,7 +232,7 @@ public final class SingleSignOutHandler {
* @return the uncompressed logout message.
*/
private String uncompressLogoutMessage(final String originalMessage) {
final byte[] binaryMessage = Base64.decodeBase64(originalMessage);
final byte[] binaryMessage = DatatypeConverter.parseBase64Binary(originalMessage);
Inflater decompresser = null;
try {
@ -289,23 +261,23 @@ public final class SingleSignOutHandler {
* @param request HTTP request containing a CAS logout message.
*/
private void destroySession(final HttpServletRequest request) {
final String logoutMessage;
// front channel logout -> the message needs to be base64 decoded + decompressed
if (isFrontChannelLogoutRequest(request)) {
logoutMessage = uncompressLogoutMessage(CommonUtils.safeGetParameter(request,
this.frontLogoutParameterName));
} else {
logoutMessage = CommonUtils.safeGetParameter(request, this.logoutParameterName, this.safeParameters);
String logoutMessage = CommonUtils.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");
if (CommonUtils.isNotBlank(token)) {
final HttpSession session = this.sessionMappingStorage.removeSessionByMappingId(token);
if (session != null) {
String sessionID = session.getId();
final String sessionID = session.getId();
logger.debug("Invalidating session [{}] for token [{}]", sessionID, token);
try {
@ -318,33 +290,6 @@ public final class SingleSignOutHandler {
}
}
/**
* Compute the redirection url to the CAS server when it's a front channel SLO
* (depending on the relay state parameter).
*
* @param request The HTTP request.
* @return the redirection url to the CAS server.
*/
private String computeRedirectionToServer(final HttpServletRequest request) {
final String relayStateValue = CommonUtils.safeGetParameter(request, this.relayStateParameterName);
// if we have a state value -> redirect to the CAS server to continue the logout process
if (StringUtils.isNotBlank(relayStateValue)) {
final StringBuilder buffer = new StringBuilder();
buffer.append(casServerUrlPrefix);
if (!this.casServerUrlPrefix.endsWith("/")) {
buffer.append("/");
}
buffer.append("logout?_eventId=next&");
buffer.append(this.relayStateParameterName);
buffer.append("=");
buffer.append(CommonUtils.urlEncode(relayStateValue));
final String redirectUrl = buffer.toString();
logger.debug("Redirection url to the CAS server: {}", redirectUrl);
return redirectUrl;
}
return null;
}
private boolean isMultipartRequest(final HttpServletRequest request) {
return request.getContentType() != null && request.getContentType().toLowerCase().startsWith("multipart");
}
@ -368,6 +313,7 @@ public final class SingleSignOutHandler {
private class Servlet25LogoutStrategy implements LogoutStrategy {
@Override
public void logout(final HttpServletRequest request) {
// nothing additional to do here
}
@ -375,6 +321,7 @@ public final class SingleSignOutHandler {
private class Servlet30LogoutStrategy implements LogoutStrategy {
@Override
public void logout(final HttpServletRequest request) {
try {
request.logout();

View File

@ -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 the following location:
@ -36,10 +36,12 @@ public final class SingleSignOutHttpSessionListener implements HttpSessionListen
private SessionMappingStorage sessionMappingStorage;
@Override
public void sessionCreated(final HttpSessionEvent event) {
// nothing to do at the moment
}
@Override
public void sessionDestroyed(final HttpSessionEvent event) {
if (sessionMappingStorage == null) {
sessionMappingStorage = getSessionMappingStorage();

View File

@ -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 the following location:
@ -32,6 +32,7 @@ import javax.net.ssl.SSLSession;
public final class AnyHostnameVerifier implements HostnameVerifier {
/** {@inheritDoc} */
@Override
public boolean verify(final String hostname, final SSLSession session) {
return true;
}

View File

@ -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 the following location:
@ -18,6 +18,7 @@
*/
package org.jasig.cas.client.ssl;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
@ -28,7 +29,7 @@ import java.net.URLConnection;
* @author Misagh Moayyed
* @since 3.3
*/
public interface HttpURLConnectionFactory {
public interface HttpURLConnectionFactory extends Serializable {
/**
* Receives a {@link URLConnection} instance typically as a result of a {@link URL}

View File

@ -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 the following location:
@ -18,8 +18,7 @@
*/
package org.jasig.cas.client.ssl;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.security.KeyStore;
@ -41,6 +40,8 @@ import org.slf4j.LoggerFactory;
*/
public final class HttpsURLConnectionFactory implements HttpURLConnectionFactory {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LoggerFactory.getLogger(HttpsURLConnectionFactory.class);
/**
@ -77,6 +78,7 @@ public final class HttpsURLConnectionFactory implements HttpURLConnectionFactory
this.hostnameVerifier = verifier;
}
@Override
public HttpURLConnection buildHttpURLConnection(final URLConnection url) {
return this.configureHttpsConnectionIfNeeded(url);
}
@ -146,4 +148,45 @@ public final class HttpsURLConnectionFactory implements HttpURLConnectionFactory
return null;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final HttpsURLConnectionFactory that = (HttpsURLConnectionFactory) o;
if (!hostnameVerifier.equals(that.hostnameVerifier)) return false;
if (!sslConfiguration.equals(that.sslConfiguration)) return false;
return true;
}
@Override
public int hashCode() {
int result = hostnameVerifier.hashCode();
result = 31 * result + sslConfiguration.hashCode();
return result;
}
private void writeObject(final ObjectOutputStream out) throws IOException {
if (this.hostnameVerifier == HttpsURLConnection.getDefaultHostnameVerifier()) {
out.writeObject(null);
} else {
out.writeObject(this.hostnameVerifier);
}
out.writeObject(this.sslConfiguration);
}
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
final Object internalHostNameVerifier = in.readObject();
if (internalHostNameVerifier == null) {
this.hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
} else {
this.hostnameVerifier = (HostnameVerifier) internalHostNameVerifier;
}
this.sslConfiguration = (Properties) in.readObject();
}
}

View File

@ -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 the following location:
@ -16,9 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.cas.client.ssl;
import java.io.Serializable;
import java.util.regex.Pattern;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
@ -32,10 +32,12 @@ import javax.net.ssl.SSLSession;
* @since 3.1.10
*
*/
public final class RegexHostnameVerifier implements HostnameVerifier {
public final class RegexHostnameVerifier implements HostnameVerifier, Serializable {
private static final long serialVersionUID = 1L;
/** Allowed hostname pattern */
private Pattern pattern;
private final Pattern pattern;
/**
* Creates a new instance using the given regular expression.
@ -47,6 +49,7 @@ public final class RegexHostnameVerifier implements HostnameVerifier {
}
/** {@inheritDoc} */
@Override
public boolean verify(final String hostname, final SSLSession session) {
return pattern.matcher(hostname).matches();
}

View File

@ -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 the following location:
@ -20,6 +20,7 @@ package org.jasig.cas.client.ssl;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.io.Serializable;
/**
* Verifies a SSL peer host name based on an explicit whitelist of allowed hosts.
@ -29,10 +30,12 @@ import javax.net.ssl.SSLSession;
* @since 3.1.10
*
*/
public final class WhitelistHostnameVerifier implements HostnameVerifier {
public final class WhitelistHostnameVerifier implements HostnameVerifier, Serializable {
private static final long serialVersionUID = 1L;
/** Allowed hosts */
private String[] allowedHosts;
private final String[] allowedHosts;
/**
* Creates a new instance using the given array of allowed hosts.
@ -53,6 +56,7 @@ public final class WhitelistHostnameVerifier implements HostnameVerifier {
}
/** {@inheritDoc} */
@Override
public boolean verify(final String hostname, final SSLSession session) {
for (final String allowedHost : this.allowedHosts) {

View File

@ -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 the following location:
@ -18,10 +18,14 @@
*/
package org.jasig.cas.client.util;
import org.jasig.cas.client.Protocol;
import org.jasig.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;
/**
* Abstract filter that contains code that is common to all CAS filters.
@ -42,12 +46,8 @@ 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_";
/** Defines the parameter to look for for the artifact. */
private String artifactParameterName = "ticket";
private final Protocol protocol;
/** Defines the parameter to look for for the service. */
private String serviceParameterName = "service";
/** Sets where response.encodeUrl should be called on service urls when constructed. */
private boolean encodeServiceUrl = true;
@ -59,18 +59,17 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
/** The exact url of the service. */
private String service;
protected AbstractCasFilter(final Protocol protocol) {
this.protocol = protocol;
}
@Override
public final void init(final FilterConfig filterConfig) throws ServletException {
super.init(filterConfig);
if (!isIgnoreInitConfiguration()) {
setServerName(getPropertyFromInitParams(filterConfig, "serverName", null));
logger.trace("Loading serverName property: {}", this.serverName);
setService(getPropertyFromInitParams(filterConfig, "service", null));
logger.trace("Loading service property: {}", this.service);
setArtifactParameterName(getPropertyFromInitParams(filterConfig, "artifactParameterName", "ticket"));
logger.trace("Loading artifact parameter name property: {}", this.artifactParameterName);
setServiceParameterName(getPropertyFromInitParams(filterConfig, "serviceParameterName", "service"));
logger.trace("Loading serviceParameterName property: {} ", this.serviceParameterName);
setEncodeServiceUrl(parseBoolean(getPropertyFromInitParams(filterConfig, "encodeServiceUrl", "true")));
logger.trace("Loading encodeServiceUrl property: {}", this.encodeServiceUrl);
setServerName(getString(ConfigurationKeys.SERVER_NAME));
setService(getString(ConfigurationKeys.SERVICE));
setEncodeServiceUrl(getBoolean(ConfigurationKeys.ENCODE_SERVICE_URL));
initInternal(filterConfig);
}
@ -92,8 +91,6 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
* afterPropertiesSet();
*/
public void init() {
CommonUtils.assertNotNull(this.artifactParameterName, "artifactParameterName cannot be null.");
CommonUtils.assertNotNull(this.serviceParameterName, "serviceParameterName cannot be null.");
CommonUtils.assertTrue(CommonUtils.isNotEmpty(this.serverName) || CommonUtils.isNotEmpty(this.service),
"serverName or service must be set.");
CommonUtils.assertTrue(CommonUtils.isBlank(this.serverName) || CommonUtils.isBlank(this.service),
@ -101,13 +98,15 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
}
// empty implementation as most filters won't need this.
@Override
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.artifactParameterName, this.encodeServiceUrl);
this.protocol.getServiceParameterName(),
this.protocol.getArtifactParameterName(), this.encodeServiceUrl);
}
/**
@ -129,26 +128,14 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
this.service = service;
}
public final void setArtifactParameterName(final String artifactParameterName) {
this.artifactParameterName = artifactParameterName;
}
public final void setServiceParameterName(final String serviceParameterName) {
this.serviceParameterName = serviceParameterName;
}
public final void setEncodeServiceUrl(final boolean encodeServiceUrl) {
this.encodeServiceUrl = encodeServiceUrl;
}
public final String getArtifactParameterName() {
return this.artifactParameterName;
protected Protocol getProtocol() {
return this.protocol;
}
public final String getServiceParameterName() {
return this.serviceParameterName;
}
/**
* Template method to allow you to change how you retrieve the ticket.
*
@ -156,6 +143,7 @@ public abstract class AbstractCasFilter extends AbstractConfigurationFilter {
* @return the ticket if its found, null otherwise.
*/
protected String retrieveTicketFromRequest(final HttpServletRequest request) {
return CommonUtils.safeGetParameter(request, getArtifactParameterName());
return CommonUtils.safeGetParameter(request, this.protocol.getArtifactParameterName(),
Arrays.asList(this.protocol.getArtifactParameterName()));
}
}

View File

@ -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 the following location:
@ -18,10 +18,13 @@
*/
package org.jasig.cas.client.util;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import org.jasig.cas.client.configuration.ConfigurationKey;
import org.jasig.cas.client.configuration.ConfigurationStrategy;
import org.jasig.cas.client.configuration.ConfigurationStrategyName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,94 +37,42 @@ import org.slf4j.LoggerFactory;
*/
public abstract class AbstractConfigurationFilter implements Filter {
private static final String CONFIGURATION_STRATEGY_KEY = "configurationStrategy";
protected final Logger logger = LoggerFactory.getLogger(getClass());
private boolean ignoreInitConfiguration = false;
/**
* Retrieves the property from the FilterConfig. First it checks the FilterConfig's initParameters to see if it
* has a value.
* If it does, it returns that, otherwise it retrieves the ServletContext's initParameters and returns that value if any.
* <p>
* Finally, it will check JNDI if all other methods fail. All the JNDI properties should be stored under either java:comp/env/cas/SHORTFILTERNAME/{propertyName}
* or java:comp/env/cas/{propertyName}
* <p>
* Essentially the documented order is:
* <ol>
* <li>FilterConfig.getInitParameter</li>
* <li>ServletContext.getInitParameter</li>
* <li>java:comp/env/cas/SHORTFILTERNAME/{propertyName}</li>
* <li>java:comp/env/cas/{propertyName}</li>
* <li>Default Value</li>
* </ol>
*
*
* @param filterConfig the Filter Configuration.
* @param propertyName the property to retrieve.
* @param defaultValue the default value if the property is not found.
* @return the property value, following the above conventions. It will always return the more specific value (i.e.
* filter vs. context).
*/
protected final String getPropertyFromInitParams(final FilterConfig filterConfig, final String propertyName,
final String defaultValue) {
final String value = filterConfig.getInitParameter(propertyName);
private ConfigurationStrategy configurationStrategy;
if (CommonUtils.isNotBlank(value)) {
if ("renew".equals(propertyName)) {
throw new IllegalArgumentException(
"Renew MUST be specified via context parameter or JNDI environment to avoid misconfiguration.");
}
logger.info("Property [{}] loaded from FilterConfig.getInitParameter with value [{}]", propertyName, value);
return value;
}
final String value2 = filterConfig.getServletContext().getInitParameter(propertyName);
if (CommonUtils.isNotBlank(value2)) {
logger.info("Property [{}] loaded from ServletContext.getInitParameter with value [{}]", propertyName,
value2);
return value2;
}
InitialContext context;
try {
context = new InitialContext();
} catch (final NamingException e) {
logger.warn(e.getMessage(), e);
return defaultValue;
}
final String shortName = this.getClass().getName().substring(this.getClass().getName().lastIndexOf(".") + 1);
final String value3 = loadFromContext(context, "java:comp/env/cas/" + shortName + "/" + propertyName);
if (CommonUtils.isNotBlank(value3)) {
logger.info("Property [{}] loaded from JNDI Filter Specific Property with value [{}]", propertyName, value3);
return value3;
}
final String value4 = loadFromContext(context, "java:comp/env/cas/" + propertyName);
if (CommonUtils.isNotBlank(value4)) {
logger.info("Property [{}] loaded from JNDI with value [{}]", propertyName, value4);
return value4;
}
logger.info("Property [{}] not found. Using default value [{}]", propertyName, defaultValue);
return defaultValue;
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
final String configurationStrategyName = filterConfig.getServletContext().getInitParameter(CONFIGURATION_STRATEGY_KEY);
this.configurationStrategy = ReflectUtils.newInstance(ConfigurationStrategyName.resolveToConfigurationStrategy(configurationStrategyName));
this.configurationStrategy.init(filterConfig, getClass());
}
protected final boolean parseBoolean(final String value) {
return ((value != null) && value.equalsIgnoreCase("true"));
protected final boolean getBoolean(final ConfigurationKey<Boolean> configurationKey) {
return this.configurationStrategy.getBoolean(configurationKey);
}
protected final String loadFromContext(final InitialContext context, final String path) {
try {
return (String) context.lookup(path);
} catch (final NamingException e) {
return null;
}
protected final String getString(final ConfigurationKey<String> configurationKey) {
return this.configurationStrategy.getString(configurationKey);
}
public final void setIgnoreInitConfiguration(boolean ignoreInitConfiguration) {
protected final long getLong(final ConfigurationKey<Long> configurationKey) {
return this.configurationStrategy.getLong(configurationKey);
}
protected final int getInt(final ConfigurationKey<Integer> configurationKey) {
return this.configurationStrategy.getInt(configurationKey);
}
protected final <T> Class<? extends T> getClass(final ConfigurationKey<Class<? extends T>> configurationKey) {
return this.configurationStrategy.getClass(configurationKey);
}
public final void setIgnoreInitConfiguration(final boolean ignoreInitConfiguration) {
this.ignoreInitConfiguration = ignoreInitConfiguration;
}

View File

@ -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 the following location:
@ -24,7 +24,6 @@ import org.jasig.cas.client.validation.Assertion;
* Static holder that places Assertion in a ThreadLocal.
*
* @author Scott Battaglia
* @version $Revision: 11728 $ $Date: 2007-09-26 14:20:43 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public class AssertionHolder {

View File

@ -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 the following location:
@ -28,17 +28,18 @@ 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.
*
* @author Scott Battaglia
* @version $Revision: 11728 $ $Date: 2007-09-26 14:20:43 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public final class AssertionThreadLocalFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
// nothing to do here
}
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpSession session = request.getSession(false);
final Assertion assertion = (Assertion) (session == null ? request
@ -53,6 +54,7 @@ public final class AssertionThreadLocalFilter implements Filter {
}
}
@Override
public void destroy() {
// nothing to do
}

View File

@ -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 the following location:
@ -18,15 +18,7 @@
*/
package org.jasig.cas.client.util;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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;
@ -35,11 +27,27 @@ import org.jasig.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;
import java.io.UnsupportedEncodingException;
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.
*
* @author Scott Battaglia
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public final class CommonUtils {
@ -58,14 +66,20 @@ public final class CommonUtils {
private static final HttpURLConnectionFactory DEFAULT_URL_CONNECTION_FACTORY = new HttpsURLConnectionFactory();
private CommonUtils() {
// nothing to do
private static final String SERVICE_PARAMETER_NAMES;
static {
final Set<String> serviceParameterSet = new HashSet<String>(4);
for (final Protocol protocol : Protocol.values()) {
serviceParameterSet.add(protocol.getServiceParameterName());
}
SERVICE_PARAMETER_NAMES = serviceParameterSet.toString()
.replaceAll("\\[|\\]", "")
.replaceAll("\\s", "");
}
public static String formatForUtcTime(final Date date) {
final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(date);
private CommonUtils() {
// nothing to do
}
/**
@ -99,7 +113,7 @@ public final class CommonUtils {
* Assert that the statement is true, otherwise throw an exception with the
* provided message.
*
* @param cond the codition to assert is true.
* @param cond the condition to assert is true.
* @param message the message to display if the condition is not true.
*/
public static void assertTrue(final boolean cond, final String message) {
@ -108,6 +122,20 @@ public final class CommonUtils {
}
}
/**
* Assert that the statement is true, otherwise throw an exception with the
* provided message.
*
* @param cond the condition to assert is false.
* @param message the message to display if the condition is not false.
*/
public static void assertFalse(final boolean cond, final String message) {
if (cond) {
throw new IllegalArgumentException(message);
}
}
/**
* Determines whether the String is null or of length 0.
*
@ -115,7 +143,7 @@ public final class CommonUtils {
* @return true if its null or length of 0, false otherwise.
*/
public static boolean isEmpty(final String string) {
return string == null || string.length() == 0;
return string == null || string.isEmpty();
}
/**
@ -137,7 +165,7 @@ public final class CommonUtils {
* @return true if its blank, false otherwise.
*/
public static boolean isBlank(final String string) {
return isEmpty(string) || string.trim().length() == 0;
return isEmpty(string) || string.trim().isEmpty();
}
/**
@ -159,21 +187,38 @@ public final class CommonUtils {
* @param serviceUrl the actual service's url.
* @param renew whether we should send renew or not.
* @param gateway where we should send gateway or not.
* @param method the method used by the CAS server to send the user back to the application.
* @return the fully constructed redirect url.
*/
public static String constructRedirectUrl(final String casServerLoginUrl, final String serviceParameterName,
final String serviceUrl, final boolean renew, final boolean gateway) {
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" : "");
+ urlEncode(serviceUrl) + (renew ? "&renew=true" : "") + (gateway ? "&gateway=true" : "")
+ (method != null ? "&method=" + method : "");
}
/**
* Construct redirect url to a CAS server.
*
* @param casServerLoginUrl the cas server login url
* @param serviceParameterName the service parameter name
* @param serviceUrl the service url
* @param renew the renew
* @param gateway the gateway
* @return the string
*/
public static String constructRedirectUrl(final String casServerLoginUrl, final String serviceParameterName,
final String serviceUrl, final boolean renew, final boolean gateway) {
return constructRedirectUrl(casServerLoginUrl, serviceParameterName, serviceUrl, renew, gateway, null);
}
/**
* Url encode a value using UTF-8 encoding.
*
*
* @param value the value to encode.
* @return the encoded value.
*/
public static String urlEncode(String value) {
public static String urlEncode(final String value) {
try {
return URLEncoder.encode(value, "UTF-8");
} catch (final UnsupportedEncodingException e) {
@ -182,8 +227,8 @@ public final class CommonUtils {
}
public static void readAndRespondToProxyReceptorRequest(final HttpServletRequest request,
final HttpServletResponse response, final ProxyGrantingTicketStorage proxyGrantingTicketStorage)
throws IOException {
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);
@ -194,12 +239,12 @@ public final class CommonUtils {
}
LOGGER.debug("Received proxyGrantingTicketId [{}] for proxyGrantingTicketIou [{}]", proxyGrantingTicket,
proxyGrantingTicketIou);
proxyGrantingTicketIou);
proxyGrantingTicketStorage.save(proxyGrantingTicketIou, proxyGrantingTicket);
LOGGER.debug("Successfully saved proxyGrantingTicketId [{}] for proxyGrantingTicketIou [{}]",
proxyGrantingTicket, proxyGrantingTicketIou);
proxyGrantingTicket, proxyGrantingTicketIou);
response.getWriter().write("<?xml version=\"1.0\"?>");
response.getWriter().write("<casClient:proxySuccess xmlns:casClient=\"http://www.yale.edu/tp/casClient\" />");
@ -208,7 +253,7 @@ public final class CommonUtils {
protected static String findMatchingServerName(final HttpServletRequest request, final String serverName) {
final String[] serverNames = serverName.split(" ");
if (serverNames == null || serverNames.length == 0 || serverNames.length == 1) {
if (serverNames.length == 0 || serverNames.length == 1) {
return serverName;
}
@ -216,11 +261,7 @@ public final class CommonUtils {
final String xHost = request.getHeader("X-Forwarded-Host");
final String comparisonHost;
if (xHost != null && host == "localhost") {
comparisonHost = xHost;
} else {
comparisonHost = host;
}
comparisonHost = (xHost != null) ? xHost : host;
if (comparisonHost == null) {
return serverName;
@ -237,86 +278,99 @@ public final class CommonUtils {
return serverNames[0];
}
private static boolean serverNameContainsPort(final boolean containsScheme, final String serverName) {
if (!containsScheme && serverName.contains(":")) {
return true;
}
final int schemeIndex = serverName.indexOf(":");
final int portIndex = serverName.lastIndexOf(":");
return schemeIndex != portIndex;
}
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.
*
* @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 constuct 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.
*/
* 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) {
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 StringBuilder buffer = new StringBuilder();
final String serverName = findMatchingServerName(request, serverNames);
final URIBuilder originalRequestUrl = new URIBuilder(request.getRequestURL().toString(), encode);
originalRequestUrl.setParameters(request.getQueryString());
boolean containsScheme = true;
final URIBuilder builder;
if (!serverName.startsWith("https://") && !serverName.startsWith("http://")) {
buffer.append(request.isSecure() ? "https://" : "http://");
containsScheme = false;
final String scheme = request.isSecure() ? "https://" : "http://";
builder = new URIBuilder(scheme + serverName, encode);
} else {
builder = new URIBuilder(serverName, encode);
}
buffer.append(serverName);
if (!serverNameContainsPort(containsScheme, serverName) && !requestIsOnStandardPort(request)) {
buffer.append(":");
buffer.append(request.getServerPort());
if (builder.getPort() == -1 && !requestIsOnStandardPort(request)) {
builder.setPort(request.getServerPort());
}
buffer.append(request.getRequestURI());
builder.setEncodedPath(builder.getEncodedPath() + request.getRequestURI());
if (CommonUtils.isNotBlank(request.getQueryString())) {
final int location = request.getQueryString().indexOf(artifactParameterName + "=");
if (location == 0) {
final String returnValue = encode ? response.encodeURL(buffer.toString()) : buffer.toString();
LOGGER.debug("serviceUrl generated: {}", returnValue);
return returnValue;
}
buffer.append("?");
if (location == -1) {
buffer.append(request.getQueryString());
} else if (location > 0) {
final int actualLocation = request.getQueryString().indexOf("&" + artifactParameterName + "=");
if (actualLocation == -1) {
buffer.append(request.getQueryString());
} else if (actualLocation > 0) {
buffer.append(request.getQueryString().substring(0, actualLocation));
final List<String> 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 returnValue = encode ? response.encodeURL(buffer.toString()) : buffer.toString();
final String result = builder.toString();
final String returnValue = encode ? response.encodeURL(result) : result;
LOGGER.debug("serviceUrl generated: {}", returnValue);
return returnValue;
}
@ -338,13 +392,13 @@ public final class CommonUtils {
* @return the value of the parameter.
*/
public static String safeGetParameter(final HttpServletRequest request, final String parameter,
final List<String> parameters) {
final List<String> 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);
.getParameter(parameter);
}
public static String safeGetParameter(final HttpServletRequest request, final String parameter) {
@ -363,8 +417,8 @@ public final class CommonUtils {
public static String getResponseFromServer(final String constructedUrl, final String encoding) {
try {
return getResponseFromServer(new URL(constructedUrl), DEFAULT_URL_CONNECTION_FACTORY, encoding);
} catch (final Exception e) {
throw new RuntimeException(e);
} catch (final IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@ -382,7 +436,7 @@ public final class CommonUtils {
* @return the response.
*/
public static String getResponseFromServer(final URL constructedUrl, final HttpURLConnectionFactory factory,
final String encoding) {
final String encoding) {
HttpURLConnection conn = null;
InputStreamReader in = null;
@ -402,8 +456,14 @@ public final class CommonUtils {
}
return builder.toString();
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
} catch (final RuntimeException e) {
throw e;
} catch (final SSLException e) {
LOGGER.error("SSL error getting response from host: {} : Error Message: {}", constructedUrl.getHost(), e.getMessage(), e);
throw new RuntimeException(e);
} catch (final IOException e) {
LOGGER.error("Error getting response from host: [{}] with path: [{}] and protocol: [{}] Error Message: {}",
constructedUrl.getHost(), constructedUrl.getPath(), constructedUrl.getProtocol(), e.getMessage(), e);
throw new RuntimeException(e);
} finally {
closeQuietly(in);
@ -432,7 +492,7 @@ public final class CommonUtils {
public static void sendRedirect(final HttpServletResponse response, final String url) {
try {
response.sendRedirect(url);
} catch (final Exception e) {
} catch (final IOException e) {
LOGGER.warn(e.getMessage(), e);
}
@ -441,7 +501,7 @@ public final class CommonUtils {
/**
* Unconditionally close a {@link Closeable}. Equivalent to {@link java.io.Closeable#close()}close(), except any exceptions
* will be ignored. This is typically used in finally blocks.
* @param resource
* @param resource the resource to close
*/
public static void closeQuietly(final Closeable resource) {
try {
@ -452,4 +512,236 @@ public final class CommonUtils {
//ignore
}
}
/**
* <p>Converts a String to a boolean (optimised for performance).</p>
*
* <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
* (case insensitive) will return {@code true}. Otherwise,
* {@code false} is returned.</p>
*
* <p>This method performs 4 times faster (JDK1.4) than
* {@code Boolean.valueOf(String)}. However, this method accepts
* 'on' and 'yes', 't', 'y' as true values.
*
* <pre>
* BooleanUtils.toBoolean(null) = false
* BooleanUtils.toBoolean("true") = true
* BooleanUtils.toBoolean("TRUE") = true
* BooleanUtils.toBoolean("tRUe") = true
* BooleanUtils.toBoolean("on") = true
* BooleanUtils.toBoolean("yes") = true
* BooleanUtils.toBoolean("false") = false
* BooleanUtils.toBoolean("x gti") = false
* BooleanUtils.toBooleanObject("y") = true
* BooleanUtils.toBooleanObject("n") = false
* BooleanUtils.toBooleanObject("t") = true
* BooleanUtils.toBooleanObject("f") = false
* </pre>
*
* @param str the String to check
* @return the boolean value of the string, {@code false} if no match or the String is null
*/
public static boolean toBoolean(final String str) {
return toBooleanObject(str) == Boolean.TRUE;
}
/**
* <p>Converts a String to a Boolean.</p>
*
* <p>{@code 'true'}, {@code 'on'}, {@code 'y'}, {@code 't'} or {@code 'yes'}
* (case insensitive) will return {@code true}.
* {@code 'false'}, {@code 'off'}, {@code 'n'}, {@code 'f'} or {@code 'no'}
* (case insensitive) will return {@code false}.
* Otherwise, {@code null} is returned.</p>
*
* <p>NOTE: This returns null and will throw a NullPointerException if autoboxed to a boolean. </p>
*
* <pre>
* // N.B. case is not significant
* BooleanUtils.toBooleanObject(null) = null
* BooleanUtils.toBooleanObject("true") = Boolean.TRUE
* BooleanUtils.toBooleanObject("T") = Boolean.TRUE // i.e. T[RUE]
* BooleanUtils.toBooleanObject("false") = Boolean.FALSE
* BooleanUtils.toBooleanObject("f") = Boolean.FALSE // i.e. f[alse]
* BooleanUtils.toBooleanObject("No") = Boolean.FALSE
* BooleanUtils.toBooleanObject("n") = Boolean.FALSE // i.e. n[o]
* BooleanUtils.toBooleanObject("on") = Boolean.TRUE
* BooleanUtils.toBooleanObject("ON") = Boolean.TRUE
* BooleanUtils.toBooleanObject("off") = Boolean.FALSE
* BooleanUtils.toBooleanObject("oFf") = Boolean.FALSE
* BooleanUtils.toBooleanObject("yes") = Boolean.TRUE
* BooleanUtils.toBooleanObject("Y") = Boolean.TRUE // i.e. Y[ES]
* BooleanUtils.toBooleanObject("blue") = null
* BooleanUtils.toBooleanObject("true ") = null // trailing space (too long)
* BooleanUtils.toBooleanObject("ono") = null // does not match on or no
* </pre>
*
* @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) {
// Previously used equalsIgnoreCase, which was fast for interned 'true'.
// Non interned 'true' matched 15 times slower.
//
// Optimisation provides same performance as before for interned 'true'.
// Similar performance for null, 'false', and other strings not length 2/3/4.
// 'true'/'TRUE' match 4 times slower, 'tRUE'/'True' 7 times slower.
if (str == "true") {
return Boolean.TRUE;
}
if (str == null) {
return null;
}
switch (str.length()) {
case 1: {
final char ch0 = str.charAt(0);
if (ch0 == 'y' || ch0 == 'Y' ||
ch0 == 't' || ch0 == 'T') {
return Boolean.TRUE;
}
if (ch0 == 'n' || ch0 == 'N' ||
ch0 == 'f' || ch0 == 'F') {
return Boolean.FALSE;
}
break;
}
case 2: {
final char ch0 = str.charAt(0);
final char ch1 = str.charAt(1);
if ((ch0 == 'o' || ch0 == 'O') &&
(ch1 == 'n' || ch1 == 'N')) {
return Boolean.TRUE;
}
if ((ch0 == 'n' || ch0 == 'N') &&
(ch1 == 'o' || ch1 == 'O')) {
return Boolean.FALSE;
}
break;
}
case 3: {
final char ch0 = str.charAt(0);
final char ch1 = str.charAt(1);
final char ch2 = str.charAt(2);
if ((ch0 == 'y' || ch0 == 'Y') &&
(ch1 == 'e' || ch1 == 'E') &&
(ch2 == 's' || ch2 == 'S')) {
return Boolean.TRUE;
}
if ((ch0 == 'o' || ch0 == 'O') &&
(ch1 == 'f' || ch1 == 'F') &&
(ch2 == 'f' || ch2 == 'F')) {
return Boolean.FALSE;
}
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);
if ((ch0 == 't' || ch0 == 'T') &&
(ch1 == 'r' || ch1 == 'R') &&
(ch2 == 'u' || ch2 == 'U') &&
(ch3 == 'e' || ch3 == 'E')) {
return Boolean.TRUE;
}
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);
if ((ch0 == 'f' || ch0 == 'F') &&
(ch1 == 'a' || ch1 == 'A') &&
(ch2 == 'l' || ch2 == 'L') &&
(ch3 == 's' || ch3 == 'S') &&
(ch4 == 'e' || ch4 == 'E')) {
return Boolean.FALSE;
}
break;
}
default:
break;
}
return null;
}
/**
* <p>Convert a <code>String</code> to a <code>long</code>, returning a
* default value if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, the default value is returned.</p>
*
* <pre>
* NumberUtils.toLong(null, 1L) = 1L
* NumberUtils.toLong("", 1L) = 1L
* NumberUtils.toLong("1", 0L) = 1L
* </pre>
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the long represented by the string, or the default if conversion fails
*/
public static long toLong(final String str, final long defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Long.parseLong(str);
} catch (final NumberFormatException nfe) {
return defaultValue;
}
}
/**
* <p>Convert a <code>String</code> to an <code>int</code>, returning a
* default value if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, the default value is returned.</p>
*
* <pre>
* NumberUtils.toInt(null, 1) = 1
* NumberUtils.toInt("", 1) = 1
* NumberUtils.toInt("1", 0) = 1
* </pre>
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the int represented by the string, or the default if conversion fails
*/
public static int toInt(final String str, final int defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Integer.parseInt(str);
} catch (final NumberFormatException nfe) {
return defaultValue;
}
}
/**
* Returns the string as-is, unless it's <code>null</code>;
* in this case an empty string is returned.
*
* @param string a possibly <code>null</code> string
* @return a non-<code>null</code> string
*/
public static String nullToEmpty(final String string) {
return string == null ? "" : string;
}
/**
* Adds a trailing slash to the given uri, if it doesn't already have one.
*
* @param uri a string that may or may not end with a slash
* @return the same string, except with a slash suffix (if necessary).
*/
public static String addTrailingSlash(final String uri) {
return uri.endsWith("/") ? uri : uri + "/";
}
}

View File

@ -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 the following location:
@ -31,7 +31,6 @@ import org.slf4j.LoggerFactory;
* the associated filter is executed. Otherwise, the normal chain is executed.
*
* @author Scott Battaglia
* @version $Revision: 11729 $ $Date: 2006-09-26 14:22:30 -0400 (Tue, 26 Sep 2006) $
* @since 3.0
*/
public final class DelegatingFilter implements Filter {
@ -78,10 +77,12 @@ public final class DelegatingFilter implements Filter {
this.exactMatch = exactMatch;
}
@Override
public void destroy() {
// nothing to do here
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
throws IOException, ServletException {
@ -108,6 +109,7 @@ public final class DelegatingFilter implements Filter {
}
}
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
// nothing to do here.
}

View File

@ -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 the following location:
@ -24,22 +24,22 @@ 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
* init filter name/param values.
* <p>
* <p/>
* If there is an exact match the filter uses that value. If there's a non-exact match (i.e. inheritance), then the filter
* uses the last value that matched.
* <p>
* <p/>
* If there is no match it will redirect to a default error page. The default exception is configured via the "defaultErrorRedirectPage" property.
*
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.4
*
*/
public final class ErrorRedirectFilter implements Filter {
@ -49,17 +49,19 @@ public final class ErrorRedirectFilter implements Filter {
private String defaultErrorRedirectPage;
@Override
public void destroy() {
// nothing to do here
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
throws IOException, ServletException {
final HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
filterChain.doFilter(request, response);
} catch (final ServletException e) {
final Throwable t = e.getCause();
} catch (final Exception e) {
final Throwable t = extractErrorToCompare(e);
ErrorHolder currentMatch = null;
for (final ErrorHolder errorHolder : this.errors) {
if (errorHolder.exactMatch(t)) {
@ -78,6 +80,23 @@ public final class ErrorRedirectFilter implements Filter {
}
}
/**
* 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");

View File

@ -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 the following location:
@ -26,6 +26,7 @@ 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;
/**
@ -43,7 +44,6 @@ import org.jasig.cas.client.validation.Assertion;
*
* @author Scott Battaglia
* @author Marvin S. Addison
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public final class HttpServletRequestWrapperFilter extends AbstractConfigurationFilter {
@ -54,6 +54,7 @@ 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
}
@ -63,8 +64,9 @@ public final class HttpServletRequestWrapperFilter extends AbstractConfiguration
* <code>request.getRemoteUser</code> to the underlying Assertion object
* stored in the user session.
*/
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final FilterChain filterChain) throws IOException, ServletException {
final AttributePrincipal principal = retrievePrincipalFromSessionOrRequest(servletRequest);
filterChain.doFilter(new CasHttpServletRequestWrapper((HttpServletRequest) servletRequest, principal),
@ -81,9 +83,11 @@ public final class HttpServletRequestWrapperFilter extends AbstractConfiguration
return assertion == null ? null : assertion.getPrincipal();
}
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
this.roleAttribute = getPropertyFromInitParams(filterConfig, "roleAttribute", null);
this.ignoreCase = Boolean.parseBoolean(getPropertyFromInitParams(filterConfig, "ignoreCase", "false"));
super.init(filterConfig);
this.roleAttribute = getString(ConfigurationKeys.ROLE_ATTRIBUTE);
this.ignoreCase = getBoolean(ConfigurationKeys.IGNORE_CASE);
}
final class CasHttpServletRequestWrapper extends HttpServletRequestWrapper {
@ -95,14 +99,17 @@ public final class HttpServletRequestWrapperFilter extends AbstractConfiguration
this.principal = principal;
}
@Override
public Principal getUserPrincipal() {
return this.principal;
}
@Override
public String getRemoteUser() {
return principal != null ? this.principal.getName() : null;
}
@Override
public boolean isUserInRole(final String role) {
if (CommonUtils.isBlank(role)) {
logger.debug("No valid role provided. Returning false.");

View File

@ -0,0 +1,92 @@
/**
* 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 java.io.*;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
/**
* IO utility class.
*
* @author Marvin S. Addison
* @since 3.4
*/
public final class IOUtils {
/** UTF-8 character set. */
public static final Charset UTF8 = Charset.forName("UTF-8");
private IOUtils() { /** Utility class pattern. */ }
/**
* Reads all data from the given stream as UTF-8 character data and closes it on completion or errors.
*
* @param in Input stream containing character data.
*
* @return String of all data in stream.
*
* @throws IOException On IO errors.
*/
public static String readString(final InputStream in) throws IOException {
return readString(in, UTF8);
}
/**
* Reads all data from the given stream as character data in the given character set and closes it on completion
* or errors.
*
* @param in Input stream containing character data.
* @param charset Character set of data in stream.
*
* @return String of all data in stream.
*
* @throws IOException On IO errors.
*/
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);
try {
while (reader.read(buffer) > -1) {
buffer.flip();
builder.append(buffer);
}
} finally {
closeQuietly(reader);
}
return builder.toString();
}
/**
* Unconditionally close a {@link Closeable} resource. Errors on close are ignored.
*
* @param resource Resource to close.
*/
public static void closeQuietly(final Closeable resource) {
try {
if (resource != null) {
resource.close();
}
} catch (final IOException e) {
//ignore
}
}
}

View File

@ -0,0 +1,83 @@
/**
* 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 javax.xml.namespace.NamespaceContext;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Namespace context implementation backed by a map of XML prefixes to namespace URIs.
*
* @author Marvin S. Addison
* @since 3.4
*/
public class MapNamespaceContext implements NamespaceContext {
private final Map<String, String> namespaceMap;
/**
* Creates a new instance from an array of namespace delcarations.
*
* @param namespaceDeclarations An array of namespace declarations of the form prefix->uri.
*/
public MapNamespaceContext(final String ... namespaceDeclarations) {
namespaceMap = new HashMap<String, String>();
int index;
String key;
String value;
for (final String decl : namespaceDeclarations) {
index = decl.indexOf('-');
key = decl.substring(0, index);
value = decl.substring(index + 2);
namespaceMap.put(key, value);
}
}
/**
* Creates a new instance from a map.
*
* @param namespaceMap Map of XML namespace prefixes (keys) to URIs (values).
*/
public MapNamespaceContext(final Map<String, String> namespaceMap) {
this.namespaceMap = namespaceMap;
}
@Override
public String getNamespaceURI(final String prefix) {
return namespaceMap.get(prefix);
}
@Override
public String getPrefix(final String namespaceURI) {
for (final Map.Entry<String, String> entry : namespaceMap.entrySet()) {
if (entry.getValue().equalsIgnoreCase(namespaceURI)) {
return entry.getKey();
}
}
return null;
}
@Override
public Iterator getPrefixes(final String namespaceURI) {
return Collections.singleton(getPrefix(namespaceURI)).iterator();
}
}

View File

@ -0,0 +1,108 @@
/**
* 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 org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
/**
* Utility class to parse private keys.
*
* @author Jerome LELEU
* @since 3.6.0
*/
public class PrivateKeyUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(PrivateKeyUtils.class);
static {
Security.addProvider(new BouncyCastleProvider());
}
public static PrivateKey createKey(final String path, final String algorithm) {
final PrivateKey key = readPemPrivateKey(path);
if (key == null) {
return readDERPrivateKey(path, algorithm);
} else {
return key;
}
}
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);
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];
fis.read(bytes, 0, (int) byteLength);
final PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(bytes);
final KeyFactory 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) {}
}
}
}

View File

@ -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 the following location:
@ -22,6 +22,7 @@ import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
@ -148,4 +149,35 @@ public final class ReflectUtils {
throw new RuntimeException("Error setting property " + propertyName, e);
}
}
/**
* Gets the value of the given declared field on the target object or any of its superclasses.
*
* @param fieldName Name of field to get.
* @param target Target object that possesses field.
*
* @return Field value.
*/
public static Object getField(final String fieldName, final Object target) {
Class<?> clazz = target.getClass();
Field field = null;
do {
try {
field = clazz.getDeclaredField(fieldName);
} catch (final NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
} while (field == null && clazz != null);
if (field == null) {
throw new IllegalArgumentException(fieldName + " does not exist on " + target);
}
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
return field.get(target);
} catch (final Exception e) {
throw new IllegalArgumentException("Error getting field " + fieldName, e);
}
}
}

View File

@ -0,0 +1,109 @@
/**
* 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 org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.xpath.*;
/**
* Thread local XPath expression.
*
* @author Marvin S. Addison
* @since 3.4
*/
public class ThreadLocalXPathExpression extends ThreadLocal<XPathExpression> implements XPathExpression {
/** XPath expression */
private final String expression;
/** Namespace context. */
private final NamespaceContext context;
/**
* Creates a new instance from an XPath expression and namespace context.
*
* @param xPath XPath expression.
* @param context Namespace context for handling namespace prefix to URI mappings.
*/
public ThreadLocalXPathExpression(final String xPath, final NamespaceContext context) {
this.expression = xPath;
this.context = context;
}
@Override
public Object evaluate(final Object o, final QName qName) throws XPathExpressionException {
return get().evaluate(o, qName);
}
@Override
public String evaluate(final Object o) throws XPathExpressionException {
return get().evaluate(o);
}
@Override
public Object evaluate(final InputSource inputSource, final QName qName) throws XPathExpressionException {
return get().evaluate(inputSource, qName);
}
@Override
public String evaluate(final InputSource inputSource) throws XPathExpressionException {
return get().evaluate(inputSource);
}
/**
* Evaluates the XPath expression and returns the result coerced to a string.
*
* @param o Object on which to evaluate the expression; typically a DOM node.
*
* @return Evaluation result as a string.
*
* @throws XPathExpressionException On XPath evaluation errors.
*/
public String evaluateAsString(final Object o) throws XPathExpressionException {
return (String) evaluate(o, XPathConstants.STRING);
}
/**
* Evaluates the XPath expression and returns the result coerced to a node list.
*
* @param o Object on which to evaluate the expression; typically a DOM node.
*
* @return Evaluation result as a node list.
*
* @throws XPathExpressionException On XPath evaluation errors.
*/
public NodeList evaluateAsNodeList(final Object o) throws XPathExpressionException {
return (NodeList) evaluate(o, XPathConstants.NODESET);
}
@Override
protected XPathExpression initialValue() {
try {
final XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(context);
return xPath.compile(expression);
} catch (final XPathExpressionException e) {
throw new IllegalArgumentException("Invalid XPath expression");
}
}
}

View File

@ -0,0 +1,682 @@
/**
* 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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
/**
* A utility class borrowed from apache http-client to build uris.
*
* @author Misagh Moayyed
* @since 3.4
*/
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<BasicNameValuePair> queryParams;
private String query;
private boolean encode;
private String fragment;
private String encodedFragment;
/**
* Constructs an empty instance.
*/
public URIBuilder() {
super();
this.port = -1;
}
public URIBuilder(final boolean encode) {
this();
setEncode(encode);
}
/**
* Construct an instance from the string which must be a valid URI.
*
* @param string a valid URI in string form
* @throws RuntimeException if the input is not a valid URI
*/
public URIBuilder(final String string) {
super();
try {
digestURI(new URI(string));
} catch (final URISyntaxException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public URIBuilder(final String string, final boolean encode) {
super();
try {
setEncode(encode);
digestURI(new URI(string));
} catch (final URISyntaxException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* Construct an instance from the provided URI.
*
* @param uri the uri to digest
*/
public URIBuilder(final URI uri) {
super();
digestURI(uri);
}
private List<BasicNameValuePair> parseQuery(final String query) {
try {
final Charset utf8 = Charset.forName("UTF-8");
if (query != null && !query.isEmpty()) {
final List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
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());
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;
}
} catch (final UnsupportedEncodingException e) {
LOGGER.error(e.getMessage(), e);
}
return new ArrayList<BasicNameValuePair>();
}
/**
* Builds a {@link URI} instance.
*/
public URI build() {
try {
return new URI(buildString());
} catch (final URISyntaxException e) {
throw new RuntimeException(e);
}
}
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();
this.encodedAuthority = uri.getRawAuthority();
this.host = uri.getHost();
this.port = uri.getPort();
this.encodedUserInfo = uri.getRawUserInfo();
this.userInfo = uri.getUserInfo();
this.encodedPath = uri.getRawPath();
this.path = uri.getPath();
this.encodedQuery = uri.getRawQuery();
this.queryParams = parseQuery(uri.getRawQuery());
this.encodedFragment = uri.getRawFragment();
this.fragment = uri.getFragment();
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<BasicNameValuePair> 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.
*/
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.
*/
public URIBuilder removeQuery() {
this.queryParams = null;
this.query = null;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Sets URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.
* <p>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove custom query if present.
* </p>
*/
public URIBuilder setParameters(final List<BasicNameValuePair> nvps) {
this.queryParams = new ArrayList<BasicNameValuePair>();
this.queryParams.addAll(nvps);
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
public URIBuilder setParameters(final String queryParameters) {
this.queryParams = new ArrayList<BasicNameValuePair>();
this.queryParams.addAll(parseQuery(queryParameters));
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
/**
* Adds URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.
* <p>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove custom query if present.
* </p>
*/
public URIBuilder addParameters(final List<BasicNameValuePair> nvps) {
if (this.queryParams == null || this.queryParams.isEmpty()) {
this.queryParams = new ArrayList<BasicNameValuePair>();
}
this.queryParams.addAll(nvps);
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
/**
* Sets URI query parameters. The parameter name / values are expected to be unescaped
* and may contain non ASCII characters.
* <p>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove custom query if present.
* </p>
*/
public URIBuilder setParameters(final BasicNameValuePair... nvps) {
if (this.queryParams == null) {
this.queryParams = new ArrayList<BasicNameValuePair>();
} else {
this.queryParams.clear();
}
for (final BasicNameValuePair nvp : nvps) {
this.queryParams.add(nvp);
}
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
/**
* Adds parameter to URI query. The parameter name and value are expected to be unescaped
* and may contain non ASCII characters.
* <p>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove custom query if present.
* </p>
*/
public URIBuilder addParameter(final String param, final String value) {
if (this.queryParams == null) {
this.queryParams = new ArrayList<BasicNameValuePair>();
}
this.queryParams.add(new BasicNameValuePair(param, value));
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
/**
* Sets parameter of URI query overriding existing value if set. The parameter name and value
* are expected to be unescaped and may contain non ASCII characters.
* <p>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove custom query if present.
* </p>
*/
public URIBuilder setParameter(final String param, final String value) {
if (this.queryParams == null) {
this.queryParams = new ArrayList<BasicNameValuePair>();
}
if (!this.queryParams.isEmpty()) {
for (final Iterator<BasicNameValuePair> it = this.queryParams.iterator(); it.hasNext(); ) {
final BasicNameValuePair nvp = it.next();
if (nvp.getName().equals(param)) {
it.remove();
}
}
}
this.queryParams.add(new BasicNameValuePair(param, value));
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.query = null;
return this;
}
/**
* Clears URI query parameters.
*/
public URIBuilder clearParameters() {
this.queryParams = null;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
return this;
}
/**
* Sets custom URI query. The value is expected to be unescaped and may contain non ASCII
* characters.
* <p>
* Please note query parameters and custom query component are mutually exclusive. This method
* will remove query parameters if present.
* </p>
*/
public URIBuilder setCustomQuery(final String query) {
this.query = query;
this.encodedQuery = null;
this.encodedSchemeSpecificPart = null;
this.queryParams = null;
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;
return this;
}
public URIBuilder setEncodedQuery(final String query) {
this.query = null;
this.encodedFragment = query;
return this;
}
public boolean isAbsolute() {
return this.scheme != null;
}
public boolean isOpaque() {
return this.path == null;
}
public String getScheme() {
return this.scheme;
}
public String getUserInfo() {
return this.userInfo;
}
public String getHost() {
return this.host;
}
public int getPort() {
return this.port;
}
public String getPath() {
return this.path;
}
public String getEncodedPath() {
return this.encodedPath;
}
public List<BasicNameValuePair> getQueryParams() {
if (this.queryParams != null) {
return new ArrayList<BasicNameValuePair>(this.queryParams);
}
return new ArrayList<BasicNameValuePair>();
}
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);
}
@Override
public int hashCode() {
int 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);
result = 31 * result + (encodedUserInfo != null ? encodedUserInfo.hashCode() : 0);
result = 31 * result + (host != null ? host.hashCode() : 0);
result = 31 * result + port;
result = 31 * result + (path != null ? path.hashCode() : 0);
result = 31 * result + (encodedPath != null ? encodedPath.hashCode() : 0);
result = 31 * result + (encodedQuery != null ? encodedQuery.hashCode() : 0);
result = 31 * result + (queryParams != null ? queryParams.hashCode() : 0);
result = 31 * result + (query != null ? query.hashCode() : 0);
result = 31 * result + (encode ? 1 : 0);
result = 31 * result + (fragment != null ? fragment.hashCode() : 0);
result = 31 * result + (encodedFragment != null ? encodedFragment.hashCode() : 0);
return result;
}
public static class BasicNameValuePair implements Cloneable, Serializable {
private static final long serialVersionUID = -6437800749411518984L;
private final String name;
private final String value;
/**
* Default Constructor taking a name and a value. The value may be null.
*
* @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;
}
@Override
public String toString() {
// don't call complex default formatting for a simple toString
if (this.value == null) {
return name;
}
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;
}
if (object == null) {
return false;
}
if (object instanceof BasicNameValuePair) {
final BasicNameValuePair that = (BasicNameValuePair) object;
return this.name.equals(that.name)
&& this.value.equals(that.value);
}
return false;
}
@Override
public int hashCode() {
return 133 * this.name.hashCode() * this.value.hashCode();
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}

View File

@ -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 the following location:
@ -19,23 +19,26 @@
package org.jasig.cas.client.util;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
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.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
/**
* Common utilities for easily parsing XML without duplicating logic.
*
* @author Scott Battaglia
* @version $Revision: 11729 $ $Date: 2007-09-26 14:22:30 -0400 (Tue, 26 Sep 2007) $
* @since 3.0
*/
public final class XmlUtils {
@ -45,6 +48,36 @@ public final class XmlUtils {
*/
private final static Logger LOGGER = LoggerFactory.getLogger(XmlUtils.class);
/**
* Creates a new namespace-aware DOM document object by parsing the given XML.
*
* @param xml XML content.
*
* @return DOM document.
*/
public static Document newDocument(final String xml) {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final Map<String, Boolean> features = new HashMap<String, Boolean>();
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<String, Boolean> entry : features.entrySet()) {
try {
factory.setFeature(entry.getKey(), entry.getValue());
} catch (final ParserConfigurationException e) {
LOGGER.warn("Failed setting XML feature {}: {}", entry.getKey(), e);
}
}
factory.setExpandEntityReferences(false);
factory.setNamespaceAware(true);
try {
return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
} catch (final Exception e) {
throw new RuntimeException("XML parsing error: " + e);
}
}
/**
* Get an instance of an XML reader from the XMLReaderFactory.
*
@ -52,16 +85,20 @@ public final class XmlUtils {
*/
public static XMLReader getXmlReader() {
try {
final XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
reader.setFeature("http://xml.org/sax/features/namespaces", true);
reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
return reader;
final SAXParserFactory 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);
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
return factory.newSAXParser().getXMLReader();
} catch (final Exception e) {
throw new RuntimeException("Unable to create XMLReader", e);
}
}
/**
* Retrieve the text for a group of elements. Each text element is an entry
* in a list.
@ -81,13 +118,15 @@ public final class XmlUtils {
private StringBuilder buffer = new StringBuilder();
@Override
public void startElement(final String uri, final String localName, final String qName,
final Attributes attributes) throws SAXException {
final Attributes attributes) throws SAXException {
if (localName.equals(element)) {
this.foundElement = true;
}
}
@Override
public void endElement(final String uri, final String localName, final String qName) throws SAXException {
if (localName.equals(element)) {
this.foundElement = false;
@ -96,7 +135,8 @@ public final class XmlUtils {
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
@Override
public void characters(final char[] ch, final int start, final int length) throws SAXException {
if (this.foundElement) {
this.buffer.append(ch, start, length);
}
@ -132,20 +172,23 @@ public final class XmlUtils {
private boolean foundElement = false;
@Override
public void startElement(final String uri, final String localName, final String qName,
final Attributes attributes) throws SAXException {
final Attributes attributes) throws SAXException {
if (localName.equals(element)) {
this.foundElement = true;
}
}
@Override
public void endElement(final String uri, final String localName, final String qName) throws SAXException {
if (localName.equals(element)) {
this.foundElement = false;
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
@Override
public void characters(final char[] ch, final int start, final int length) throws SAXException {
if (this.foundElement) {
builder.append(ch, start, length);
}

View File

@ -1,9 +1,9 @@
<!--
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:

View File

@ -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 the following location:
@ -34,13 +34,10 @@ public abstract class AbstractCasProtocolUrlBasedTicketValidator extends Abstrac
super(casServerUrlPrefix);
}
protected final void setDisableXmlSchemaValidation(final boolean disable) {
// nothing to do
}
/**
* Retrieves the response from the server by opening a connection and merely reading the response.
*/
@Override
protected final String retrieveResponseFromServer(final URL validationUrl, final String ticket) {
return CommonUtils.getResponseFromServer(validationUrl, getURLConnectionFactory(), getEncoding());
}

View File

@ -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 the following location:
@ -25,6 +25,9 @@ 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;
@ -68,6 +71,10 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
*/
private boolean useSession = true;
protected AbstractTicketValidationFilter(final Protocol protocol) {
super(protocol);
}
/**
* Template method to return the appropriate validator.
*
@ -81,12 +88,11 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
/**
* Gets the ssl config to use for HTTPS connections
* if one is configured for this filter.
* @param filterConfig Servlet filter configuration.
* @return Properties that can contains key/trust info for Client Side Certificates
*/
protected Properties getSSLConfig(final FilterConfig filterConfig) {
protected Properties getSSLConfig() {
final Properties properties = new Properties();
final String fileName = getPropertyFromInitParams(filterConfig, "sslConfigFile", null);
final String fileName = getString(ConfigurationKeys.SSL_CONFIG_FILE);
if (fileName != null) {
FileInputStream fis = null;
@ -106,14 +112,11 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
/**
* Gets the configured {@link HostnameVerifier} to use for HTTPS connections
* if one is configured for this filter.
* @param filterConfig Servlet filter configuration.
* @return Instance of specified host name verifier or null if none specified.
*/
protected HostnameVerifier getHostnameVerifier(final FilterConfig filterConfig) {
final String className = getPropertyFromInitParams(filterConfig, "hostnameVerifier", null);
logger.trace("Using hostnameVerifier parameter: {}", className);
final String config = getPropertyFromInitParams(filterConfig, "hostnameVerifierConfig", null);
logger.trace("Using hostnameVerifierConfig parameter: {}", config);
protected HostnameVerifier getHostnameVerifier() {
final Class<? extends HostnameVerifier> className = getClass(ConfigurationKeys.HOSTNAME_VERIFIER);
final String config = getString(ConfigurationKeys.HOSTNAME_VERIFIER_CONFIG);
if (className != null) {
if (config != null) {
return ReflectUtils.newInstance(className, config);
@ -124,15 +127,11 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
return null;
}
@Override
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
setExceptionOnValidationFailure(parseBoolean(getPropertyFromInitParams(filterConfig,
"exceptionOnValidationFailure", "false")));
logger.trace("Setting exceptionOnValidationFailure parameter: {}", this.exceptionOnValidationFailure);
setRedirectAfterValidation(parseBoolean(getPropertyFromInitParams(filterConfig, "redirectAfterValidation",
"true")));
logger.trace("Setting redirectAfterValidation parameter: {}", this.redirectAfterValidation);
setUseSession(parseBoolean(getPropertyFromInitParams(filterConfig, "useSession", "true")));
logger.trace("Setting useSession parameter: {}", this.useSession);
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.");
@ -143,6 +142,7 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
super.initInternal(filterConfig);
}
@Override
public void init() {
super.init();
CommonUtils.assertNotNull(this.ticketValidator, "ticketValidator cannot be null.");
@ -188,8 +188,9 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
// nothing to do here.
}
@Override
public final void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final FilterChain filterChain) throws IOException, ServletException {
if (!preFilter(servletRequest, servletResponse, filterChain)) {
return;
@ -254,4 +255,4 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
public final void setUseSession(final boolean useSession) {
this.useSession = useSession;
}
}
}

View File

@ -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 the following location:
@ -71,8 +71,8 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator
* @param casServerUrlPrefix the location of the CAS server.
*/
protected AbstractUrlBasedTicketValidator(final String casServerUrlPrefix) {
this.casServerUrlPrefix = casServerUrlPrefix;
CommonUtils.assertNotNull(this.casServerUrlPrefix, "casServerUrlPrefix cannot be null.");
CommonUtils.assertNotNull(casServerUrlPrefix, "casServerUrlPrefix cannot be null.");
this.casServerUrlPrefix = CommonUtils.addTrailingSlash(casServerUrlPrefix);
}
/**
@ -90,13 +90,6 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator
*/
protected abstract String getUrlSuffix();
/**
* Disable XML Schema validation. Note, setting this to true may not be reversable. Defaults to false. Setting it to false
* after setting it to true may not have any affect.
*
* @param disabled whether to disable or not.
*/
protected abstract void setDisableXmlSchemaValidation(boolean disabled);
/**
* Constructs the URL to send the validation request to.
@ -131,12 +124,9 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator
int i = 0;
buffer.append(this.casServerUrlPrefix);
if (!this.casServerUrlPrefix.endsWith("/")) {
buffer.append("/");
}
buffer.append(suffix);
for (Map.Entry<String, String> entry : urlParameters.entrySet()) {
for (final Map.Entry<String, String> entry : urlParameters.entrySet()) {
final String key = entry.getKey();
final String value = entry.getValue();
@ -191,6 +181,7 @@ public abstract class AbstractUrlBasedTicketValidator implements TicketValidator
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);

View File

@ -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 the following location:

View File

@ -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 the following location:
@ -101,32 +101,39 @@ public final class AssertionImpl implements Assertion {
CommonUtils.assertNotNull(this.attributes, "attributes cannot be null.");
}
@Override
public Date getAuthenticationDate() {
return this.authenticationDate;
}
@Override
public Date getValidFromDate() {
return this.validFromDate;
}
@Override
public Date getValidUntilDate() {
return this.validUntilDate;
}
@Override
public Map<String, Object> getAttributes() {
return this.attributes;
}
@Override
public AttributePrincipal getPrincipal() {
return this.principal;
}
@Override
public boolean isValid() {
if (this.validFromDate == null) {
return true;
}
final Date now = new Date();
return this.validFromDate.before(now) && (this.validUntilDate == null || this.validUntilDate.after(now));
return (this.validFromDate.before(now) || this.validFromDate.equals(now))
&& (this.validUntilDate == null || this.validUntilDate.after(now) || this.validUntilDate.equals(now));
}
}

View File

@ -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 the following location:
@ -19,29 +19,37 @@
package org.jasig.cas.client.validation;
import javax.servlet.FilterConfig;
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;
/**
* Implementation of AbstractTicketValidatorFilter that instanciates a Cas10TicketValidator.
* Implementation of AbstractTicketValidatorFilter that creates a Cas10TicketValidator.
* <p>Deployers can provide the "casServerPrefix" and the "renew" attributes via the standard context or filter init
* parameters.
*
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1
*/
public class Cas10TicketValidationFilter extends AbstractTicketValidationFilter {
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final String casServerUrlPrefix = getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", null);
final Cas10TicketValidator validator = new Cas10TicketValidator(casServerUrlPrefix);
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
public Cas10TicketValidationFilter() {
super(Protocol.CAS1);
}
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig),
getSSLConfig(filterConfig));
@Override
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final String casServerUrlPrefix = getString(ConfigurationKeys.CAS_SERVER_URL_PREFIX);
final Cas10TicketValidator validator = new Cas10TicketValidator(casServerUrlPrefix);
validator.setRenew(getBoolean(ConfigurationKeys.RENEW));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(),
getSSLConfig());
validator.setURLConnectionFactory(factory);
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));
validator.setEncoding(getString(ConfigurationKeys.ENCODING));
return validator;
}

View File

@ -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 the following location:
@ -35,10 +35,12 @@ public final class Cas10TicketValidator extends AbstractCasProtocolUrlBasedTicke
super(casServerUrlPrefix);
}
@Override
protected String getUrlSuffix() {
return "validate";
}
@Override
protected Assertion parseResponseFromServer(final String response) throws TicketValidationException {
if (!response.startsWith("yes")) {
throw new TicketValidationException("CAS Server could not validate ticket.");

View File

@ -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 the following location:
@ -19,20 +19,27 @@
package org.jasig.cas.client.validation;
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.*;
/**
* Creates either a CAS20ProxyTicketValidator or a CAS20ServiceTicketValidator depending on whether any of the
* proxy parameters are set.
* <p>
* <p/>
* 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}.
*
@ -40,20 +47,20 @@ import org.jasig.cas.client.util.ReflectUtils;
* @author Brad Cupit (brad [at] lsu {dot} edu)
* @version $Revision$ $Date$
* @since 3.1
*
*/
public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketValidationFilter {
private static final String[] RESERVED_INIT_PARAMS = new String[] { "proxyGrantingTicketStorageClass",
"proxyReceptorUrl", "acceptAnyProxy", "allowedProxyChains", "casServerUrlPrefix", "proxyCallbackUrl",
"renew", "exceptionOnValidationFailure", "redirectAfterValidation", "useSession", "serverName", "service",
"artifactParameterName", "serviceParameterName", "encodeServiceUrl", "millisBetweenCleanUps",
"hostnameVerifier", "encoding", "config", "ticketValidatorClass" };
private static final int DEFAULT_MILLIS_BETWEEN_CLEANUPS = 60 * 1000;
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()
};
/**
* The URL to send to the CAS server as the URL that will process proxying requests on the CAS client.
* The URL to send to the CAS server as the URL that will process proxying requests on the CAS client.
*/
private String proxyReceptorUrl;
@ -63,25 +70,40 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
private int millisBetweenCleanUps;
protected Class<? extends Cas20ServiceTicketValidator> defaultServiceTicketValidatorClass;
protected Class<? extends Cas20ProxyTicketValidator> defaultProxyTicketValidatorClass;
private PrivateKey privateKey;
/**
* Storage location of ProxyGrantingTickets and Proxy Ticket IOUs.
*/
private ProxyGrantingTicketStorage proxyGrantingTicketStorage = new ProxyGrantingTicketStorageImpl();
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
setProxyReceptorUrl(getPropertyFromInitParams(filterConfig, "proxyReceptorUrl", null));
public Cas20ProxyReceivingTicketValidationFilter() {
this(Protocol.CAS2);
this.defaultServiceTicketValidatorClass = Cas20ServiceTicketValidator.class;
this.defaultProxyTicketValidatorClass = Cas20ProxyTicketValidator.class;
}
final String proxyGrantingTicketStorageClass = getPropertyFromInitParams(filterConfig,
"proxyGrantingTicketStorageClass", null);
protected Cas20ProxyReceivingTicketValidationFilter(final Protocol protocol) {
super(protocol);
}
@Override
protected void initInternal(final FilterConfig filterConfig) throws ServletException {
setProxyReceptorUrl(getString(ConfigurationKeys.PROXY_RECEPTOR_URL));
final Class<? extends ProxyGrantingTicketStorage> 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 = getPropertyFromInitParams(filterConfig, "cipherAlgorithm",
AbstractEncryptedProxyGrantingTicketStorageImpl.DEFAULT_ENCRYPTION_ALGORITHM);
final String secretKey = getPropertyFromInitParams(filterConfig, "secretKey", null);
final String cipherAlgorithm = getString(ConfigurationKeys.CIPHER_ALGORITHM);
final String secretKey = getString(ConfigurationKeys.SECRET_KEY);
p.setCipherAlgorithm(cipherAlgorithm);
@ -95,12 +117,13 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
}
}
logger.trace("Setting proxyReceptorUrl parameter: {}", this.proxyReceptorUrl);
this.millisBetweenCleanUps = Integer.parseInt(getPropertyFromInitParams(filterConfig, "millisBetweenCleanUps",
Integer.toString(DEFAULT_MILLIS_BETWEEN_CLEANUPS)));
this.millisBetweenCleanUps = getInt(ConfigurationKeys.MILLIS_BETWEEN_CLEAN_UPS);
this.privateKey = buildPrivateKey(getString(PRIVATE_KEY_PATH), getString(PRIVATE_KEY_ALGORITHM));
super.initInternal(filterConfig);
}
@Override
public void init() {
super.init();
CommonUtils.assertNotNull(this.proxyGrantingTicketStorage, "proxyGrantingTicketStorage cannot be null.");
@ -115,13 +138,20 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
this.timer.schedule(this.timerTask, this.millisBetweenCleanUps, this.millisBetweenCleanUps);
}
private <T> T createNewTicketValidator(final String ticketValidatorClass, final String casServerUrlPrefix,
final Class<T> clazz) {
if (CommonUtils.isBlank(ticketValidatorClass)) {
private <T> T createNewTicketValidator(final Class<? extends Cas20ServiceTicketValidator> ticketValidatorClass, final String casServerUrlPrefix,
final Class<T> clazz) {
if (ticketValidatorClass == null) {
return ReflectUtils.newInstance(clazz, casServerUrlPrefix);
}
return ReflectUtils.newInstance(ticketValidatorClass, 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;
}
/**
@ -130,39 +160,39 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
* @param filterConfig the Filter Configuration object.
* @return a fully constructed TicketValidator.
*/
@Override
protected final TicketValidator getTicketValidator(final FilterConfig filterConfig) {
final String allowAnyProxy = getPropertyFromInitParams(filterConfig, "acceptAnyProxy", null);
final String allowedProxyChains = getPropertyFromInitParams(filterConfig, "allowedProxyChains", null);
final String casServerUrlPrefix = getPropertyFromInitParams(filterConfig, "casServerUrlPrefix", null);
final String ticketValidatorClass = getPropertyFromInitParams(filterConfig, "ticketValidatorClass", null);
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<? extends Cas20ServiceTicketValidator> ticketValidatorClass = getClass(ConfigurationKeys.TICKET_VALIDATOR_CLASS);
final Cas20ServiceTicketValidator validator;
if (CommonUtils.isNotBlank(allowAnyProxy) || CommonUtils.isNotBlank(allowedProxyChains)) {
if (allowAnyProxy || CommonUtils.isNotBlank(allowedProxyChains)) {
final Cas20ProxyTicketValidator v = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix,
Cas20ProxyTicketValidator.class);
v.setAcceptAnyProxy(parseBoolean(allowAnyProxy));
this.defaultProxyTicketValidatorClass);
v.setAcceptAnyProxy(allowAnyProxy);
v.setAllowedProxyChains(CommonUtils.createProxyList(allowedProxyChains));
validator = v;
} else {
validator = createNewTicketValidator(ticketValidatorClass, casServerUrlPrefix,
Cas20ServiceTicketValidator.class);
this.defaultServiceTicketValidatorClass);
}
validator.setProxyCallbackUrl(getPropertyFromInitParams(filterConfig, "proxyCallbackUrl", null));
validator.setProxyCallbackUrl(getString(ConfigurationKeys.PROXY_CALLBACK_URL));
validator.setProxyGrantingTicketStorage(this.proxyGrantingTicketStorage);
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(filterConfig),
getSSLConfig(filterConfig));
final HttpURLConnectionFactory factory = new HttpsURLConnectionFactory(getHostnameVerifier(),
getSSLConfig());
validator.setURLConnectionFactory(factory);
validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getPropertyFromInitParams(filterConfig,
"encoding", null), factory));
validator.setRenew(parseBoolean(getPropertyFromInitParams(filterConfig, "renew", "false")));
validator.setEncoding(getPropertyFromInitParams(filterConfig, "encoding", null));
validator.setProxyRetriever(new Cas20ProxyRetriever(casServerUrlPrefix, getString(ConfigurationKeys.ENCODING), factory));
validator.setRenew(getBoolean(ConfigurationKeys.RENEW));
validator.setEncoding(getString(ConfigurationKeys.ENCODING));
final Map<String, String> additionalParameters = new HashMap<String, String>();
final List<String> params = Arrays.asList(RESERVED_INIT_PARAMS);
for (final Enumeration<?> e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
for (final Enumeration<?> e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) {
final String s = (String) e.nextElement();
if (!params.contains(s)) {
@ -170,10 +200,13 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
}
}
validator.setPrivateKey(this.privateKey);
validator.setCustomParameters(additionalParameters);
return validator;
}
@Override
public void destroy() {
super.destroy();
this.timer.cancel();
@ -182,8 +215,9 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
/**
* 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 FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final String requestUri = request.getRequestURI();

View File

@ -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 the following location:
@ -18,6 +18,7 @@
*/
package org.jasig.cas.client.validation;
import java.util.Arrays;
import java.util.List;
import org.jasig.cas.client.util.XmlUtils;
@ -45,16 +46,32 @@ public class Cas20ProxyTicketValidator extends Cas20ServiceTicketValidator {
return this.allowedProxyChains;
}
@Override
protected String getUrlSuffix() {
return "proxyValidate";
}
@Override
protected void customParseResponse(final String response, final Assertion assertion)
throws TicketValidationException {
final List<String> proxies = XmlUtils.getTextForElements(response, "proxy");
final List<String> 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."
);
}
// this means there was nothing in the proxy chain, which is okay
if ((this.allowEmptyProxyChain && proxies.isEmpty()) || this.acceptAnyProxy) {
if (this.allowEmptyProxyChain && proxies.isEmpty()) {
logger.debug("Found an empty proxy chain, permitted by client configuration");
return;
}
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.");
return;
}
@ -63,9 +80,17 @@ public class Cas20ProxyTicketValidator extends Cas20ServiceTicketValidator {
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);
throw new InvalidProxyChainTicketValidationException("Invalid proxy chain: " + proxies.toString());
}
protected List<String> parseProxiesFromResponse(final String response) {
return XmlUtils.getTextForElements(response, "proxy");
}
public final void setAcceptAnyProxy(final boolean acceptAnyProxy) {
this.acceptAnyProxy = acceptAnyProxy;
}

View File

@ -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 the following location:
@ -19,9 +19,13 @@
package org.jasig.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.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;
@ -43,6 +47,9 @@ import org.xml.sax.helpers.DefaultHandler;
*/
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. */
private String proxyCallbackUrl;
@ -52,12 +59,14 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
/** Implementation of the proxy retriever. */
private ProxyRetriever proxyRetriever;
/** Private key for decryption */
private PrivateKey privateKey;
/**
* Constructs an instance of the CAS 2.0 Service Ticket Validator with the supplied
* CAS server url prefix.
*
* @param casServerUrlPrefix the CAS Server URL prefix.
* @param urlFactory URL connection factory to use when communicating with the server
*/
public Cas20ServiceTicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
@ -69,30 +78,26 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
*
* @param urlParameters the Map containing the existing parameters to send to the server.
*/
@Override
protected final void populateUrlAttributeMap(final Map<String, String> urlParameters) {
urlParameters.put("pgtUrl", this.proxyCallbackUrl);
}
@Override
protected String getUrlSuffix() {
return "serviceValidate";
}
protected final Assertion parseResponseFromServer(final String response) throws TicketValidationException {
final String error = XmlUtils.getTextForElement(response, "authenticationFailure");
@Override
protected Assertion parseResponseFromServer(final String response) throws TicketValidationException {
final String error = parseAuthenticationFailureFromResponse(response);
if (CommonUtils.isNotBlank(error)) {
throw new TicketValidationException(error);
}
final String principal = XmlUtils.getTextForElement(response, "user");
final String proxyGrantingTicketIou = XmlUtils.getTextForElement(response, "proxyGrantingTicket");
final String proxyGrantingTicket;
if (CommonUtils.isBlank(proxyGrantingTicketIou) || this.proxyGrantingTicketStorage == null) {
proxyGrantingTicket = null;
} else {
proxyGrantingTicket = this.proxyGrantingTicketStorage.retrieve(proxyGrantingTicketIou);
}
final String principal = parsePrincipalFromResponse(response);
final String proxyGrantingTicket = retrieveProxyGrantingTicket(response);
if (CommonUtils.isEmpty(principal)) {
throw new TicketValidationException("No principal was found in the response from the CAS server.");
@ -101,6 +106,7 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
final Assertion assertion;
final Map<String, Object> attributes = extractCustomAttributes(response);
if (CommonUtils.isNotBlank(proxyGrantingTicket)) {
attributes.remove(PGT_ATTRIBUTE);
final AttributePrincipal attributePrincipal = new AttributePrincipalImpl(principal, attributes,
proxyGrantingTicket, this.proxyRetriever);
assertion = new AssertionImpl(attributePrincipal);
@ -113,6 +119,52 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
return assertion;
}
protected String retrieveProxyGrantingTicket(final String response) {
final List<String> values = XmlUtils.getTextForElements(response, PGT_ATTRIBUTE);
for (final String value : values) {
if (value != null) {
if (value.startsWith(PGTIOU_PREFIX)) {
return retrieveProxyGrantingTicketFromStorage(value);
} else {
return retrieveProxyGrantingTicketViaEncryption(value);
}
}
}
return null;
}
protected String retrieveProxyGrantingTicketFromStorage(final String pgtIou) {
if (this.proxyGrantingTicketStorage != null) {
return this.proxyGrantingTicketStorage.retrieve(pgtIou);
}
return null;
}
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);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
final byte[] cipherData = cipher.doFinal(cred64);
final String pgt = new String(cipherData);
logger.debug("Decrypted PGT: {}", pgt);
return pgt;
} catch (final Exception e) {
logger.error("Unable to decrypt PGT", e);
}
}
return null;
}
protected String parsePrincipalFromResponse(final String response) {
return XmlUtils.getTextForElement(response, "user");
}
protected String parseAuthenticationFailureFromResponse(final String response) {
return XmlUtils.getTextForElement(response, "authenticationFailure");
}
/**
* Default attribute parsing of attributes that look like the following:
* &lt;cas:attributes&gt;
@ -246,4 +298,12 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
return this.attributes;
}
}
public PrivateKey getPrivateKey() {
return privateKey;
}
public void setPrivateKey(final PrivateKey privateKey) {
this.privateKey = privateKey;
}
}

View File

@ -0,0 +1,40 @@
/**
* 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 org.jasig.cas.client.Protocol;
/**
* Creates either a Cas30ProxyTicketValidator or a Cas30ServiceTicketValidator depending on whether any of the
* proxy parameters are set.
* <p/>
* 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}.
*
* @author Jerome Leleu
* @since 3.4.0
*/
public class Cas30ProxyReceivingTicketValidationFilter extends Cas20ProxyReceivingTicketValidationFilter {
public Cas30ProxyReceivingTicketValidationFilter() {
super(Protocol.CAS3);
this.defaultServiceTicketValidatorClass = Cas30ServiceTicketValidator.class;
this.defaultProxyTicketValidatorClass = Cas30ProxyTicketValidator.class;
}
}

View File

@ -0,0 +1,37 @@
/**
* 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;
/**
* Service and proxy tickets validation service for the CAS protocol v3.
*
* @author Jerome Leleu
* @since 3.4.0
*/
public class Cas30ProxyTicketValidator extends Cas20ProxyTicketValidator {
public Cas30ProxyTicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
}
@Override
protected String getUrlSuffix() {
return "p3/proxyValidate";
}
}

View File

@ -0,0 +1,90 @@
/**
* 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 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 java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Service tickets validation service for the CAS protocol v3.
*
* @author Jerome Leleu
* @since 3.4.0
*/
public class Cas30ServiceTicketValidator extends Cas20ServiceTicketValidator {
public Cas30ServiceTicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
}
@Override
protected String getUrlSuffix() {
return "p3/serviceValidate";
}
/**
* Custom attribute extractor that will account for inlined CAS attributes. Useful when CAS is acting as
* as SAML 2 IdP and returns SAML attributes with names that contains namespaces.
*
* @param xml the XML to parse.
* @return - Map of attributes
*/
@Override
protected Map<String, Object> extractCustomAttributes(final String xml) {
final Document document = XmlUtils.newDocument(xml);
// Check if attributes are inlined. If not return default super method results
final NodeList attributeList = document.getElementsByTagName("cas:attribute");
if (attributeList.getLength() == 0) {
return super.extractCustomAttributes(xml);
}
final HashMap<String, Object> attributes = new HashMap<String, Object>();
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);
if (mapValue != null) {
if (mapValue instanceof List) {
((List) mapValue).add(value);
} else {
final LinkedList<Object> list = new LinkedList<Object>();
list.add(mapValue);
list.add(value);
attributes.put(name, list);
}
} else {
attributes.put(name, value);
}
}
return attributes;
}
}

View File

@ -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 the following location:

View File

@ -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 the following location:
@ -19,9 +19,13 @@
package org.jasig.cas.client.validation;
import java.util.ArrayList;
import java.util.Arrays;
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;
/**
* Holding class for the proxy list to make Spring configuration easier.
@ -32,24 +36,62 @@ import org.jasig.cas.client.util.CommonUtils;
*/
public final class ProxyList {
private final List<String[]> proxyChains;
private final Logger logger = LoggerFactory.getLogger(getClass());
private final List<List<UrlPatternMatcherStrategy>> proxyChains;
public ProxyList(final List<String[]> proxyChains) {
CommonUtils.assertNotNull(proxyChains, "List of proxy chains cannot be null.");
this.proxyChains = proxyChains;
this.proxyChains = new ArrayList<List<UrlPatternMatcherStrategy>>();
for (final String[] list : proxyChains) {
final List<UrlPatternMatcherStrategy> chain = new ArrayList<UrlPatternMatcherStrategy>();
for (final String item : list) {
if (item.startsWith("^")) {
chain.add(new RegexUrlPatternMatcherStrategy(item));
} else {
chain.add(new ExactUrlPatternMatcherStrategy(item));
}
}
this.proxyChains.add(chain);
}
}
public ProxyList() {
this(new ArrayList<String[]>());
}
public boolean contains(String[] proxiedList) {
for (final String[] list : this.proxyChains) {
if (Arrays.equals(proxiedList, list)) {
return true;
public boolean contains(final String[] proxiedList) {
StringBuilder loggingOutput;
for (final List<UrlPatternMatcherStrategy> proxyChain : this.proxyChains) {
loggingOutput = new StringBuilder();
if (proxyChain.size() == proxiedList.length) {
for (int linkIndex = 0; linkIndex < proxyChain.size(); linkIndex++) {
final String linkToTest = proxiedList[linkIndex];
loggingOutput.append(linkToTest);
if (proxyChain.get(linkIndex).matches(linkToTest)) {
//If we are at the last link, we found a good proxyChain.
if (linkIndex == proxyChain.size() - 1) {
logger.info("Proxy chain matched: {}", loggingOutput.toString());
return true;
}
} else {
logger.warn("Proxy chain did not match at {}. Skipping to next allowedProxyChain", loggingOutput.toString());
break;
}
loggingOutput.append("->");
}
}
}
logger.warn("No proxy chain matched the allowedProxyChains list.");
return false;
}

View File

@ -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 the following location:
@ -36,6 +36,7 @@ import org.jasig.cas.client.util.CommonUtils;
*/
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<String[]> proxyChains = new ArrayList<String[]>();

View File

@ -1,288 +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.
*/
package org.jasig.cas.client.validation;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
import org.jasig.cas.client.util.CommonUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Interval;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.IdentifierGenerator;
import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
import org.opensaml.saml1.core.*;
import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.io.UnmarshallingException;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.parse.XMLParserException;
import org.opensaml.xml.schema.XSAny;
import org.opensaml.xml.schema.XSString;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* TicketValidator that can understand validating a SAML artifact. This includes the SOAP request/response.
*
* @author Scott Battaglia
* @since 3.1
*/
public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator {
static {
try {
// we really only need to do this once, so this is why its here.
DefaultBootstrap.bootstrap();
} catch (final ConfigurationException e) {
throw new RuntimeException(e);
}
}
/** Time tolerance to allow for time drifting. */
private long tolerance = 1000L;
private final BasicParserPool basicParserPool;
private final IdentifierGenerator identifierGenerator;
public Saml11TicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
this.basicParserPool = new BasicParserPool();
this.basicParserPool.setNamespaceAware(true);
try {
this.identifierGenerator = new SecureRandomIdentifierGenerator();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
protected String getUrlSuffix() {
return "samlValidate";
}
protected void populateUrlAttributeMap(final Map<String, String> urlParameters) {
final String service = urlParameters.get("service");
urlParameters.remove("service");
urlParameters.remove("ticket");
urlParameters.put("TARGET", service);
}
@Override
protected void setDisableXmlSchemaValidation(final boolean disabled) {
if (disabled) {
this.basicParserPool.setSchema(null);
}
}
protected byte[] getBytes(final String text) {
try {
return CommonUtils.isNotBlank(getEncoding()) ? text.getBytes(getEncoding()) : text.getBytes();
} catch (final Exception e) {
return text.getBytes();
}
}
protected Assertion parseResponseFromServer(final String response) throws TicketValidationException {
try {
final Document responseDocument = this.basicParserPool.parse(new ByteArrayInputStream(getBytes(response)));
final Element responseRoot = responseDocument.getDocumentElement();
final UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
final Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(responseRoot);
final Envelope envelope = (Envelope) unmarshaller.unmarshall(responseRoot);
final Response samlResponse = (Response) envelope.getBody().getOrderedChildren().get(0);
final List<org.opensaml.saml1.core.Assertion> assertions = samlResponse.getAssertions();
if (assertions.isEmpty()) {
throw new TicketValidationException("No assertions found.");
}
for (final org.opensaml.saml1.core.Assertion assertion : assertions) {
if (!isValidAssertion(assertion)) {
continue;
}
final AuthenticationStatement authenticationStatement = getSAMLAuthenticationStatement(assertion);
if (authenticationStatement == null) {
throw new TicketValidationException("No AuthentiationStatement found in SAML Assertion.");
}
final Subject subject = authenticationStatement.getSubject();
if (subject == null) {
throw new TicketValidationException("No Subject found in SAML Assertion.");
}
final List<Attribute> attributes = getAttributesFor(assertion, subject);
final Map<String, Object> personAttributes = new HashMap<String, Object>();
for (final Attribute samlAttribute : attributes) {
final List<?> values = getValuesFrom(samlAttribute);
personAttributes.put(samlAttribute.getAttributeName(), values.size() == 1 ? values.get(0) : values);
}
final AttributePrincipal principal = new AttributePrincipalImpl(subject.getNameIdentifier()
.getNameIdentifier(), personAttributes);
final Map<String, Object> authenticationAttributes = new HashMap<String, Object>();
authenticationAttributes.put("samlAuthenticationStatement::authMethod",
authenticationStatement.getAuthenticationMethod());
final DateTime notBefore = assertion.getConditions().getNotBefore();
final DateTime notOnOrAfter = assertion.getConditions().getNotOnOrAfter();
final DateTime authenticationInstant = authenticationStatement.getAuthenticationInstant();
return new AssertionImpl(principal, notBefore.toDate(), notOnOrAfter.toDate(),
authenticationInstant.toDate(), authenticationAttributes);
}
} catch (final UnmarshallingException e) {
throw new TicketValidationException(e);
} catch (final XMLParserException e) {
throw new TicketValidationException(e);
}
throw new TicketValidationException(
"No Assertion found within valid time range. Either there's a replay of the ticket or there's clock drift. Check tolerance range, or server/client synchronization.");
}
private boolean isValidAssertion(final org.opensaml.saml1.core.Assertion assertion) {
final DateTime notBefore = assertion.getConditions().getNotBefore();
final DateTime notOnOrAfter = assertion.getConditions().getNotOnOrAfter();
if (notBefore == null || notOnOrAfter == null) {
logger.debug("Assertion has no bounding dates. Will not process.");
return false;
}
final DateTime currentTime = new DateTime(DateTimeZone.UTC);
final Interval validityRange = new Interval(notBefore.minus(this.tolerance), notOnOrAfter.plus(this.tolerance));
if (validityRange.contains(currentTime)) {
logger.debug("Current time is within the interval validity.");
return true;
}
if (currentTime.isBefore(validityRange.getStart())) {
logger.debug("skipping assertion that's not yet valid...");
return false;
}
logger.debug("skipping expired assertion...");
return false;
}
private AuthenticationStatement getSAMLAuthenticationStatement(final org.opensaml.saml1.core.Assertion assertion) {
final List<AuthenticationStatement> statements = assertion.getAuthenticationStatements();
if (statements.isEmpty()) {
return null;
}
return statements.get(0);
}
private List<Attribute> getAttributesFor(final org.opensaml.saml1.core.Assertion assertion, final Subject subject) {
final List<Attribute> attributes = new ArrayList<Attribute>();
for (final AttributeStatement attribute : assertion.getAttributeStatements()) {
if (subject.getNameIdentifier().getNameIdentifier()
.equals(attribute.getSubject().getNameIdentifier().getNameIdentifier())) {
attributes.addAll(attribute.getAttributes());
}
}
return attributes;
}
private List<?> getValuesFrom(final Attribute attribute) {
final List<Object> list = new ArrayList<Object>();
for (final Object o : attribute.getAttributeValues()) {
if (o instanceof XSAny) {
list.add(((XSAny) o).getTextContent());
} else if (o instanceof XSString) {
list.add(((XSString) o).getValue());
} else {
list.add(o.toString());
}
}
return list;
}
protected String retrieveResponseFromServer(final URL validationUrl, final String ticket) {
final String MESSAGE_TO_SEND = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body><samlp:Request xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" MajorVersion=\"1\" MinorVersion=\"1\" RequestID=\""
+ this.identifierGenerator.generateIdentifier()
+ "\" IssueInstant=\""
+ CommonUtils.formatForUtcTime(new Date())
+ "\">"
+ "<samlp:AssertionArtifact>"
+ ticket
+ "</samlp:AssertionArtifact></samlp:Request></SOAP-ENV:Body></SOAP-ENV:Envelope>";
HttpURLConnection conn = null;
DataOutputStream out = null;
BufferedReader in = null;
try {
conn = this.getURLConnectionFactory().buildHttpURLConnection(validationUrl.openConnection());
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml");
conn.setRequestProperty("Content-Length", Integer.toString(MESSAGE_TO_SEND.length()));
conn.setRequestProperty("SOAPAction", "http://www.oasis-open.org/committees/security");
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(MESSAGE_TO_SEND);
out.flush();
in = new BufferedReader(CommonUtils.isNotBlank(getEncoding()) ? new InputStreamReader(
conn.getInputStream(), Charset.forName(getEncoding())) : new InputStreamReader(
conn.getInputStream()));
final StringBuilder buffer = new StringBuilder(256);
String line;
while ((line = in.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (final IOException e) {
throw new RuntimeException(e);
} finally {
CommonUtils.closeQuietly(out);
CommonUtils.closeQuietly(in);
if (conn != null) {
conn.disconnect();
}
}
}
public void setTolerance(final long tolerance) {
this.tolerance = tolerance;
}
}

View File

@ -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 the following location:

View File

@ -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 the following location:

View File

@ -0,0 +1,35 @@
/**
* 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.json;
import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter;
/**
* Creates either a Cas30JsonServiceTicketValidator to validate tickets.
*
* @author Misagh Moayyed
*/
public class Cas30JsonProxyReceivingTicketValidationFilter extends Cas30ProxyReceivingTicketValidationFilter {
public Cas30JsonProxyReceivingTicketValidationFilter() {
super();
this.defaultServiceTicketValidatorClass = Cas30JsonServiceTicketValidator.class;
this.defaultProxyTicketValidatorClass = Cas30JsonProxyTicketValidator.class;
}
}

View File

@ -0,0 +1,61 @@
/**
* 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.json;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.Cas30ProxyTicketValidator;
import org.jasig.cas.client.validation.TicketValidationException;
import java.util.Collections;
import java.util.List;
/**
* This is {@link Cas30JsonProxyTicketValidator} that attempts to parse the CAS validation response
* as JSON. Very similar to {@link Cas30JsonServiceTicketValidator}, it also honors proxies as the name suggests.
*
* @author Misagh Moayyed
*/
public class Cas30JsonProxyTicketValidator extends Cas30ProxyTicketValidator {
public Cas30JsonProxyTicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
setCustomParameters(Collections.singletonMap("format", "JSON"));
}
@Override
protected Assertion parseResponseFromServer(final String response) throws TicketValidationException {
try {
final TicketValidationJsonResponse json = new JsonValidationResponseParser().parse(response);
return json.getAssertion(getProxyGrantingTicketStorage(), getProxyRetriever());
} catch (final Exception e) {
logger.warn("Unable parse the JSON response");
return super.parseResponseFromServer(response);
}
}
@Override
protected List<String> parseProxiesFromResponse(final String response) {
try {
final TicketValidationJsonResponse json = new JsonValidationResponseParser().parse(response);
return json.getServiceResponse().getAuthenticationSuccess().getProxies();
} catch (final Exception e) {
logger.warn("Unable to locate proxies from the JSON response", e);
return super.parseProxiesFromResponse(response);
}
}
}

View File

@ -0,0 +1,62 @@
/**
* 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.json;
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;
import java.util.Map;
/**
* This is {@link Cas30JsonServiceTicketValidator} that attempts to parse the CAS validation response
* as JSON. If the response is not formatted as JSON, it shall fallback to the XML default syntax.
* The JSON response provides advantages in terms of naming and parsing CAS attributes that have special
* names that otherwise may not be encoded as XML, such as the invalid {@code <cas:special:attribute>value</cas:special:attribute>}
*
* @author Misagh Moayyed
*/
public class Cas30JsonServiceTicketValidator extends Cas30ServiceTicketValidator {
public Cas30JsonServiceTicketValidator(final String casServerUrlPrefix) {
super(casServerUrlPrefix);
setCustomParameters(Collections.singletonMap("format", "JSON"));
}
@Override
protected Assertion parseResponseFromServer(final String response) throws TicketValidationException {
try {
final TicketValidationJsonResponse 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);
return super.parseResponseFromServer(response);
} catch (final IOException e) {
throw new TicketValidationException(e.getMessage(), e);
}
}
@Override
protected Map<String, Object> extractCustomAttributes(final String xml) {
return Collections.emptyMap();
}
}

View File

@ -0,0 +1,66 @@
/**
* 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.json;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.TicketValidationException;
import java.io.IOException;
/**
* This is {@link JsonValidationResponseParser}.
*
* @author Misagh Moayyed
*/
final class JsonValidationResponseParser {
private final ObjectMapper objectMapper;
public JsonValidationResponseParser() {
this.objectMapper = new ObjectMapper();
this.objectMapper.findAndRegisterModules();
}
public TicketValidationJsonResponse parse(final String response) throws TicketValidationException, IOException {
if (CommonUtils.isBlank(response)) {
throw new TicketValidationException("Invalid JSON response; The response is empty");
}
final TicketValidationJsonResponse json = this.objectMapper.readValue(response, TicketValidationJsonResponse.class);
final TicketValidationJsonResponse.CasServiceResponseAuthentication serviceResponse = json.getServiceResponse();
if (serviceResponse.getAuthenticationFailure() != null
&& serviceResponse.getAuthenticationSuccess() != 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);
}
if (serviceResponse.getAuthenticationFailure() != null) {
final String error = json.getServiceResponse().getAuthenticationFailure().getCode()
+ " - " + serviceResponse.getAuthenticationFailure().getDescription();
throw new TicketValidationException(error);
}
final String principal = json.getServiceResponse().getAuthenticationSuccess().getUser();
if (CommonUtils.isEmpty(principal)) {
throw new TicketValidationException("No principal was found in the response from the CAS server.");
}
return json;
}
}

View File

@ -0,0 +1,158 @@
/**
* 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.json;
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;
/**
* This is {@link TicketValidationJsonResponse}.
*
* @author Misagh Moayyed
*/
final class TicketValidationJsonResponse {
private final CasServiceResponseAuthentication serviceResponse;
@JsonCreator
public 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<String, Object> 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;
@JsonCreator
public 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() {
return this.user;
}
public void setUser(final String user) {
this.user = user;
}
public String getProxyGrantingTicket() {
return this.proxyGrantingTicket;
}
public void setProxyGrantingTicket(final String proxyGrantingTicket) {
this.proxyGrantingTicket = proxyGrantingTicket;
}
public List getProxies() {
return this.proxies;
}
public void setProxies(final List proxies) {
this.proxies = proxies;
}
public Map getAttributes() {
return this.attributes;
}
public void setAttributes(final Map attributes) {
this.attributes = attributes;
}
}
static class CasServiceResponseAuthenticationFailure {
private String code;
private String description;
public String getCode() {
return this.code;
}
public void setCode(final String code) {
this.code = code;
}
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
}
}

Some files were not shown because too many files have changed in this diff Show More