├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── deploy-docs.yml │ ├── release-scheduler.yml │ └── update-scheduled-release-version.yml ├── .gitignore ├── .sdkmanrc ├── .vscode ├── launch.json └── settings.json ├── CODE_OF_CONDUCT.adoc ├── CONTRIBUTING.md ├── README.adoc ├── build.gradle ├── buildSrc ├── build.gradle └── src │ └── main │ ├── groovy │ ├── io │ │ └── spring │ │ │ └── gradle │ │ │ └── convention │ │ │ └── SpringMavenBomPlugin.groovy │ └── org │ │ └── springframework │ │ └── gradle │ │ └── docs │ │ └── SpringDeployDocsPlugin.groovy │ ├── java │ ├── io │ │ └── spring │ │ │ └── gradle │ │ │ └── convention │ │ │ ├── SpringDocsPlugin.java │ │ │ ├── SpringModulePlugin.java │ │ │ └── SpringRootProjectPlugin.java │ └── org │ │ └── springframework │ │ ├── gradle │ │ ├── ProjectUtils.java │ │ ├── SpringJavaPlugin.java │ │ ├── SpringMavenPlugin.java │ │ ├── checkstyle │ │ │ └── SpringJavaCheckstylePlugin.java │ │ ├── classpath │ │ │ ├── CheckClasspathForProhibitedDependencies.java │ │ │ ├── SpringCheckClasspathForProhibitedDependenciesPlugin.java │ │ │ └── SpringCheckProhibitedDependenciesLifecyclePlugin.java │ │ ├── docs │ │ │ ├── SpringAsciidoctorPlugin.java │ │ │ ├── SpringJavadocApiPlugin.java │ │ │ └── SpringJavadocOptionsPlugin.java │ │ ├── jacoco │ │ │ └── SpringJacocoPlugin.java │ │ ├── management │ │ │ └── SpringManagementConfigurationPlugin.java │ │ ├── maven │ │ │ ├── SpringArtifactoryPlugin.java │ │ │ ├── SpringMavenPublishingConventionsPlugin.java │ │ │ ├── SpringNexusPlugin.java │ │ │ ├── SpringPublishAllJavaComponentsPlugin.java │ │ │ ├── SpringPublishArtifactsPlugin.java │ │ │ ├── SpringPublishLocalPlugin.java │ │ │ ├── SpringRepositoryPlugin.java │ │ │ └── SpringSigningPlugin.java │ │ ├── nohttp │ │ │ └── SpringNoHttpPlugin.java │ │ ├── propdeps │ │ │ ├── SpringPropDepsEclipsePlugin.java │ │ │ ├── SpringPropDepsIdeaPlugin.java │ │ │ └── SpringPropDepsPlugin.java │ │ ├── properties │ │ │ └── SpringCopyPropertiesPlugin.java │ │ └── sonarqube │ │ │ └── SpringSonarQubePlugin.java │ │ └── security │ │ └── kerberos │ │ └── gradle │ │ ├── JavaConventions.java │ │ └── SamplePlugin.java │ └── resources │ └── META-INF │ └── gradle-plugins │ ├── io.spring.convention.bom.properties │ ├── io.spring.convention.docs.properties │ ├── io.spring.convention.root.properties │ ├── io.spring.convention.spring-module.properties │ └── org.springframework.gradle.deploy-docs.properties ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts └── release │ └── release-notes-sections.yml ├── settings.gradle ├── spring-security-kerberos-bom └── spring-security-kerberos-bom.gradle ├── spring-security-kerberos-client ├── spring-security-kerberos-client.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── springframework │ │ └── security │ │ └── kerberos │ │ └── client │ │ ├── KerberosRestTemplate.java │ │ ├── config │ │ └── SunJaasKrb5LoginConfig.java │ │ └── ldap │ │ └── KerberosLdapContextSource.java │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── security │ │ └── kerberos │ │ └── client │ │ └── KerberosRestTemplateTests.java │ └── resources │ ├── log4j.properties │ ├── minikdc-krb5.conf │ └── minikdc.ldiff ├── spring-security-kerberos-core ├── spring-security-kerberos-core.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── springframework │ │ └── security │ │ └── kerberos │ │ └── authentication │ │ ├── JaasSubjectHolder.java │ │ ├── KerberosAuthentication.java │ │ ├── KerberosAuthenticationProvider.java │ │ ├── KerberosClient.java │ │ ├── KerberosMultiTier.java │ │ ├── KerberosServiceAuthenticationProvider.java │ │ ├── KerberosServiceRequestToken.java │ │ ├── KerberosTicketValidation.java │ │ ├── KerberosTicketValidator.java │ │ ├── KerberosUsernamePasswordAuthenticationToken.java │ │ └── sun │ │ ├── GlobalSunJaasKerberosConfig.java │ │ ├── JaasUtil.java │ │ ├── SunJaasKerberosClient.java │ │ └── SunJaasKerberosTicketValidator.java │ └── test │ └── java │ └── org │ └── springframework │ └── security │ └── kerberos │ └── authentication │ ├── KerberosAuthenticationProviderTest.java │ ├── KerberosServiceAuthenticationProviderTest.java │ ├── KerberosTicketValidationTest.java │ └── sun │ └── SunJaasKerberosTicketValidatorTests.java ├── spring-security-kerberos-docs ├── antora-playbook.yml ├── antora.yml ├── modules │ └── ROOT │ │ ├── examples │ │ ├── AuthProviderConfig.java │ │ ├── AuthProviderConfigTest.java │ │ ├── DummyUserDetailsService.java │ │ ├── KerberosLdapContextSourceConfig.java │ │ ├── KerberosRestTemplateConfig.java │ │ └── SpnegoConfig.java │ │ ├── images │ │ ├── drawio-kerb-cc1.png │ │ ├── drawio-kerb-cc2.png │ │ ├── drawio-kerb-cc3.png │ │ ├── drawio-kerb-cc4.png │ │ ├── ff1.png │ │ ├── ff2.png │ │ ├── ff3.png │ │ ├── ie1.png │ │ └── ie2.png │ │ ├── nav.adoc │ │ └── pages │ │ ├── appendix.adoc │ │ ├── index.adoc │ │ ├── introduction.adoc │ │ ├── samples.adoc │ │ └── ssk.adoc ├── package.json └── spring-security-kerberos-docs.gradle ├── spring-security-kerberos-management └── spring-security-kerberos-management.gradle ├── spring-security-kerberos-samples ├── sec-client-rest-template │ ├── sec-client-rest-template.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── demo │ │ │ └── app │ │ │ └── Application.java │ │ └── resources │ │ └── application.yml ├── sec-server-client-auth │ ├── sec-server-client-auth.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── demo │ │ │ └── app │ │ │ ├── Application.java │ │ │ ├── DummyUserDetailsService.java │ │ │ ├── MvcConfig.java │ │ │ └── WebSecurityConfig.java │ │ └── resources │ │ ├── application.yml │ │ ├── logback.xml │ │ └── templates │ │ ├── hello.html │ │ ├── home.html │ │ └── login.html ├── sec-server-spnego-form-auth │ ├── sec-server-spnego-form-auth.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── demo │ │ │ └── app │ │ │ ├── Application.java │ │ │ ├── DummyUserDetailsService.java │ │ │ ├── MvcConfig.java │ │ │ └── WebSecurityConfig.java │ │ └── resources │ │ ├── application.yml │ │ ├── templates │ │ ├── hello.html │ │ ├── home.html │ │ └── login.html │ │ └── xlogback.xml ├── sec-server-win-auth │ ├── sec-server-win-auth.gradle │ └── src │ │ └── main │ │ ├── java │ │ └── demo │ │ │ └── app │ │ │ ├── ActiveDirectoryLdapAuthoritiesPopulator.java │ │ │ ├── Application.java │ │ │ ├── MvcConfig.java │ │ │ └── WebSecurityConfig.java │ │ └── resources │ │ ├── application.yml │ │ └── templates │ │ ├── hello.html │ │ ├── home.html │ │ └── login.html └── src │ └── main │ └── java │ └── demo │ └── DummyUserDetailsService.java ├── spring-security-kerberos-test ├── spring-security-kerberos-test.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── springframework │ │ └── security │ │ └── kerberos │ │ └── test │ │ ├── KerberosSecurityTestcase.java │ │ └── MiniKdc.java │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── security │ │ └── kerberos │ │ └── test │ │ └── TestMiniKdc.java │ └── resources │ ├── log4j.properties │ ├── minikdc-krb5.conf │ └── minikdc.ldiff └── spring-security-kerberos-web ├── spring-security-kerberos-web.gradle └── src ├── main └── java │ └── org │ └── springframework │ └── security │ └── kerberos │ └── web │ └── authentication │ ├── ResponseHeaderSettingKerberosAuthenticationSuccessHandler.java │ ├── SpnegoAuthenticationProcessingFilter.java │ └── SpnegoEntryPoint.java └── test ├── java └── org │ └── springframework │ └── security │ └── kerberos │ ├── docs │ ├── AuthProviderConfig.java │ ├── AuthProviderConfigTest.java │ ├── DummyUserDetailsService.java │ └── SpnegoConfig.java │ └── web │ ├── SpnegoAuthenticationProcessingFilterTest.java │ └── SpnegoEntryPointTest.java └── resources └── org └── springframework └── security └── kerberos └── docs ├── AuthProviderConfig.xml ├── SpnegoConfig.xml └── appproperties.xml /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | registries: 3 | spring-milestones: 4 | type: maven-repository 5 | url: https://repo.spring.io/milestone 6 | updates: 7 | - package-ecosystem: gradle 8 | target-branch: main 9 | directory: / 10 | schedule: 11 | interval: daily 12 | time: '03:00' 13 | timezone: Etc/UTC 14 | labels: 15 | - 'type: dependency-upgrade' 16 | registries: 17 | - spring-milestones 18 | ignore: 19 | - dependency-name: org.junit:junit-bom 20 | update-types: 21 | - version-update:semver-major 22 | - dependency-name: org.mockito:mockito-bom 23 | update-types: 24 | - version-update:semver-major 25 | - dependency-name: com.gradle.develocity 26 | update-types: 27 | - version-update:semver-major 28 | - version-update:semver-minor 29 | - dependency-name: io.spring.ge.conventions 30 | update-types: 31 | - version-update:semver-major 32 | - version-update:semver-minor 33 | - dependency-name: '*' 34 | update-types: 35 | - version-update:semver-major 36 | - version-update:semver-minor 37 | - package-ecosystem: github-actions 38 | target-branch: main 39 | directory: / 40 | schedule: 41 | interval: weekly 42 | labels: 43 | - 'type: task' 44 | - 'in: build' 45 | ignore: 46 | - dependency-name: sjohnr/* 47 | - package-ecosystem: npm 48 | target-branch: main 49 | directory: /docs 50 | schedule: 51 | interval: weekly 52 | 53 | - package-ecosystem: npm 54 | target-branch: docs-build 55 | directory: / 56 | schedule: 57 | interval: weekly 58 | - package-ecosystem: github-actions 59 | target-branch: docs-build 60 | directory: / 61 | schedule: 62 | interval: weekly 63 | labels: 64 | - 'type: task' 65 | - 'in: build' 66 | ignore: 67 | - dependency-name: sjohnr/* -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - '**' 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | uses: spring-io/spring-security-release-tools/.github/workflows/build.yml@v1 13 | strategy: 14 | matrix: 15 | include: 16 | - nickname: linux adopt 17 17 | jdk: 17 18 | jdk-distribution: adopt 19 | - nickname: linux liberica 17 20 | jdk: 17 21 | jdk-distribution: liberica 22 | with: 23 | runs-on: ubuntu-latest 24 | java-version: ${{ matrix.jdk }} 25 | distribution: ${{ matrix.jdk-distribution }} 26 | secrets: inherit 27 | deploy-artifacts: 28 | name: Deploy Artifacts 29 | needs: [ build ] 30 | uses: spring-io/spring-security-release-tools/.github/workflows/deploy-artifacts.yml@v1 31 | with: 32 | should-deploy-artifacts: ${{ needs.build.outputs.should-deploy-artifacts }} 33 | secrets: inherit 34 | deploy-javadocs: 35 | name: Deploy Javadocs 36 | needs: [ build ] 37 | uses: spring-io/spring-security-release-tools/.github/workflows/deploy-docs.yml@v1 38 | with: 39 | should-deploy-docs: ${{ needs.build.outputs.should-deploy-artifacts }} 40 | secrets: inherit 41 | antora: 42 | name: Invoke Antora Docs Build 43 | runs-on: ubuntu-latest 44 | needs: [build] 45 | if: ${{ needs.build.outputs.should-deploy-artifacts == 'true' }} 46 | steps: 47 | - uses: actions/checkout@v4 48 | - name: Dispatch (partial build) 49 | if: github.ref_type == 'branch' 50 | env: 51 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 52 | run: gh workflow run deploy-docs.yml -r docs-build -f build-refname=${{ github.ref_name }} 53 | 54 | perform-release: 55 | name: Perform Release 56 | needs: [deploy-artifacts, deploy-javadocs] 57 | uses: spring-io/spring-security-release-tools/.github/workflows/perform-release.yml@v1 58 | with: 59 | should-perform-release: ${{ needs.deploy-artifacts.outputs.artifacts-deployed }} 60 | project-version: ${{ needs.deploy-artifacts.outputs.project-version }} 61 | milestone-repo-url: https://repo.spring.io/artifactory/milestone 62 | release-repo-url: https://repo1.maven.org/maven2 63 | artifact-path: org/springframework/security/kerberos/spring-security-kerberos-core 64 | slack-announcing-id: spring-security-kerberos-announcing 65 | secrets: inherit 66 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docs 2 | on: 3 | workflow_dispatch: 4 | 5 | permissions: 6 | actions: write 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | if: github.repository_owner == 'spring-projects' 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v4 14 | with: 15 | ref: docs-build 16 | fetch-depth: 1 17 | - name: Dispatch (partial build) 18 | if: github.ref_type == 'branch' 19 | env: 20 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }} 22 | - name: Dispatch (full build) 23 | if: github.ref_type == 'tag' 24 | env: 25 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) 27 | -------------------------------------------------------------------------------- /.github/workflows/release-scheduler.yml: -------------------------------------------------------------------------------- 1 | name: Release Scheduler 2 | 3 | on: 4 | schedule: 5 | - cron: '15 15 * * *' # Every day at 3:15pm UTC 6 | workflow_dispatch: 7 | 8 | permissions: 9 | actions: write 10 | 11 | jobs: 12 | dispatch_scheduled_releases: 13 | name: Dispatch scheduled releases 14 | if: ${{ github.repository_owner == 'spring-projects' }} 15 | strategy: 16 | matrix: 17 | # List of active maintenance branches. 18 | branch: [ main ] 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 1 25 | - name: Dispatch 26 | env: 27 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | run: gh workflow run update-scheduled-release-version.yml -r ${{ matrix.branch }} 29 | -------------------------------------------------------------------------------- /.github/workflows/update-scheduled-release-version.yml: -------------------------------------------------------------------------------- 1 | name: Update Scheduled Release Version 2 | 3 | on: 4 | workflow_dispatch: # Manual trigger only. Triggered by release-scheduler.yml on main. 5 | 6 | jobs: 7 | update-scheduled-release-version: 8 | name: Update Scheduled Release Version 9 | uses: spring-io/spring-security-release-tools/.github/workflows/update-scheduled-release-version.yml@v1 10 | secrets: inherit 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | build/ 4 | bin/ 5 | *.iml 6 | .gradle/ 7 | .classpath 8 | .DS_Store 9 | .project 10 | .settings 11 | kerberos-user.properties 12 | node_modules 13 | -------------------------------------------------------------------------------- /.sdkmanrc: -------------------------------------------------------------------------------- 1 | # Use sdkman to run "sdk env" to initialize with correct JDK version 2 | # Enable auto-env through the sdkman_auto_env config 3 | # See https://sdkman.io/usage#config 4 | # A summary is to add the following to ~/.sdkman/etc/config 5 | # sdkman_auto_env=true 6 | java=17.0.3-tem 7 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "java", 6 | "name": "Application", 7 | "request": "launch", 8 | "mainClass": "demo.app.Application", 9 | "projectName": "sec-server-win-auth" 10 | }, 11 | { 12 | "type": "java", 13 | "name": "sec-client-rest-template", 14 | "request": "launch", 15 | "mainClass": "demo.app.Application", 16 | "projectName": "sec-client-rest-template" 17 | }, 18 | { 19 | "type": "java", 20 | "name": "sec-server-spnego-form-auth", 21 | "request": "launch", 22 | "mainClass": "demo.app.Application", 23 | "projectName": "sec-server-spnego-form-auth" 24 | }, 25 | { 26 | "type": "java", 27 | "name": "sec-server-win-auth", 28 | "request": "launch", 29 | "mainClass": "demo.app.Application", 30 | "projectName": "sec-server-win-auth" 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.completion.importOrder": [ 3 | "java", 4 | "javax", 5 | "", 6 | "org.springframework", 7 | "#" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.adoc: -------------------------------------------------------------------------------- 1 | = Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of fostering an open 4 | and welcoming community, we pledge to respect all people who contribute through reporting 5 | issues, posting feature requests, updating documentation, submitting pull requests or 6 | patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free experience for 9 | everyone, regardless of level of experience, gender, gender identity and expression, 10 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, 11 | religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic addresses, 20 | without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 24 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 25 | Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors 26 | that they deem inappropriate, threatening, offensive, or harmful. 27 | 28 | By adopting this Code of Conduct, project maintainers commit themselves to fairly and 29 | consistently applying these principles to every aspect of managing this project. Project 30 | maintainers who do not follow or enforce the Code of Conduct may be permanently removed 31 | from the project team. 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an 34 | individual is representing the project or its community. 35 | 36 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 37 | contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will 38 | be reviewed and investigated and will result in a response that is deemed necessary and 39 | appropriate to the circumstances. Maintainers are obligated to maintain confidentiality 40 | with regard to the reporter of an incident. 41 | 42 | This Code of Conduct is adapted from the 43 | http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at 44 | http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/] 45 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Spring Security Kerberos image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Develocity", link="https://ge.spring.io/scans?search.rootProjectNames=spring-security-kerberos"] 2 | 3 | With the Spring Security Kerberos Extension, your users are authenticated against your web application just by opening the URL. There is no need to enter a username/password and no need to install additional software. 4 | 5 | == Code of Conduct 6 | This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct]. 7 | By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io. 8 | 9 | 10 | == Downloading Artifacts 11 | See https://github.com/spring-projects/spring-framework/wiki/Downloading-Spring-artifacts[downloading Spring artifacts] for Maven repository information. 12 | 13 | == Documentation 14 | Be sure to read the http://docs.spring.io/spring-security-kerberos/docs/1.0.x/reference/htmlsingle/[Spring Security Kerberos Reference]. 15 | Extensive JavaDoc for the Spring Security Kerberos code is also available in the http://docs.spring.io/spring-security-kerberos/docs/1.0.x/api/[Spring Security Kerberos API Documentation]. 16 | 17 | == Samples 18 | Samples can be found under `spring-security-kerberos-samples`. Check 19 | the reference documentation more about what those do. 20 | 21 | == Building from Source 22 | Spring Security Kerberos uses a http://gradle.org[Gradle]-based build system. 23 | In the instructions below, http://vimeo.com/34436402[`./gradlew`] is invoked from the root of the source tree and serves as 24 | a cross-platform, self-contained bootstrap mechanism for the build. 25 | 26 | === Prerequisites 27 | http://help.github.com/set-up-git-redirect[Git] and the http://www.oracle.com/technetwork/java/javase/downloads[JDK17 build]. 28 | 29 | Be sure that your `JAVA_HOME` environment variable points to the `jdk1.7.0` folder extracted from the JDK download. 30 | 31 | === Check out sources 32 | [indent=0] 33 | ---- 34 | git clone git@github.com:spring-projects/spring-security-kerberos.git 35 | ---- 36 | 37 | === Install all spring-\* jars into your local Maven cache 38 | [indent=0] 39 | ---- 40 | ./gradlew install 41 | ---- 42 | 43 | === Compile and test; build all jars, distribution zips, and docs 44 | [indent=0] 45 | ---- 46 | ./gradlew build 47 | ---- 48 | 49 | Discover more commands with `./gradlew tasks`. 50 | See also the https://github.com/spring-projects/spring-framework/wiki/Gradle-build-and-release-FAQ[Gradle build and release FAQ]. 51 | 52 | == Getting Support 53 | Check out the http://stackoverflow.com/questions/tagged/spring-security[Spring Security tags on Stack Overflow]. 54 | http://spring.io/services[Commercial support] is available too. 55 | 56 | == Contributing 57 | http://help.github.com/send-pull-requests[Pull requests] are welcome; see the https://github.com/spring-projects/spring-security-kerberos/blob/master/CONTRIBUTING.md[contributor guidelines] for details. 58 | 59 | == License 60 | Spring Security Kerberos is Open Source software released under the 61 | https://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license]. 62 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.root' 3 | alias(libs.plugins.security.release) 4 | } 5 | 6 | description = 'Spring Security Kerberos' 7 | 8 | repositories { 9 | // maven { url 'https://repo.spring.io/snapshot' } 10 | // maven { url 'https://repo.spring.io/milestone' } 11 | // maven { url 'https://repo.spring.io/release' } 12 | mavenCentral() 13 | } 14 | 15 | allprojects { 16 | group = 'org.springframework.security.kerberos' 17 | 18 | repositories { 19 | mavenCentral() 20 | // maven { url 'https://repo.spring.io/release' } 21 | // if (version.contains('-')) { 22 | // maven { url "https://repo.spring.io/milestone" } 23 | // } 24 | // if (version.endsWith('-SNAPSHOT')) { 25 | // maven { url "https://repo.spring.io/snapshot" } 26 | // } 27 | } 28 | 29 | configurations.all { 30 | resolutionStrategy.cacheChangingModulesFor 1, 'hours' 31 | } 32 | } 33 | 34 | develocity { 35 | buildScan { 36 | termsOfUseUrl = 'https://gradle.com/help/legal-terms-of-use' 37 | termsOfUseAgree = 'yes' 38 | } 39 | } 40 | 41 | springRelease { 42 | repositoryOwner = "spring-projects" 43 | repositoryName = "spring-security-kerberos" 44 | weekOfMonth = 4 45 | dayOfWeek = 1 46 | referenceDocUrl = "https://docs.spring.io/spring-security-kerberos/reference/{version}/" 47 | apiDocUrl = "https://docs.spring.io/spring-security-kerberos/docs/{version}/api/" 48 | replaceVersionInReferenceDocUrl = true 49 | releaseVersionPrefix = "v" 50 | } -------------------------------------------------------------------------------- /buildSrc/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java-gradle-plugin" 3 | id "java" 4 | id "groovy" 5 | } 6 | 7 | java { 8 | sourceCompatibility = JavaVersion.VERSION_17 9 | } 10 | 11 | repositories { 12 | gradlePluginPortal() 13 | mavenCentral() 14 | maven { url "https://repo.spring.io/plugins-release/" } 15 | } 16 | 17 | dependencies { 18 | implementation "org.apache.commons:commons-compress:1.26.2" 19 | implementation "com.github.ben-manes:gradle-versions-plugin:0.38.0" 20 | implementation "io.github.gradle-nexus:publish-plugin:1.1.0" 21 | implementation "io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.41" 22 | implementation "io.spring.nohttp:nohttp-gradle:0.0.11" 23 | implementation "org.asciidoctor:asciidoctor-gradle-jvm:3.3.2" 24 | implementation "org.asciidoctor:asciidoctor-gradle-jvm-pdf:3.3.2" 25 | implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21" 26 | implementation "org.hidetake:gradle-ssh-plugin:2.10.1" 27 | implementation "org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0" 28 | implementation "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1" 29 | implementation "org.springframework:spring-core:6.1.8" 30 | } 31 | 32 | 33 | gradlePlugin { 34 | plugins { 35 | samplePlugin { 36 | id = "org.springframework.security.kerberos.sample" 37 | implementationClass = "org.springframework.security.kerberos.gradle.SamplePlugin" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenBomPlugin.groovy: -------------------------------------------------------------------------------- 1 | package io.spring.gradle.convention 2 | 3 | import org.gradle.api.Plugin 4 | import org.gradle.api.Project 5 | import org.gradle.api.plugins.JavaPlatformPlugin 6 | import org.springframework.gradle.properties.SpringCopyPropertiesPlugin 7 | import org.springframework.gradle.SpringMavenPlugin 8 | 9 | public class SpringMavenBomPlugin implements Plugin { 10 | static String MAVEN_BOM_TASK_NAME = "mavenBom" 11 | 12 | public void apply(Project project) { 13 | project.plugins.apply(JavaPlatformPlugin) 14 | project.plugins.apply(SpringMavenPlugin) 15 | project.plugins.apply(SpringCopyPropertiesPlugin) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /buildSrc/src/main/groovy/org/springframework/gradle/docs/SpringDeployDocsPlugin.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package org.springframework.gradle.docs 17 | 18 | import org.gradle.api.Plugin 19 | import org.gradle.api.Project 20 | 21 | class SpringDeployDocsPlugin implements Plugin { 22 | 23 | @Override 24 | void apply(Project project) { 25 | project.getPluginManager().apply('org.hidetake.ssh') 26 | 27 | project.ssh.settings { 28 | knownHosts = allowAnyHosts 29 | } 30 | project.remotes { 31 | docs { 32 | role 'docs' 33 | if (project.hasProperty('deployDocsHost')) { 34 | host = project.findProperty('deployDocsHost') 35 | } 36 | retryCount = 5 // retry 5 times (default is 0) 37 | retryWaitSec = 10 // wait 10 seconds between retries (default is 0) 38 | user = project.findProperty('deployDocsSshUsername') 39 | if (project.hasProperty('deployDocsSshKeyPath')) { 40 | identity = project.file(project.findProperty('deployDocsSshKeyPath')) 41 | } else if (project.hasProperty('deployDocsSshKey')) { 42 | identity = project.findProperty('deployDocsSshKey') 43 | } 44 | if (project.hasProperty('deployDocsSshPassphrase')) { 45 | passphrase = project.findProperty('deployDocsSshPassphrase') 46 | } 47 | } 48 | } 49 | 50 | project.task('deployDocs') { 51 | dependsOn 'docsZip' 52 | doFirst { 53 | project.ssh.run { 54 | session(project.remotes.docs) { 55 | def now = System.currentTimeMillis() 56 | def name = project.rootProject.name 57 | def version = project.rootProject.version 58 | def tempPath = "/tmp/${name}-${now}-docs/".replaceAll(' ', '_') 59 | execute "mkdir -p $tempPath" 60 | 61 | project.tasks.docsZip.outputs.each { o -> 62 | put from: o.files, into: tempPath 63 | } 64 | 65 | execute "unzip $tempPath*.zip -d $tempPath" 66 | 67 | def extractPath = "/var/www/domains/spring.io/docs/htdocs/autorepo/docs/${name}/${version}/" 68 | 69 | execute "rm -rf $extractPath" 70 | execute "mkdir -p $extractPath" 71 | execute "mv $tempPath/docs/* $extractPath" 72 | execute "chmod -R g+w $extractPath" 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.convention; 18 | 19 | import java.io.File; 20 | 21 | import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask; 22 | import org.gradle.api.Plugin; 23 | import org.gradle.api.Project; 24 | import org.gradle.api.Task; 25 | import org.gradle.api.file.DuplicatesStrategy; 26 | import org.gradle.api.plugins.BasePlugin; 27 | import org.gradle.api.plugins.JavaPlugin; 28 | import org.gradle.api.plugins.PluginManager; 29 | import org.gradle.api.tasks.TaskContainer; 30 | import org.gradle.api.tasks.bundling.Zip; 31 | 32 | import org.springframework.gradle.docs.SpringAsciidoctorPlugin; 33 | import org.springframework.gradle.docs.SpringJavadocApiPlugin; 34 | import org.springframework.gradle.docs.SpringJavadocOptionsPlugin; 35 | import org.springframework.gradle.management.SpringManagementConfigurationPlugin; 36 | import org.springframework.gradle.maven.SpringRepositoryPlugin; 37 | 38 | /** 39 | * Aggregates asciidoc, javadoc, and deploying of the docs into a single plugin. 40 | * 41 | * @author Steve Riesenberg 42 | */ 43 | public class SpringDocsPlugin implements Plugin { 44 | @Override 45 | public void apply(Project project) { 46 | // Apply default plugins 47 | PluginManager pluginManager = project.getPluginManager(); 48 | pluginManager.apply(BasePlugin.class); 49 | pluginManager.apply(JavaPlugin.class); 50 | pluginManager.apply(SpringManagementConfigurationPlugin.class); 51 | pluginManager.apply(SpringRepositoryPlugin.class); 52 | pluginManager.apply(SpringAsciidoctorPlugin.class); 53 | // Note: Applying plugin via id since it requires groovy compilation 54 | pluginManager.apply("org.springframework.gradle.deploy-docs"); 55 | pluginManager.apply(SpringJavadocApiPlugin.class); 56 | pluginManager.apply(SpringJavadocOptionsPlugin.class); 57 | 58 | TaskContainer tasks = project.getTasks(); 59 | project.configure(tasks.withType(AbstractAsciidoctorTask.class), (task) -> { 60 | File destination = new File(project.getBuildDir(), "docs"); 61 | task.setOutputDir(destination); 62 | task.sources((patternSet) -> { 63 | patternSet.include("**/*.adoc"); 64 | patternSet.exclude("_*/**"); 65 | }); 66 | }); 67 | 68 | // Add task to create documentation archive 69 | Zip docsZip = tasks.create("docsZip", Zip.class, (zip) -> { 70 | zip.dependsOn(tasks.getByName("api"), tasks.getByName("asciidoctor")/*, tasks.getByName("asciidoctorPdf")*/); 71 | zip.setGroup("Distribution"); 72 | zip.getArchiveBaseName().set(project.getRootProject().getName()); 73 | zip.getArchiveClassifier().set("docs"); 74 | zip.setDescription("Builds -docs archive containing all " + 75 | "Docs for deployment at docs.spring.io"); 76 | zip.into("docs"); 77 | zip.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE); 78 | }); 79 | 80 | // Add task to aggregate documentation 81 | Task docs = tasks.create("docs", (task) -> { 82 | task.dependsOn(docsZip); 83 | task.setGroup("Documentation"); 84 | task.setDescription("An aggregator task to generate all the documentation"); 85 | }); 86 | 87 | // Wire docs task into the build 88 | tasks.getByName("assemble").dependsOn(docs); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/io/spring/gradle/convention/SpringModulePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.convention; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.plugins.JavaLibraryPlugin; 22 | import org.gradle.api.plugins.PluginManager; 23 | 24 | import org.springframework.gradle.SpringJavaPlugin; 25 | import org.springframework.gradle.SpringMavenPlugin; 26 | import org.springframework.gradle.classpath.SpringCheckClasspathForProhibitedDependenciesPlugin; 27 | 28 | /** 29 | * @author Steve Riesenberg 30 | */ 31 | public class SpringModulePlugin implements Plugin { 32 | @Override 33 | public void apply(Project project) { 34 | // Apply default plugins 35 | PluginManager pluginManager = project.getPluginManager(); 36 | pluginManager.apply(JavaLibraryPlugin.class); 37 | pluginManager.apply(SpringJavaPlugin.class); 38 | pluginManager.apply(SpringMavenPlugin.class); 39 | pluginManager.apply(SpringCheckClasspathForProhibitedDependenciesPlugin.class); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/io/spring/gradle/convention/SpringRootProjectPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.spring.gradle.convention; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.plugins.BasePlugin; 22 | import org.gradle.api.plugins.PluginManager; 23 | 24 | import org.springframework.gradle.classpath.SpringCheckProhibitedDependenciesLifecyclePlugin; 25 | import org.springframework.gradle.maven.SpringArtifactoryPlugin; 26 | import org.springframework.gradle.maven.SpringNexusPlugin; 27 | import org.springframework.gradle.nohttp.SpringNoHttpPlugin; 28 | import org.springframework.gradle.sonarqube.SpringSonarQubePlugin; 29 | 30 | /** 31 | * @author Steve Riesenberg 32 | */ 33 | public class SpringRootProjectPlugin implements Plugin { 34 | @Override 35 | public void apply(Project project) { 36 | // Apply default plugins 37 | PluginManager pluginManager = project.getPluginManager(); 38 | pluginManager.apply(BasePlugin.class); 39 | // pluginManager.apply(SpringNoHttpPlugin.class); 40 | pluginManager.apply(SpringNexusPlugin.class); 41 | pluginManager.apply(SpringCheckProhibitedDependenciesLifecyclePlugin.class); 42 | pluginManager.apply(SpringArtifactoryPlugin.class); 43 | pluginManager.apply(SpringSonarQubePlugin.class); 44 | 45 | // Apply default repositories 46 | project.getRepositories().mavenCentral(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/ProjectUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle; 18 | 19 | import org.gradle.api.Project; 20 | 21 | /** 22 | * @author Steve Riesenberg 23 | */ 24 | public class ProjectUtils { 25 | private ProjectUtils() { 26 | } 27 | 28 | public static String getProjectName(Project project) { 29 | String projectName = project.getRootProject().getName(); 30 | if (projectName.endsWith("-build")) { 31 | projectName = projectName.substring(0, projectName.length() - "-build".length()); 32 | } 33 | return projectName; 34 | } 35 | 36 | public static boolean isSnapshot(Project project) { 37 | String projectVersion = projectVersion(project); 38 | return projectVersion.matches("^.*([.-]BUILD)?-SNAPSHOT$"); 39 | } 40 | 41 | public static boolean isMilestone(Project project) { 42 | String projectVersion = projectVersion(project); 43 | return projectVersion.matches("^.*[.-]M\\d+$") || projectVersion.matches("^.*[.-]RC\\d+$"); 44 | } 45 | 46 | public static boolean isRelease(Project project) { 47 | return !(isSnapshot(project) || isMilestone(project)); 48 | } 49 | 50 | private static String projectVersion(Project project) { 51 | return String.valueOf(project.getVersion()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/SpringJavaPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | import io.spring.javaformat.gradle.SpringJavaFormatPlugin; 23 | import org.gradle.api.JavaVersion; 24 | import org.gradle.api.Plugin; 25 | import org.gradle.api.Project; 26 | import org.gradle.api.plugins.GroovyPlugin; 27 | import org.gradle.api.plugins.JavaPlugin; 28 | import org.gradle.api.plugins.JavaPluginExtension; 29 | import org.gradle.api.plugins.PluginManager; 30 | import org.gradle.api.tasks.compile.CompileOptions; 31 | import org.gradle.api.tasks.compile.JavaCompile; 32 | import org.gradle.api.tasks.testing.Test; 33 | import org.gradle.jvm.tasks.Jar; 34 | import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper; 35 | 36 | import org.springframework.gradle.checkstyle.SpringJavaCheckstylePlugin; 37 | import org.springframework.gradle.docs.SpringJavadocOptionsPlugin; 38 | import org.springframework.gradle.jacoco.SpringJacocoPlugin; 39 | import org.springframework.gradle.management.SpringManagementConfigurationPlugin; 40 | import org.springframework.gradle.maven.SpringRepositoryPlugin; 41 | import org.springframework.gradle.propdeps.SpringPropDepsEclipsePlugin; 42 | import org.springframework.gradle.propdeps.SpringPropDepsIdeaPlugin; 43 | import org.springframework.gradle.properties.SpringCopyPropertiesPlugin; 44 | 45 | /** 46 | * @author Steve Riesenberg 47 | */ 48 | public class SpringJavaPlugin implements Plugin { 49 | @Override 50 | public void apply(Project project) { 51 | // Apply default plugins 52 | PluginManager pluginManager = project.getPluginManager(); 53 | pluginManager.apply(JavaPlugin.class); 54 | pluginManager.apply(SpringManagementConfigurationPlugin.class); 55 | if (project.file("src/main/groovy").exists() 56 | || project.file("src/test/groovy").exists() 57 | || project.file("src/integration-test/groovy").exists()) { 58 | pluginManager.apply(GroovyPlugin.class); 59 | } 60 | if (project.file("src/main/kotlin").exists() 61 | || project.file("src/test/kotlin").exists() 62 | || project.file("src/integration-test/kotlin").exists() 63 | || project.getBuildFile().getName().endsWith(".kts")) { 64 | pluginManager.apply(KotlinPluginWrapper.class); 65 | } 66 | pluginManager.apply(SpringRepositoryPlugin.class); 67 | pluginManager.apply(SpringPropDepsEclipsePlugin.class); 68 | pluginManager.apply(SpringPropDepsIdeaPlugin.class); 69 | pluginManager.apply(SpringJavadocOptionsPlugin.class); 70 | // pluginManager.apply(SpringJavaFormatPlugin.class); 71 | // pluginManager.apply(SpringJavaCheckstylePlugin.class); 72 | pluginManager.apply(SpringCopyPropertiesPlugin.class); 73 | pluginManager.apply(SpringJacocoPlugin.class); 74 | 75 | // Apply Java source compatibility version 76 | JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); 77 | java.setTargetCompatibility(JavaVersion.VERSION_17); 78 | 79 | // Configure Java tasks 80 | project.getTasks().withType(JavaCompile.class, (javaCompile) -> { 81 | CompileOptions options = javaCompile.getOptions(); 82 | options.setEncoding("UTF-8"); 83 | options.getCompilerArgs().add("-parameters"); 84 | if (JavaVersion.current().isJava11Compatible()) { 85 | options.getRelease().set(17); 86 | } 87 | }); 88 | project.getTasks().withType(Jar.class, (jar) -> jar.manifest((manifest) -> { 89 | Map attributes = new HashMap<>(); 90 | attributes.put("Created-By", String.format("%s (%s)", System.getProperty("java.version"), System.getProperty("java.specification.vendor"))); 91 | attributes.put("Implementation-Title", project.getName()); 92 | attributes.put("Implementation-Version", project.getVersion().toString()); 93 | attributes.put("Automatic-Module-Name", project.getName().replace("-", ".")); 94 | manifest.attributes(attributes); 95 | })); 96 | project.getTasks().withType(Test.class, (test) -> { 97 | test.useJUnitPlatform(); 98 | }); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/SpringMavenPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.plugins.PluginManager; 22 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 23 | 24 | import org.springframework.gradle.maven.SpringArtifactoryPlugin; 25 | import org.springframework.gradle.maven.SpringMavenPublishingConventionsPlugin; 26 | import org.springframework.gradle.maven.SpringPublishAllJavaComponentsPlugin; 27 | import org.springframework.gradle.maven.SpringPublishArtifactsPlugin; 28 | import org.springframework.gradle.maven.SpringPublishLocalPlugin; 29 | import org.springframework.gradle.maven.SpringSigningPlugin; 30 | 31 | /** 32 | * @author Steve Riesenberg 33 | */ 34 | public class SpringMavenPlugin implements Plugin { 35 | @Override 36 | public void apply(Project project) { 37 | // Apply default plugins 38 | PluginManager pluginManager = project.getPluginManager(); 39 | pluginManager.apply(MavenPublishPlugin.class); 40 | 41 | pluginManager.apply(SpringSigningPlugin.class); 42 | pluginManager.apply(SpringMavenPublishingConventionsPlugin.class); 43 | pluginManager.apply(SpringPublishAllJavaComponentsPlugin.class); 44 | pluginManager.apply(SpringPublishLocalPlugin.class); 45 | pluginManager.apply(SpringPublishArtifactsPlugin.class); 46 | pluginManager.apply(SpringArtifactoryPlugin.class); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/classpath/CheckClasspathForProhibitedDependencies.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.classpath; 18 | 19 | import java.io.IOException; 20 | import java.util.TreeSet; 21 | import java.util.stream.Collectors; 22 | 23 | import org.gradle.api.DefaultTask; 24 | import org.gradle.api.GradleException; 25 | import org.gradle.api.Task; 26 | import org.gradle.api.artifacts.Configuration; 27 | import org.gradle.api.artifacts.ModuleVersionIdentifier; 28 | import org.gradle.api.artifacts.ResolvedConfiguration; 29 | import org.gradle.api.file.FileCollection; 30 | import org.gradle.api.tasks.Classpath; 31 | import org.gradle.api.tasks.TaskAction; 32 | 33 | /** 34 | * A {@link Task} for checking the classpath for prohibited dependencies. 35 | * 36 | * @author Andy Wilkinson 37 | */ 38 | public class CheckClasspathForProhibitedDependencies extends DefaultTask { 39 | 40 | private Configuration classpath; 41 | 42 | public CheckClasspathForProhibitedDependencies() { 43 | getOutputs().upToDateWhen((task) -> true); 44 | } 45 | 46 | public void setClasspath(Configuration classpath) { 47 | this.classpath = classpath; 48 | } 49 | 50 | @Classpath 51 | public FileCollection getClasspath() { 52 | return this.classpath; 53 | } 54 | 55 | @TaskAction 56 | public void checkForProhibitedDependencies() throws IOException { 57 | ResolvedConfiguration resolvedConfiguration = this.classpath.getResolvedConfiguration(); 58 | TreeSet prohibited = resolvedConfiguration.getResolvedArtifacts().stream() 59 | .map((artifact) -> artifact.getModuleVersion().getId()).filter(this::prohibited) 60 | .map((id) -> id.getGroup() + ":" + id.getName()).collect(Collectors.toCollection(TreeSet::new)); 61 | if (!prohibited.isEmpty()) { 62 | StringBuilder message = new StringBuilder(String.format("Found prohibited dependencies in '%s':%n", this.classpath.getName())); 63 | for (String dependency : prohibited) { 64 | message.append(String.format(" %s%n", dependency)); 65 | } 66 | throw new GradleException(message.toString()); 67 | } 68 | } 69 | 70 | private boolean prohibited(ModuleVersionIdentifier id) { 71 | String group = id.getGroup(); 72 | if (group.equals("javax.batch")) { 73 | return false; 74 | } 75 | if (group.equals("javax.cache")) { 76 | return false; 77 | } 78 | if (group.equals("javax.money")) { 79 | return false; 80 | } 81 | if (group.startsWith("javax")) { 82 | return true; 83 | } 84 | if (group.equals("commons-logging")) { 85 | return true; 86 | } 87 | if (group.equals("org.slf4j") && id.getName().equals("jcl-over-slf4j")) { 88 | return true; 89 | } 90 | if (group.startsWith("org.jboss.spec")) { 91 | return true; 92 | } 93 | if (group.equals("org.apache.geronimo.specs")) { 94 | return true; 95 | } 96 | return false; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckClasspathForProhibitedDependenciesPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.classpath; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.artifacts.Configuration; 22 | import org.gradle.api.artifacts.ConfigurationContainer; 23 | import org.gradle.api.plugins.JavaBasePlugin; 24 | import org.gradle.api.tasks.SourceSetContainer; 25 | import org.gradle.api.tasks.TaskProvider; 26 | import org.gradle.language.base.plugins.LifecycleBasePlugin; 27 | 28 | import org.springframework.util.StringUtils; 29 | 30 | /** 31 | * @author Andy Wilkinson 32 | * @author Rob Winch 33 | */ 34 | public class SpringCheckClasspathForProhibitedDependenciesPlugin implements Plugin { 35 | 36 | @Override 37 | public void apply(Project project) { 38 | project.getPlugins().apply(SpringCheckProhibitedDependenciesLifecyclePlugin.class); 39 | project.getPlugins().withType(JavaBasePlugin.class, (javaBasePlugin) -> 40 | configureProhibitedDependencyChecks(project)); 41 | } 42 | 43 | private void configureProhibitedDependencyChecks(Project project) { 44 | SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class); 45 | sourceSets.all((sourceSet) -> createProhibitedDependenciesChecks(project, 46 | sourceSet.getCompileClasspathConfigurationName(), sourceSet.getRuntimeClasspathConfigurationName())); 47 | } 48 | 49 | private void createProhibitedDependenciesChecks(Project project, String... configurationNames) { 50 | ConfigurationContainer configurations = project.getConfigurations(); 51 | for (String configurationName : configurationNames) { 52 | Configuration configuration = configurations.getByName(configurationName); 53 | createProhibitedDependenciesCheck(configuration, project); 54 | } 55 | } 56 | 57 | private void createProhibitedDependenciesCheck(Configuration classpath, Project project) { 58 | String taskName = "check" + StringUtils.capitalize(classpath.getName() + "ForProhibitedDependencies"); 59 | TaskProvider checkClasspathTask = project.getTasks().register(taskName, 60 | CheckClasspathForProhibitedDependencies.class, (checkClasspath) -> { 61 | checkClasspath.setGroup(LifecycleBasePlugin.CHECK_TASK_NAME); 62 | checkClasspath.setDescription("Checks " + classpath.getName() + " for prohibited dependencies"); 63 | checkClasspath.setClasspath(classpath); 64 | }); 65 | project.getTasks().named(SpringCheckProhibitedDependenciesLifecyclePlugin.CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME, (checkProhibitedTask) -> checkProhibitedTask.dependsOn(checkClasspathTask)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckProhibitedDependenciesLifecyclePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.classpath; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.Task; 22 | import org.gradle.api.plugins.JavaBasePlugin; 23 | import org.gradle.api.tasks.TaskProvider; 24 | 25 | /** 26 | * @author Rob Winch 27 | */ 28 | public class SpringCheckProhibitedDependenciesLifecyclePlugin implements Plugin { 29 | public static final String CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME = "checkForProhibitedDependencies"; 30 | 31 | @Override 32 | public void apply(Project project) { 33 | TaskProvider checkProhibitedDependencies = project.getTasks().register(SpringCheckProhibitedDependenciesLifecyclePlugin.CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME, (task) -> { 34 | task.setGroup(JavaBasePlugin.VERIFICATION_GROUP); 35 | task.setDescription("Checks both the compile/runtime classpath of every SourceSet for prohibited dependencies"); 36 | }); 37 | project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME, (checkTask) -> { 38 | checkTask.dependsOn(checkProhibitedDependencies); 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocApiPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.docs; 18 | 19 | import java.io.File; 20 | import java.util.Collections; 21 | import java.util.HashSet; 22 | import java.util.Set; 23 | import java.util.regex.Pattern; 24 | 25 | import io.spring.gradle.convention.SpringModulePlugin; 26 | import org.gradle.api.Action; 27 | import org.gradle.api.JavaVersion; 28 | import org.gradle.api.Plugin; 29 | import org.gradle.api.Project; 30 | import org.gradle.api.Task; 31 | import org.gradle.api.plugins.JavaPluginExtension; 32 | import org.gradle.api.tasks.SourceSet; 33 | import org.gradle.api.tasks.javadoc.Javadoc; 34 | import org.slf4j.Logger; 35 | import org.slf4j.LoggerFactory; 36 | 37 | /** 38 | * @author Rob Winch 39 | * @author Steve Riesenberg 40 | */ 41 | public class SpringJavadocApiPlugin implements Plugin { 42 | private final Logger logger = LoggerFactory.getLogger(getClass()); 43 | private Set excludes = Collections.singleton(Pattern.compile("test")); 44 | 45 | @Override 46 | public void apply(Project project) { 47 | // Create task to generate aggregated docs 48 | Javadoc api = project.getTasks().create("api", Javadoc.class, (javadoc) -> { 49 | javadoc.setGroup("Documentation"); 50 | javadoc.setDescription("Generates aggregated Javadoc API documentation."); 51 | }); 52 | 53 | // Note: The following action cannot be a lambda, for groovy compatibility 54 | api.doLast(new Action() { 55 | @Override 56 | public void execute(Task task) { 57 | if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { 58 | project.copy((copy) -> copy.from(api.getDestinationDir()) 59 | .into(api.getDestinationDir()) 60 | .include("element-list") 61 | .rename("element-list", "package-list")); 62 | } 63 | } 64 | }); 65 | 66 | Set subprojects = project.getRootProject().getSubprojects(); 67 | for (Project subproject : subprojects) { 68 | addProject(api, subproject); 69 | } 70 | 71 | if (subprojects.isEmpty()) { 72 | addProject(api, project); 73 | } 74 | 75 | api.setMaxMemory("1024m"); 76 | api.setDestinationDir(new File(project.getBuildDir(), "api")); 77 | } 78 | 79 | public void setExcludes(String... excludes) { 80 | if (excludes == null) { 81 | this.excludes = Collections.emptySet(); 82 | } 83 | this.excludes = new HashSet<>(excludes.length); 84 | for (String exclude : excludes) { 85 | this.excludes.add(Pattern.compile(exclude)); 86 | } 87 | } 88 | 89 | private void addProject(Javadoc api, Project project) { 90 | for (Pattern exclude : excludes) { 91 | if (exclude.matcher(project.getName()).matches()) { 92 | logger.info("Skipping {} because it is excluded by {}", project, exclude); 93 | return; 94 | } 95 | } 96 | logger.info("Try add sources for {}", project); 97 | project.getPlugins().withType(SpringModulePlugin.class, (plugin) -> { 98 | logger.info("Added sources for {}", project); 99 | 100 | JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); 101 | SourceSet mainSourceSet = java.getSourceSets().getByName("main"); 102 | 103 | api.setSource(api.getSource().plus(mainSourceSet.getAllJava())); 104 | project.getTasks().withType(Javadoc.class).all((projectJavadoc) -> 105 | api.setClasspath(api.getClasspath().plus(projectJavadoc.getClasspath()))); 106 | }); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocOptionsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.docs; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.tasks.javadoc.Javadoc; 22 | import org.gradle.external.javadoc.StandardJavadocDocletOptions; 23 | 24 | /** 25 | * @author Steve Riesenberg 26 | */ 27 | public class SpringJavadocOptionsPlugin implements Plugin { 28 | @Override 29 | public void apply(Project project) { 30 | project.getTasks().withType(Javadoc.class, (javadoc) -> { 31 | StandardJavadocDocletOptions options = (StandardJavadocDocletOptions) javadoc.getOptions(); 32 | options.addStringOption("Xdoclint:none", "-quiet"); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/jacoco/SpringJacocoPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.jacoco; 18 | 19 | import java.util.Objects; 20 | 21 | import org.gradle.api.Plugin; 22 | import org.gradle.api.Project; 23 | import org.gradle.api.plugins.JavaPlugin; 24 | import org.gradle.testing.jacoco.plugins.JacocoPlugin; 25 | import org.gradle.testing.jacoco.plugins.JacocoPluginExtension; 26 | 27 | /** 28 | * Adds a version of jacoco to use and makes check depend on jacocoTestReport. 29 | * 30 | * @author Rob Winch 31 | * @author Steve Riesenberg 32 | */ 33 | public class SpringJacocoPlugin implements Plugin { 34 | private static final String JACOCO_TOOL_VERSION_PROPERTY = "jacocoToolVersion"; 35 | private static final String DEFAULT_JACOCO_TOOL_VERSION = "0.8.7"; 36 | 37 | @Override 38 | public void apply(Project project) { 39 | project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { 40 | project.getPluginManager().apply(JacocoPlugin.class); 41 | project.getTasks().getByName("check").dependsOn(project.getTasks().getByName("jacocoTestReport")); 42 | 43 | JacocoPluginExtension jacoco = project.getExtensions().getByType(JacocoPluginExtension.class); 44 | // NOTE: See gradle.properties#jacocoToolVersion for actual version number 45 | jacoco.setToolVersion(getJacocoToolVersion(project)); 46 | }); 47 | } 48 | 49 | private static String getJacocoToolVersion(Project project) { 50 | String jacocoToolVersion = DEFAULT_JACOCO_TOOL_VERSION; 51 | if (project.hasProperty(JACOCO_TOOL_VERSION_PROPERTY)) { 52 | jacocoToolVersion = Objects.requireNonNull(project.findProperty(JACOCO_TOOL_VERSION_PROPERTY)).toString(); 53 | } 54 | return jacocoToolVersion; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/management/SpringManagementConfigurationPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2021 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.management; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.artifacts.ConfigurationContainer; 22 | import org.gradle.api.plugins.JavaPlugin; 23 | import org.gradle.api.plugins.JavaTestFixturesPlugin; 24 | import org.gradle.api.plugins.PluginContainer; 25 | import org.gradle.api.publish.PublishingExtension; 26 | import org.gradle.api.publish.VariantVersionMappingStrategy; 27 | import org.gradle.api.publish.maven.MavenPublication; 28 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 29 | 30 | /** 31 | * Creates a Management configuration that is appropriate for adding a platform to that is not exposed externally. If 32 | * the JavaPlugin is applied, the compileClasspath, runtimeClasspath, testCompileClasspath, and testRuntimeClasspath 33 | * will extend from it. 34 | * @author Rob Winch 35 | * @author Steve Riesenberg 36 | */ 37 | public class SpringManagementConfigurationPlugin implements Plugin { 38 | public static final String MANAGEMENT_CONFIGURATION_NAME = "management"; 39 | 40 | @Override 41 | public void apply(Project project) { 42 | ConfigurationContainer configurations = project.getConfigurations(); 43 | configurations.create(MANAGEMENT_CONFIGURATION_NAME, (management) -> { 44 | management.setVisible(false); 45 | management.setCanBeConsumed(false); 46 | management.setCanBeResolved(false); 47 | 48 | PluginContainer plugins = project.getPlugins(); 49 | plugins.withType(JavaPlugin.class, (javaPlugin) -> { 50 | configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); 51 | configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); 52 | configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); 53 | configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); 54 | }); 55 | plugins.withType(JavaTestFixturesPlugin.class, (javaTestFixturesPlugin) -> { 56 | configurations.getByName("testFixturesCompileClasspath").extendsFrom(management); 57 | configurations.getByName("testFixturesRuntimeClasspath").extendsFrom(management); 58 | }); 59 | plugins.withType(MavenPublishPlugin.class, (mavenPublish) -> { 60 | PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); 61 | publishing.getPublications().withType(MavenPublication.class, (mavenPublication) -> 62 | mavenPublication.versionMapping((versions) -> 63 | versions.allVariants(VariantVersionMappingStrategy::fromResolutionResult))); 64 | }); 65 | }); 66 | } 67 | } -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringArtifactoryPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2024 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 22 | import org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin; 23 | import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention; 24 | 25 | import org.springframework.gradle.ProjectUtils; 26 | 27 | /** 28 | * @author Steve Riesenberg 29 | */ 30 | public class SpringArtifactoryPlugin implements Plugin { 31 | @Override 32 | public void apply(Project project) { 33 | // Apply base plugin 34 | project.getPlugins().apply(ArtifactoryPlugin.class); 35 | 36 | // Apply artifactory repository configuration 37 | boolean isSnapshot = ProjectUtils.isSnapshot(project); 38 | boolean isMilestone = ProjectUtils.isMilestone(project); 39 | 40 | ArtifactoryPluginConvention artifactoryExtension = project.getExtensions().getByType(ArtifactoryPluginConvention.class); 41 | artifactoryExtension.publish((publish) -> { 42 | publish.setContextUrl("https://repo.spring.io"); 43 | publish.repository((repository) -> { 44 | String repoKey = isSnapshot ? "libs-snapshot-local" : isMilestone ? "libs-milestone-local" : "libs-release-local"; 45 | repository.setRepoKey(repoKey); 46 | if (project.hasProperty("artifactoryUsername")) { 47 | repository.setUsername((String) project.findProperty("artifactoryUsername")); 48 | repository.setPassword((String) project.findProperty("artifactoryPassword")); 49 | } 50 | }); 51 | // Would fail if maven publish is not applied, i.e. in root project (SpringRootProjectPlugin) 52 | project.getPlugins().withType(MavenPublishPlugin.class, mavenPublish -> { 53 | publish.defaults((defaults) -> defaults.publications("mavenJava")); 54 | }); 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPublishingConventionsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import java.util.Collections; 20 | 21 | import org.gradle.api.Plugin; 22 | import org.gradle.api.Project; 23 | import org.gradle.api.plugins.JavaPlugin; 24 | import org.gradle.api.plugins.JavaPluginExtension; 25 | import org.gradle.api.publish.PublishingExtension; 26 | import org.gradle.api.publish.maven.MavenPom; 27 | import org.gradle.api.publish.maven.MavenPomDeveloperSpec; 28 | import org.gradle.api.publish.maven.MavenPomIssueManagement; 29 | import org.gradle.api.publish.maven.MavenPomLicenseSpec; 30 | import org.gradle.api.publish.maven.MavenPomOrganization; 31 | import org.gradle.api.publish.maven.MavenPomScm; 32 | import org.gradle.api.publish.maven.MavenPublication; 33 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 34 | 35 | /** 36 | * @author Steve Riesenberg 37 | */ 38 | public class SpringMavenPublishingConventionsPlugin implements Plugin { 39 | @Override 40 | public void apply(Project project) { 41 | project.getPlugins().withType(MavenPublishPlugin.class, (mavenPublish) -> { 42 | PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); 43 | publishing.getPublications().withType(MavenPublication.class, (mavenPublication) -> 44 | customizePom(mavenPublication.getPom(), project)); 45 | SpringMavenPublishingConventionsPlugin.this.customizeJavaPlugin(project); 46 | }); 47 | } 48 | 49 | private void customizePom(MavenPom pom, Project project) { 50 | pom.getUrl().set("https://spring.io/projects/spring-authorization-server"); 51 | pom.getName().set(project.provider(project::getName)); 52 | pom.getDescription().set(project.provider(project::getDescription)); 53 | pom.organization(this::customizeOrganization); 54 | pom.licenses(this::customizeLicences); 55 | pom.developers(this::customizeDevelopers); 56 | pom.scm(this::customizeScm); 57 | pom.issueManagement(this::customizeIssueManagement); 58 | } 59 | 60 | private void customizeOrganization(MavenPomOrganization organization) { 61 | organization.getName().set("VMware, Inc."); 62 | organization.getUrl().set("https://spring.io"); 63 | } 64 | 65 | private void customizeLicences(MavenPomLicenseSpec licences) { 66 | licences.license((licence) -> { 67 | licence.getName().set("Apache License, Version 2.0"); 68 | licence.getUrl().set("https://www.apache.org/licenses/LICENSE-2.0"); 69 | }); 70 | } 71 | 72 | private void customizeDevelopers(MavenPomDeveloperSpec developers) { 73 | developers.developer((developer) -> { 74 | developer.getName().set("Joe Grandja"); 75 | developer.getEmail().set("jgrandja@vmware.com"); 76 | developer.getOrganization().set("VMware, Inc."); 77 | developer.getOrganizationUrl().set("https://spring.io"); 78 | developer.getRoles().set(Collections.singletonList("Project lead")); 79 | }); 80 | developers.developer((developer) -> { 81 | developer.getName().set("Steve Riesenberg"); 82 | developer.getEmail().set("sriesenberg@vmware.com"); 83 | developer.getOrganization().set("VMware, Inc."); 84 | developer.getOrganizationUrl().set("https://spring.io"); 85 | }); 86 | } 87 | 88 | private void customizeScm(MavenPomScm scm) { 89 | scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-authorization-server.git"); 90 | scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-authorization-server.git"); 91 | scm.getUrl().set("https://github.com/spring-projects/spring-authorization-server"); 92 | } 93 | 94 | private void customizeIssueManagement(MavenPomIssueManagement issueManagement) { 95 | issueManagement.getSystem().set("GitHub"); 96 | issueManagement.getUrl().set("https://github.com/spring-projects/spring-authorization-server/issues"); 97 | } 98 | 99 | private void customizeJavaPlugin(Project project) { 100 | project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { 101 | JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class); 102 | extension.withJavadocJar(); 103 | extension.withSourcesJar(); 104 | }); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import java.net.URI; 20 | import java.time.Duration; 21 | 22 | import io.github.gradlenexus.publishplugin.NexusPublishExtension; 23 | import io.github.gradlenexus.publishplugin.NexusPublishPlugin; 24 | import org.gradle.api.Plugin; 25 | import org.gradle.api.Project; 26 | import org.gradle.api.Task; 27 | 28 | import org.springframework.gradle.ProjectUtils; 29 | 30 | /** 31 | * @author Steve Riesenberg 32 | */ 33 | public class SpringNexusPlugin implements Plugin { 34 | @Override 35 | public void apply(Project project) { 36 | // Apply nexus publish plugin 37 | project.getPlugins().apply(NexusPublishPlugin.class); 38 | 39 | // Create ossrh repository 40 | NexusPublishExtension nexusPublishing = project.getExtensions().getByType(NexusPublishExtension.class); 41 | nexusPublishing.getRepositories().create("ossrh", (nexusRepository) -> { 42 | nexusRepository.getNexusUrl().set(URI.create("https://s01.oss.sonatype.org/service/local/")); 43 | nexusRepository.getSnapshotRepositoryUrl().set(URI.create("https://s01.oss.sonatype.org/content/repositories/snapshots/")); 44 | }); 45 | 46 | // Configure timeouts 47 | nexusPublishing.getConnectTimeout().set(Duration.ofMinutes(3)); 48 | nexusPublishing.getClientTimeout().set(Duration.ofMinutes(3)); 49 | 50 | // Ensure release build automatically closes and releases staging repository 51 | Task finalizeDeployArtifacts = project.task("finalizeDeployArtifacts"); 52 | if (ProjectUtils.isRelease(project) && project.hasProperty("ossrhUsername")) { 53 | Task closeAndReleaseOssrhStagingRepository = project.getTasks().findByName("closeAndReleaseOssrhStagingRepository"); 54 | finalizeDeployArtifacts.dependsOn(closeAndReleaseOssrhStagingRepository); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishAllJavaComponentsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.plugins.JavaPlatformPlugin; 22 | import org.gradle.api.plugins.JavaPlugin; 23 | import org.gradle.api.publish.PublishingExtension; 24 | import org.gradle.api.publish.maven.MavenPublication; 25 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 26 | 27 | /** 28 | * @author Steve Riesenberg 29 | */ 30 | public class SpringPublishAllJavaComponentsPlugin implements Plugin { 31 | @Override 32 | public void apply(Project project) { 33 | project.getPlugins().withType(MavenPublishPlugin.class, (mavenPublish) -> { 34 | PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); 35 | publishing.getPublications().create("mavenJava", MavenPublication.class, (maven) -> { 36 | project.getPlugins().withType(JavaPlugin.class, (plugin) -> 37 | maven.from(project.getComponents().getByName("java"))); 38 | project.getPlugins().withType(JavaPlatformPlugin.class, (plugin) -> 39 | maven.from(project.getComponents().getByName("javaPlatform"))); 40 | }); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishArtifactsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | 22 | import org.springframework.gradle.ProjectUtils; 23 | 24 | /** 25 | * @author Steve Riesenberg 26 | */ 27 | public class SpringPublishArtifactsPlugin implements Plugin { 28 | @Override 29 | public void apply(Project project) { 30 | project.getTasks().register("publishArtifacts", (publishArtifacts) -> { 31 | publishArtifacts.setGroup("Publishing"); 32 | publishArtifacts.setDescription("Publish the artifacts to either Artifactory or Maven Central based on the version"); 33 | if (ProjectUtils.isRelease(project)) { 34 | publishArtifacts.dependsOn("publishToOssrh"); 35 | } else { 36 | publishArtifacts.dependsOn("artifactoryPublish"); 37 | } 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishLocalPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2024 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import java.io.File; 20 | 21 | import org.gradle.api.Plugin; 22 | import org.gradle.api.Project; 23 | import org.gradle.api.publish.PublishingExtension; 24 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; 25 | 26 | /** 27 | * @author Steve Riesenberg 28 | */ 29 | public class SpringPublishLocalPlugin implements Plugin { 30 | @Override 31 | public void apply(Project project) { 32 | project.getPlugins().withType(MavenPublishPlugin.class, (mavenPublish) -> { 33 | PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); 34 | publishing.getRepositories().maven((maven) -> { 35 | maven.setName("local"); 36 | maven.setUrl(new File(project.getRootProject().getLayout().getBuildDirectory().getAsFile().get(), "publications/repos")); 37 | }); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringRepositoryPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import java.util.Arrays; 20 | import java.util.Collections; 21 | import java.util.List; 22 | import java.util.Objects; 23 | 24 | import org.gradle.api.Plugin; 25 | import org.gradle.api.Project; 26 | 27 | import org.springframework.gradle.ProjectUtils; 28 | 29 | /** 30 | * @author Steve Riesenberg 31 | */ 32 | public class SpringRepositoryPlugin implements Plugin { 33 | @Override 34 | public void apply(Project project) { 35 | List forceMavenRepositories = Collections.emptyList(); 36 | if (project.hasProperty("forceMavenRepositories")) { 37 | forceMavenRepositories = Arrays.asList(((String) project.findProperty("forceMavenRepositories")).split(",")); 38 | } 39 | 40 | boolean isImplicitSnapshotRepository = forceMavenRepositories.isEmpty() && ProjectUtils.isSnapshot(project); 41 | boolean isImplicitMilestoneRepository = forceMavenRepositories.isEmpty() && ProjectUtils.isMilestone(project); 42 | 43 | boolean isSnapshot = isImplicitSnapshotRepository || forceMavenRepositories.contains("snapshot"); 44 | boolean isMilestone = isImplicitMilestoneRepository || forceMavenRepositories.contains("milestone"); 45 | 46 | if (forceMavenRepositories.contains("local")) { 47 | project.getRepositories().mavenLocal(); 48 | } 49 | project.getRepositories().mavenCentral(); 50 | if (isSnapshot) { 51 | repository(project, "artifactory-snapshot", "https://repo.spring.io/snapshot/"); 52 | } 53 | if (isSnapshot || isMilestone) { 54 | repository(project, "artifactory-milestone", "https://repo.spring.io/milestone/"); 55 | } 56 | repository(project, "artifactory-release", "https://repo.spring.io/release/"); 57 | } 58 | 59 | private void repository(Project project, String name, String url) { 60 | project.getRepositories().maven((repo) -> { 61 | repo.setName(name); 62 | if (project.hasProperty("artifactoryUsername")) { 63 | repo.credentials((credentials) -> { 64 | credentials.setUsername(Objects.requireNonNull(project.findProperty("artifactoryUsername")).toString()); 65 | credentials.setPassword(Objects.requireNonNull(project.findProperty("artifactoryPassword")).toString()); 66 | }); 67 | } 68 | repo.setUrl(url); 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package org.springframework.gradle.maven; 18 | 19 | import java.util.concurrent.Callable; 20 | 21 | import org.gradle.api.Plugin; 22 | import org.gradle.api.Project; 23 | import org.gradle.api.publish.Publication; 24 | import org.gradle.api.publish.PublishingExtension; 25 | import org.gradle.plugins.signing.SigningExtension; 26 | import org.gradle.plugins.signing.SigningPlugin; 27 | 28 | /** 29 | * @author Steve Riesenberg 30 | */ 31 | public class SpringSigningPlugin implements Plugin { 32 | @Override 33 | public void apply(Project project) { 34 | project.getPluginManager().apply(SigningPlugin.class); 35 | project.getPlugins().withType(SigningPlugin.class, (signingPlugin) -> { 36 | boolean hasSigningKey = project.hasProperty("signing.keyId") || project.hasProperty("signingKey"); 37 | if (hasSigningKey) { 38 | sign(project); 39 | } 40 | }); 41 | } 42 | 43 | private void sign(Project project) { 44 | SigningExtension signing = project.getExtensions().getByType(SigningExtension.class); 45 | signing.setRequired((Callable) () -> project.getGradle().getTaskGraph().hasTask("publishArtifacts")); 46 | 47 | String signingKeyId = (String) project.findProperty("signingKeyId"); 48 | String signingKey = (String) project.findProperty("signingKey"); 49 | String signingPassword = (String) project.findProperty("signingPassword"); 50 | if (signingKeyId != null) { 51 | signing.useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword); 52 | } else { 53 | signing.useInMemoryPgpKeys(signingKey, signingPassword); 54 | } 55 | project.getPlugins().withType(SpringPublishAllJavaComponentsPlugin.class, (publishingPlugin) -> { 56 | PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); 57 | Publication maven = publishing.getPublications().getByName("mavenJava"); 58 | signing.sign(maven); 59 | }); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/nohttp/SpringNoHttpPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.nohttp; 18 | 19 | import java.io.File; 20 | 21 | import io.spring.nohttp.gradle.NoHttpExtension; 22 | import io.spring.nohttp.gradle.NoHttpPlugin; 23 | import org.gradle.api.Plugin; 24 | import org.gradle.api.Project; 25 | 26 | /** 27 | * @author Steve Riesenberg 28 | */ 29 | public class SpringNoHttpPlugin implements Plugin { 30 | @Override 31 | public void apply(Project project) { 32 | // Apply nohttp plugin 33 | project.getPluginManager().apply(NoHttpPlugin.class); 34 | 35 | // Configure nohttp 36 | NoHttpExtension nohttp = project.getExtensions().getByType(NoHttpExtension.class); 37 | File allowlistFile = project.getRootProject().file("etc/nohttp/allowlist.lines"); 38 | nohttp.setAllowlistFile(allowlistFile); 39 | nohttp.getSource().exclude("**/build/**"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsEclipsePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.propdeps; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.plugins.PluginManager; 22 | import org.gradle.plugins.ide.eclipse.EclipsePlugin; 23 | import org.gradle.plugins.ide.eclipse.EclipseWtpPlugin; 24 | import org.gradle.plugins.ide.eclipse.model.EclipseModel; 25 | 26 | /** 27 | * Plugin to allow optional and provided dependency configurations to work with the 28 | * standard gradle 'eclipse' plugin 29 | * 30 | * @author Phillip Webb 31 | * @author Steve Riesenberg 32 | */ 33 | public class SpringPropDepsEclipsePlugin implements Plugin { 34 | @Override 35 | public void apply(Project project) { 36 | PluginManager pluginManager = project.getPluginManager(); 37 | pluginManager.apply(SpringPropDepsPlugin.class); 38 | pluginManager.apply(EclipsePlugin.class); 39 | pluginManager.apply(EclipseWtpPlugin.class); 40 | 41 | EclipseModel eclipseModel = project.getExtensions().getByType(EclipseModel.class); 42 | eclipseModel.classpath((classpath) -> { 43 | classpath.getPlusConfigurations().add(project.getConfigurations().getByName("provided")); 44 | classpath.getPlusConfigurations().add(project.getConfigurations().getByName("optional")); 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsIdeaPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.propdeps; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.plugins.PluginManager; 22 | import org.gradle.plugins.ide.idea.IdeaPlugin; 23 | import org.gradle.plugins.ide.idea.model.IdeaModel; 24 | 25 | /** 26 | * Plugin to allow optional and provided dependency configurations to work with the 27 | * standard gradle 'idea' plugin 28 | * 29 | * @author Phillip Webb 30 | * @author Brian Clozel 31 | * @author Steve Riesenberg 32 | * @link https://youtrack.jetbrains.com/issue/IDEA-107046 33 | * @link https://youtrack.jetbrains.com/issue/IDEA-117668 34 | */ 35 | public class SpringPropDepsIdeaPlugin implements Plugin { 36 | @Override 37 | public void apply(Project project) { 38 | PluginManager pluginManager = project.getPluginManager(); 39 | pluginManager.apply(SpringPropDepsPlugin.class); 40 | pluginManager.apply(IdeaPlugin.class); 41 | 42 | IdeaModel ideaModel = project.getExtensions().getByType(IdeaModel.class); 43 | ideaModel.module((idea) -> { 44 | // IDEA internally deals with 4 scopes : COMPILE, TEST, PROVIDED, RUNTIME 45 | // but only PROVIDED seems to be picked up 46 | idea.getScopes().get("PROVIDED").get("plus").add(project.getConfigurations().getByName("provided")); 47 | idea.getScopes().get("PROVIDED").get("plus").add(project.getConfigurations().getByName("optional")); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.propdeps; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.gradle.api.artifacts.Configuration; 22 | import org.gradle.api.plugins.JavaLibraryPlugin; 23 | import org.gradle.api.plugins.JavaPlugin; 24 | import org.gradle.api.plugins.JavaPluginExtension; 25 | import org.gradle.api.tasks.javadoc.Javadoc; 26 | 27 | import org.springframework.gradle.management.SpringManagementConfigurationPlugin; 28 | 29 | /** 30 | * Plugin to allow 'optional' and 'provided' dependency configurations 31 | * 32 | * As stated in the maven documentation, provided scope "is only available on the compilation and test classpath, 33 | * and is not transitive". 34 | * 35 | * This plugin creates two new configurations, and each one: 36 | *
    37 | *
  • is a parent of the compile configuration
  • 38 | *
  • is not visible, not transitive
  • 39 | *
  • all dependencies are excluded from the default configuration
  • 40 | *
41 | * 42 | * @author Phillip Webb 43 | * @author Brian Clozel 44 | * @author Rob Winch 45 | * @author Steve Riesenberg 46 | * 47 | * @see Maven documentation 48 | * @see Gradle configurations 49 | * @see SpringPropDepsEclipsePlugin 50 | * @see SpringPropDepsIdeaPlugin 51 | */ 52 | public class SpringPropDepsPlugin implements Plugin { 53 | @Override 54 | public void apply(Project project) { 55 | project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { 56 | Configuration provided = addConfiguration(project, "provided"); 57 | Configuration optional = addConfiguration(project, "optional"); 58 | 59 | Javadoc javadoc = (Javadoc) project.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME); 60 | javadoc.setClasspath(javadoc.getClasspath().plus(provided).plus(optional)); 61 | }); 62 | } 63 | 64 | private Configuration addConfiguration(Project project, String name) { 65 | Configuration configuration = project.getConfigurations().create(name); 66 | configuration.extendsFrom(project.getConfigurations().getByName("implementation")); 67 | project.getPlugins().withType(JavaLibraryPlugin.class, (javaLibraryPlugin) -> 68 | configuration.extendsFrom(project.getConfigurations().getByName("api"))); 69 | project.getPlugins().withType(SpringManagementConfigurationPlugin.class, (springManagementConfigurationPlugin) -> 70 | configuration.extendsFrom(project.getConfigurations().getByName("management"))); 71 | 72 | JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); 73 | java.getSourceSets().all((sourceSet) -> { 74 | sourceSet.setCompileClasspath(sourceSet.getCompileClasspath().plus(configuration)); 75 | sourceSet.setRuntimeClasspath(sourceSet.getRuntimeClasspath().plus(configuration)); 76 | }); 77 | 78 | return configuration; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/properties/SpringCopyPropertiesPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.properties; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | 22 | /** 23 | * @author Steve Riesenberg 24 | */ 25 | public class SpringCopyPropertiesPlugin implements Plugin { 26 | @Override 27 | public void apply(Project project) { 28 | copyPropertyFromRootProjectTo("group", project); 29 | copyPropertyFromRootProjectTo("version", project); 30 | copyPropertyFromRootProjectTo("description", project); 31 | } 32 | 33 | private void copyPropertyFromRootProjectTo(String propertyName, Project project) { 34 | Project rootProject = project.getRootProject(); 35 | Object property = rootProject.findProperty(propertyName); 36 | if (property != null) { 37 | project.setProperty(propertyName, property); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/gradle/sonarqube/SpringSonarQubePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.gradle.sonarqube; 18 | 19 | import org.gradle.api.Plugin; 20 | import org.gradle.api.Project; 21 | import org.sonarqube.gradle.SonarQubeExtension; 22 | import org.sonarqube.gradle.SonarQubePlugin; 23 | 24 | import org.springframework.gradle.ProjectUtils; 25 | 26 | /** 27 | * @author Steve Riesenberg 28 | */ 29 | public class SpringSonarQubePlugin implements Plugin { 30 | @Override 31 | public void apply(Project project) { 32 | // Apply sonarqube plugin 33 | project.getPluginManager().apply(SonarQubePlugin.class); 34 | 35 | // Configure sonarqube 36 | SonarQubeExtension sonarqube = project.getExtensions().getByType(SonarQubeExtension.class); 37 | sonarqube.properties((properties) -> { 38 | String projectName = ProjectUtils.getProjectName(project); 39 | properties.property("sonar.java.coveragePlugin", "jacoco"); 40 | properties.property("sonar.projectName", projectName); 41 | properties.property("sonar.jacoco.reportPath", project.getBuildDir().getName() + "/jacoco.exec"); 42 | properties.property("sonar.links.homepage", "https://spring.io/" + projectName); 43 | properties.property("sonar.links.ci", "https://jenkins.spring.io/job/" + projectName + "/"); 44 | properties.property("sonar.links.issue", "https://github.com/spring-projects/" + projectName + "/issues"); 45 | properties.property("sonar.links.scm", "https://github.com/spring-projects/" + projectName); 46 | properties.property("sonar.links.scm_dev", "https://github.com/spring-projects/" + projectName + ".git"); 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SamplePlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.gradle; 17 | 18 | import org.gradle.api.Plugin; 19 | import org.gradle.api.Project; 20 | import org.gradle.api.plugins.JavaPlugin; 21 | import org.gradle.api.plugins.PluginManager; 22 | import org.springframework.gradle.management.SpringManagementConfigurationPlugin; 23 | 24 | /** 25 | * @author Janne Valkealahti 26 | */ 27 | class SamplePlugin implements Plugin { 28 | 29 | @Override 30 | public void apply(Project project) { 31 | PluginManager pluginManager = project.getPluginManager(); 32 | pluginManager.apply(JavaPlugin.class); 33 | pluginManager.apply(SpringManagementConfigurationPlugin.class); 34 | new JavaConventions().apply(project); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.bom.properties: -------------------------------------------------------------------------------- 1 | implementation-class=io.spring.gradle.convention.SpringMavenBomPlugin -------------------------------------------------------------------------------- /buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.docs.properties: -------------------------------------------------------------------------------- 1 | implementation-class=io.spring.gradle.convention.SpringDocsPlugin -------------------------------------------------------------------------------- /buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.root.properties: -------------------------------------------------------------------------------- 1 | implementation-class=io.spring.gradle.convention.SpringRootProjectPlugin -------------------------------------------------------------------------------- /buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-module.properties: -------------------------------------------------------------------------------- 1 | implementation-class=io.spring.gradle.convention.SpringModulePlugin -------------------------------------------------------------------------------- /buildSrc/src/main/resources/META-INF/gradle-plugins/org.springframework.gradle.deploy-docs.properties: -------------------------------------------------------------------------------- 1 | # Referencing this plugin by ID allows java code to depend on groovy compilation 2 | implementation-class=org.springframework.gradle.docs.SpringDeployDocsPlugin -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=2.1.1 2 | develocityVersion=3.17.2 3 | springGeConventionsVersion=0.0.17 4 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [libraries] 2 | assertj-core='org.assertj:assertj-core:3.26.0' 3 | httpclient5="org.apache.httpcomponents.client5:httpclient5:5.3.1" 4 | junit-bom='org.junit:junit-bom:5.10.4' 5 | kerby='org.apache.kerby:kerb-simplekdc:2.0.3' 6 | mockito-bom='org.mockito:mockito-bom:5.12.0' 7 | okhttp3='com.squareup.okhttp3:okhttp:3.14.9' 8 | okhttp3-mockwebserver='com.squareup.okhttp3:mockwebserver:3.14.9' 9 | servlet-api='jakarta.servlet:jakarta.servlet-api:6.0.0' 10 | spring-framework-bom='org.springframework:spring-framework-bom:6.1.8' 11 | spring-security-bom='org.springframework.security:spring-security-bom:6.3.3' 12 | 13 | [plugins] 14 | spring-boot='org.springframework.boot:3.3.0' 15 | dependency-management='io.spring.dependency-management:1.1.5' 16 | security-release='io.spring.security.release:1.0.3' -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /scripts/release/release-notes-sections.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | repository: spring-projects/spring-security-kerberos 3 | sections: 4 | - title: ":star: New Features" 5 | labels: ["type: enhancement"] 6 | sort: "title" 7 | - title: ":beetle: Bug Fixes" 8 | labels: ["type: bug", "type: regression"] 9 | sort: "title" 10 | - title: ":hammer: Dependency Upgrades" 11 | labels: ["type: dependency-upgrade"] 12 | sort: "title" 13 | - title: ":rewind: Non-passive" 14 | labels: ["type: breaks-passivity"] 15 | sort: "title" 16 | issues: 17 | exclude: 18 | labels: [ "status: duplicate" ] 19 | ports: 20 | - label: "status: forward-port" 21 | bodyExpression: 'Forward port of issue #(\d+).*' 22 | contributors: 23 | title: ":heart: Contributors" 24 | exclude: 25 | names: ["rwinch"] 26 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | maven { url 'https://repo.spring.io/release' } 6 | if (version.contains('-')) { 7 | maven { url 'https://repo.spring.io/milestone' } 8 | } 9 | if (version.endsWith('-SNAPSHOT')) { 10 | maven { url 'https://repo.spring.io/snapshot' } 11 | } 12 | } 13 | plugins { 14 | id 'com.gradle.develocity' version "$develocityVersion" 15 | id 'io.spring.ge.conventions' version "$springGeConventionsVersion" 16 | } 17 | } 18 | 19 | plugins { 20 | id "com.gradle.develocity" 21 | id "io.spring.ge.conventions" 22 | } 23 | 24 | rootProject.name = 'spring-security-kerberos' 25 | 26 | include 'spring-security-kerberos-management' 27 | include 'spring-security-kerberos-bom' 28 | include 'spring-security-kerberos-core' 29 | include 'spring-security-kerberos-client' 30 | include 'spring-security-kerberos-web' 31 | include 'spring-security-kerberos-test' 32 | include 'spring-security-kerberos-samples:sec-client-rest-template' 33 | include 'spring-security-kerberos-samples:sec-server-client-auth' 34 | include 'spring-security-kerberos-samples:sec-server-spnego-form-auth' 35 | include 'spring-security-kerberos-samples:sec-server-win-auth' 36 | include 'spring-security-kerberos-docs' 37 | 38 | rootProject.children.each { project -> 39 | project.buildFileName = "${project.name}.gradle" 40 | if (project.name == 'spring-security-kerberos-samples') { 41 | project.children.each { sampleProject -> 42 | sampleProject.buildFileName = "${sampleProject.name}.gradle" 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /spring-security-kerberos-bom/spring-security-kerberos-bom.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.bom' 3 | } 4 | 5 | description = 'Spring Security Kerberos BOM' 6 | -------------------------------------------------------------------------------- /spring-security-kerberos-client/spring-security-kerberos-client.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.spring-module' 3 | } 4 | 5 | description = 'Spring Security Kerberos Client' 6 | 7 | dependencies { 8 | management platform(project(":spring-security-kerberos-management")) 9 | implementation project(':spring-security-kerberos-core') 10 | implementation project(':spring-security-kerberos-web') 11 | // api('org.apache.httpcomponents:httpclient') 12 | api('org.springframework:spring-web') 13 | api libs.httpclient5 14 | optional 'org.springframework.security:spring-security-ldap' 15 | // api('org.springframework.security:spring-security-web') 16 | // api('jakarta.servlet:jakarta.servlet-api') 17 | testImplementation project(':spring-security-kerberos-test') 18 | testImplementation 'org.springframework:spring-test' 19 | testImplementation 'org.springframework.security:spring-security-config' 20 | testImplementation 'org.junit.jupiter:junit-jupiter' 21 | testImplementation 'org.mockito:mockito-junit-jupiter' 22 | testImplementation libs.assertj.core 23 | testImplementation libs.okhttp3.mockwebserver 24 | } 25 | -------------------------------------------------------------------------------- /spring-security-kerberos-client/src/main/java/org/springframework/security/kerberos/client/config/SunJaasKrb5LoginConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.client.config; 17 | 18 | import java.util.HashMap; 19 | 20 | import javax.security.auth.login.AppConfigurationEntry; 21 | import javax.security.auth.login.Configuration; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | import org.springframework.beans.factory.InitializingBean; 26 | import org.springframework.core.io.ClassPathResource; 27 | import org.springframework.core.io.Resource; 28 | import org.springframework.util.Assert; 29 | 30 | /** 31 | * Implementation of {@link Configuration} which uses Sun's JAAS 32 | * Krb5LoginModule. 33 | * 34 | * @author Nelson Rodrigues 35 | * @author Janne Valkealahti 36 | * 37 | */ 38 | public class SunJaasKrb5LoginConfig extends Configuration implements InitializingBean { 39 | 40 | private static final Log LOG = LogFactory.getLog(SunJaasKrb5LoginConfig.class); 41 | 42 | private String servicePrincipal; 43 | private Resource keyTabLocation; 44 | private Boolean useTicketCache = false; 45 | private Boolean isInitiator = false; 46 | private Boolean debug = false; 47 | private String keyTabLocationAsString; 48 | 49 | public void setServicePrincipal(String servicePrincipal) { 50 | this.servicePrincipal = servicePrincipal; 51 | } 52 | 53 | public void setKeyTabLocation(Resource keyTabLocation) { 54 | this.keyTabLocation = keyTabLocation; 55 | } 56 | 57 | public void setUseTicketCache(Boolean useTicketCache) { 58 | this.useTicketCache = useTicketCache; 59 | } 60 | 61 | public void setIsInitiator(Boolean isInitiator) { 62 | this.isInitiator = isInitiator; 63 | } 64 | 65 | public void setDebug(Boolean debug) { 66 | this.debug = debug; 67 | } 68 | 69 | @Override 70 | public void afterPropertiesSet() throws Exception { 71 | Assert.hasText(servicePrincipal, "servicePrincipal must be specified"); 72 | 73 | if (keyTabLocation != null && keyTabLocation instanceof ClassPathResource) { 74 | LOG.warn("Your keytab is in the classpath. This file needs special protection and shouldn't be in the classpath. JAAS may also not be able to load this file from classpath."); 75 | } 76 | 77 | if (!useTicketCache) { 78 | Assert.notNull(keyTabLocation, "keyTabLocation must be specified when useTicketCache is false"); 79 | } 80 | 81 | if (keyTabLocation != null) { 82 | keyTabLocationAsString = keyTabLocation.getURL().toExternalForm(); 83 | if (keyTabLocationAsString.startsWith("file:")) { 84 | keyTabLocationAsString = keyTabLocationAsString.substring(5); 85 | } 86 | } 87 | } 88 | 89 | @Override 90 | public AppConfigurationEntry[] getAppConfigurationEntry(String name) { 91 | HashMap options = new HashMap(); 92 | 93 | options.put("principal", this.servicePrincipal); 94 | 95 | if (this.keyTabLocation != null) { 96 | options.put("useKeyTab", "true"); 97 | options.put("keyTab", keyTabLocationAsString); 98 | options.put("storeKey", "true"); 99 | } 100 | 101 | options.put("doNotPrompt", "true"); 102 | 103 | if (useTicketCache) { 104 | options.put("useTicketCache", "true"); 105 | options.put("renewTGT", "true"); 106 | } 107 | 108 | options.put("isInitiator", this.isInitiator.toString()); 109 | options.put("debug", this.debug.toString()); 110 | 111 | return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", 112 | AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options), }; 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /spring-security-kerberos-client/src/test/java/org/springframework/security/kerberos/client/KerberosRestTemplateTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.client; 17 | 18 | import java.io.File; 19 | import java.nio.charset.StandardCharsets; 20 | import java.util.Collections; 21 | 22 | import okhttp3.mockwebserver.Dispatcher; 23 | import okhttp3.mockwebserver.MockResponse; 24 | import okhttp3.mockwebserver.MockWebServer; 25 | import okhttp3.mockwebserver.RecordedRequest; 26 | import okio.Buffer; 27 | import org.junit.jupiter.api.AfterEach; 28 | import org.junit.jupiter.api.BeforeEach; 29 | import org.junit.jupiter.api.Test; 30 | 31 | import org.springframework.http.MediaType; 32 | import org.springframework.security.kerberos.test.KerberosSecurityTestcase; 33 | import org.springframework.security.kerberos.test.MiniKdc; 34 | 35 | import static org.assertj.core.api.Assertions.assertThat; 36 | import static org.springframework.http.HttpHeaders.AUTHORIZATION; 37 | import static org.springframework.http.HttpHeaders.CONTENT_LENGTH; 38 | import static org.springframework.http.HttpHeaders.CONTENT_TYPE; 39 | import static org.springframework.http.HttpHeaders.WWW_AUTHENTICATE; 40 | 41 | class KerberosRestTemplateTests extends KerberosSecurityTestcase { 42 | 43 | private final MockWebServer server = new MockWebServer(); 44 | private static final String helloWorld = "Hello World"; 45 | private static final MediaType textContentType = 46 | new MediaType("text", "plain", Collections.singletonMap("charset", "UTF-8")); 47 | private int port; 48 | private String baseUrl; 49 | private KerberosRestTemplate restTemplate; 50 | private String clientPrincipal; 51 | private File clientKeytab; 52 | 53 | @BeforeEach 54 | void setUp() throws Exception { 55 | this.server.setDispatcher(new TestDispatcher()); 56 | this.server.start(); 57 | this.port = this.server.getPort(); 58 | this.baseUrl = "http://localhost:" + this.port; 59 | 60 | MiniKdc kdc = getKdc(); 61 | File workDir = getWorkDir(); 62 | 63 | clientPrincipal = "client/localhost"; 64 | clientKeytab = new File(workDir, "client.keytab"); 65 | kdc.createPrincipal(clientKeytab, clientPrincipal); 66 | 67 | String serverPrincipal = "HTTP/localhost"; 68 | File serverKeytab = new File(workDir, "server.keytab"); 69 | kdc.createPrincipal(serverKeytab, serverPrincipal); 70 | } 71 | 72 | @AfterEach 73 | void tearDown() throws Exception { 74 | this.server.shutdown(); 75 | } 76 | 77 | @Test 78 | void sendsNegotiateHeader() { 79 | setUpClient(); 80 | String s = restTemplate.getForObject(baseUrl + "/get", String.class); 81 | assertThat(s).isEqualTo(helloWorld); 82 | } 83 | 84 | private void setUpClient() { 85 | restTemplate = new KerberosRestTemplate(clientKeytab.getAbsolutePath(), clientPrincipal); 86 | } 87 | 88 | private MockResponse getRequest(RecordedRequest request, byte[] body, String contentType) { 89 | if (request.getMethod().equals("OPTIONS")) { 90 | return new MockResponse().setResponseCode(200).setHeader("Allow", "GET, OPTIONS, HEAD, TRACE"); 91 | } 92 | Buffer buf = new Buffer(); 93 | buf.write(body); 94 | MockResponse response = new MockResponse() 95 | .setHeader(CONTENT_LENGTH, body.length) 96 | .setBody(buf) 97 | .setResponseCode(200); 98 | if (contentType != null) { 99 | response = response.setHeader(CONTENT_TYPE, contentType); 100 | } 101 | return response; 102 | } 103 | 104 | protected class TestDispatcher extends Dispatcher { 105 | 106 | @Override 107 | public MockResponse dispatch(RecordedRequest request) throws InterruptedException { 108 | try { 109 | byte[] helloWorldBytes = helloWorld.getBytes(StandardCharsets.UTF_8); 110 | 111 | if (request.getPath().equals("/get")) { 112 | String header = request.getHeader(AUTHORIZATION); 113 | if (header == null) { 114 | return new MockResponse().setResponseCode(401).addHeader(WWW_AUTHENTICATE, "Negotiate"); 115 | } 116 | else if (header != null && header.startsWith("Negotiate ")) { 117 | return getRequest(request, helloWorldBytes, textContentType.toString()); 118 | } 119 | } 120 | return new MockResponse().setResponseCode(404); 121 | } 122 | catch (Throwable ex) { 123 | return new MockResponse().setResponseCode(500).setBody(ex.toString()); 124 | } 125 | 126 | } 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /spring-security-kerberos-client/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2} - %m%n 6 | 7 | log4j.category.org.springframework.boot=INFO 8 | xlog4j.category.org.apache.http.wire=TRACE 9 | xlog4j.category.org.apache.http.headers=TRACE 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-client/src/test/resources/minikdc-krb5.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | [libdefaults] 19 | default_realm = {0} 20 | udp_preference_limit = 1 21 | forwardable = true 22 | 23 | [realms] 24 | {0} = '{' 25 | kdc = {1}:{2} 26 | '}' -------------------------------------------------------------------------------- /spring-security-kerberos-client/src/test/resources/minikdc.ldiff: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | dn: ou=users,dc=${0},dc=${1} 19 | objectClass: organizationalUnit 20 | objectClass: top 21 | ou: users 22 | 23 | dn: uid=krbtgt,ou=users,dc=${0},dc=${1} 24 | objectClass: top 25 | objectClass: person 26 | objectClass: inetOrgPerson 27 | objectClass: krb5principal 28 | objectClass: krb5kdcentry 29 | cn: KDC Service 30 | sn: Service 31 | uid: krbtgt 32 | userPassword: secret 33 | krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3} 34 | krb5KeyVersionNumber: 0 35 | 36 | dn: uid=ldap,ou=users,dc=${0},dc=${1} 37 | objectClass: top 38 | objectClass: person 39 | objectClass: inetOrgPerson 40 | objectClass: krb5principal 41 | objectClass: krb5kdcentry 42 | cn: LDAP 43 | sn: Service 44 | uid: ldap 45 | userPassword: secret 46 | krb5PrincipalName: ldap/${4}@${2}.${3} 47 | krb5KeyVersionNumber: 0 48 | 49 | dn: uid=user1,ou=users,dc=${0},dc=${1} 50 | objectClass: top 51 | objectClass: person 52 | objectClass: inetOrgPerson 53 | objectClass: krb5principal 54 | objectClass: krb5kdcentry 55 | cn: user1 56 | sn: Service 57 | uid: user1 58 | userPassword: secret 59 | krb5PrincipalName: user1@${2}.${3} 60 | krb5KeyVersionNumber: 0 61 | 62 | dn: uid=webtier,ou=users,dc=${0},dc=${1} 63 | objectClass: top 64 | objectClass: person 65 | objectClass: inetOrgPerson 66 | objectClass: krb5principal 67 | objectClass: krb5kdcentry 68 | cn: webtier 69 | sn: Service 70 | uid: webtier 71 | userPassword: secret 72 | krb5PrincipalName: HTTP/webtier@${2}.${3} 73 | krb5KeyVersionNumber: 0 74 | 75 | dn: uid=servicetier,ou=users,dc=${0},dc=${1} 76 | objectClass: top 77 | objectClass: person 78 | objectClass: inetOrgPerson 79 | objectClass: krb5principal 80 | objectClass: krb5kdcentry 81 | cn: servicetier 82 | sn: Service 83 | uid: servicetier 84 | userPassword: secret 85 | krb5PrincipalName: HTTP/servicetier@${2}.${3} 86 | krb5KeyVersionNumber: 0 87 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/spring-security-kerberos-core.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.spring-module' 3 | } 4 | 5 | description = 'Spring Security Kerberos Core' 6 | 7 | dependencies { 8 | management platform(project(":spring-security-kerberos-management")) 9 | api('org.springframework.security:spring-security-core') 10 | testImplementation 'org.junit.jupiter:junit-jupiter' 11 | testImplementation 'org.mockito:mockito-junit-jupiter' 12 | testImplementation libs.assertj.core 13 | } 14 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/JaasSubjectHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication; 17 | 18 | import java.io.Serializable; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | import javax.security.auth.Subject; 23 | 24 | import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; 25 | 26 | /** 27 | *

Holds the Subject of the currently authenticated user, since this 28 | * Jaas object also has the credentials, and permits creating new 29 | * credentials against other Kerberos services.

30 | * @author Bogdan Mustiata 31 | * @see SunJaasKerberosClient 32 | * @see org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider 33 | */ 34 | public class JaasSubjectHolder implements Serializable { 35 | 36 | private static final long serialVersionUID = 8174713761131577405L; 37 | 38 | private Subject jaasSubject; 39 | private String username; 40 | 41 | private Map savedTokens = new HashMap(); 42 | 43 | public JaasSubjectHolder(Subject jaasSubject) { 44 | this.jaasSubject = jaasSubject; 45 | } 46 | 47 | public JaasSubjectHolder(Subject jaasSubject, String username) { 48 | this.jaasSubject = jaasSubject; 49 | this.username = username; 50 | } 51 | 52 | public String getUsername() { 53 | return username; 54 | } 55 | 56 | public Subject getJaasSubject() { 57 | return jaasSubject; 58 | } 59 | 60 | public void addToken(String targetService, byte[] outToken) { 61 | this.savedTokens.put(targetService, outToken); 62 | } 63 | 64 | public byte[] getToken(String principalName) { 65 | return savedTokens.get(principalName); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosAuthentication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication; 17 | 18 | public interface KerberosAuthentication { 19 | 20 | JaasSubjectHolder getJaasSubjectHolder(); 21 | } 22 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosAuthenticationProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication; 17 | 18 | import org.springframework.security.authentication.AuthenticationProvider; 19 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 20 | import org.springframework.security.core.Authentication; 21 | import org.springframework.security.core.AuthenticationException; 22 | import org.springframework.security.core.userdetails.UserDetails; 23 | import org.springframework.security.core.userdetails.UserDetailsService; 24 | 25 | /** 26 | * {@link AuthenticationProvider} for kerberos. 27 | * 28 | * @author Mike Wiesner 29 | * @author Bogdan Mustiata 30 | * @since 1.0 31 | */ 32 | public class KerberosAuthenticationProvider implements AuthenticationProvider { 33 | 34 | private KerberosClient kerberosClient; 35 | 36 | private UserDetailsService userDetailsService; 37 | 38 | @Override 39 | public Authentication authenticate(Authentication authentication) throws AuthenticationException { 40 | UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; 41 | JaasSubjectHolder subjectHolder = kerberosClient.login(auth.getName(), auth.getCredentials().toString()); 42 | UserDetails userDetails = this.userDetailsService.loadUserByUsername(subjectHolder.getUsername()); 43 | KerberosUsernamePasswordAuthenticationToken output = new KerberosUsernamePasswordAuthenticationToken( 44 | userDetails, auth.getCredentials(), userDetails.getAuthorities(), subjectHolder); 45 | output.setDetails(authentication.getDetails()); 46 | return output; 47 | 48 | } 49 | 50 | @Override 51 | public boolean supports(Class authentication) { 52 | return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); 53 | } 54 | 55 | /** 56 | * Sets the kerberos client. 57 | * 58 | * @param kerberosClient the new kerberos client 59 | */ 60 | public void setKerberosClient(KerberosClient kerberosClient) { 61 | this.kerberosClient = kerberosClient; 62 | } 63 | 64 | /** 65 | * Sets the user details service. 66 | * 67 | * @param detailsService the new user details service 68 | */ 69 | public void setUserDetailsService(UserDetailsService detailsService) { 70 | this.userDetailsService = detailsService; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.security.kerberos.authentication; 18 | 19 | /** 20 | * 21 | * @author Mike Wiesner 22 | * @author Bogdan Mustiata 23 | * @since 1.0 24 | * @version $Id$ 25 | */ 26 | public interface KerberosClient { 27 | 28 | public JaasSubjectHolder login(String username, String password); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosTicketValidation.java: -------------------------------------------------------------------------------- 1 | package org.springframework.security.kerberos.authentication; 2 | 3 | import java.util.HashSet; 4 | 5 | import javax.security.auth.Subject; 6 | import javax.security.auth.kerberos.KerberosPrincipal; 7 | 8 | import org.ietf.jgss.GSSContext; 9 | import org.ietf.jgss.GSSCredential; 10 | 11 | /** 12 | * Result of ticket validation 13 | */ 14 | public class KerberosTicketValidation { 15 | 16 | private final String username; 17 | private final Subject subject; 18 | private final byte[] responseToken; 19 | private final GSSContext gssContext; 20 | private final GSSCredential delegationCredential; 21 | 22 | public KerberosTicketValidation(String username, String servicePrincipal, byte[] responseToken, GSSContext gssContext) { 23 | this(username, servicePrincipal, responseToken, gssContext, null); 24 | } 25 | 26 | public KerberosTicketValidation(String username, String servicePrincipal, byte[] responseToken, GSSContext gssContext, GSSCredential delegationCredential) { 27 | final HashSet princs = new HashSet(); 28 | princs.add(new KerberosPrincipal(servicePrincipal)); 29 | 30 | this.username = username; 31 | this.subject = new Subject(false, princs, new HashSet(), new HashSet()); 32 | this.responseToken = responseToken; 33 | this.gssContext = gssContext; 34 | this.delegationCredential = delegationCredential; 35 | } 36 | 37 | public KerberosTicketValidation(String username, Subject subject, byte[] responseToken, GSSContext gssContext) { 38 | this(username, subject, responseToken, gssContext, null); 39 | } 40 | 41 | public KerberosTicketValidation(String username, Subject subject, byte[] responseToken, GSSContext gssContext, GSSCredential delegationCredential) { 42 | this.username = username; 43 | this.subject = subject; 44 | this.responseToken = responseToken; 45 | this.gssContext = gssContext; 46 | this.delegationCredential = delegationCredential; 47 | } 48 | 49 | public String username() { 50 | return username; 51 | } 52 | 53 | public byte[] responseToken() { 54 | return responseToken; 55 | } 56 | 57 | public GSSContext getGssContext() { 58 | return gssContext; 59 | } 60 | 61 | public Subject subject() { 62 | return this.subject; 63 | } 64 | 65 | public GSSCredential getDelegationCredential() { 66 | return delegationCredential; 67 | } 68 | } -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosTicketValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication; 17 | 18 | import org.springframework.security.authentication.BadCredentialsException; 19 | 20 | /** 21 | * Implementations of this interface are used in 22 | * {@link KerberosServiceAuthenticationProvider} to validate a Kerberos/SPNEGO 23 | * Ticket. 24 | * 25 | * @author Mike Wiesner 26 | * @author Jeremy Stone 27 | * @since 1.0 28 | * @see KerberosServiceAuthenticationProvider 29 | */ 30 | public interface KerberosTicketValidator { 31 | 32 | /** 33 | * Validates a Kerberos/SPNEGO ticket. 34 | * 35 | * @param token Kerbeos/SPNEGO ticket 36 | * @return authenticated kerberos principal 37 | * @throws BadCredentialsException if the ticket is not valid 38 | */ 39 | public KerberosTicketValidation validateTicket(byte[] token) 40 | throws BadCredentialsException; 41 | } 42 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosUsernamePasswordAuthenticationToken.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication; 17 | 18 | import java.util.Collection; 19 | 20 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 21 | import org.springframework.security.core.GrantedAuthority; 22 | 23 | /** 24 | *

Holds the Username/Password as well as the JAAS Subject allowing 25 | * multi-tier authentications using Kerberos.

26 | * 27 | *

The JAAS Subject has in its private credentials the Kerberos tickets 28 | * for generating new tickets against other service principals using 29 | * KerberosMultiTier.authenticateService()

30 | * 31 | * @author Bogdan Mustiata 32 | * @see KerberosAuthenticationProvider 33 | * @see KerberosMultiTier 34 | */ 35 | public class KerberosUsernamePasswordAuthenticationToken 36 | extends UsernamePasswordAuthenticationToken 37 | implements KerberosAuthentication { 38 | 39 | private static final long serialVersionUID = 6327699460703504153L; 40 | 41 | private final JaasSubjectHolder jaasSubjectHolder; 42 | 43 | /** 44 | *

Creates an authentication token that holds the username and password, and the Subject 45 | * that the user will need to create new authentication tokens against other services.

46 | * @param principal 47 | * @param credentials 48 | * @param authorities 49 | * @param subjectHolder 50 | */ 51 | public KerberosUsernamePasswordAuthenticationToken(Object principal, 52 | Object credentials, 53 | Collection authorities, 54 | JaasSubjectHolder subjectHolder) { 55 | super(principal, credentials, authorities); 56 | this.jaasSubjectHolder = subjectHolder; 57 | } 58 | 59 | @Override 60 | public JaasSubjectHolder getJaasSubjectHolder() { 61 | return jaasSubjectHolder; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/sun/GlobalSunJaasKerberosConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication.sun; 17 | 18 | import org.springframework.beans.BeansException; 19 | import org.springframework.beans.factory.InitializingBean; 20 | import org.springframework.beans.factory.config.BeanPostProcessor; 21 | 22 | /** 23 | * Config for global jaas. 24 | * 25 | * @author Mike Wiesner 26 | * @since 1.0 27 | */ 28 | public class GlobalSunJaasKerberosConfig implements BeanPostProcessor, InitializingBean { 29 | 30 | private boolean debug = false; 31 | 32 | private String krbConfLocation; 33 | 34 | @Override 35 | public void afterPropertiesSet() throws Exception { 36 | if (debug) { 37 | System.setProperty("sun.security.krb5.debug", "true"); 38 | } 39 | if (krbConfLocation != null) { 40 | System.setProperty("java.security.krb5.conf", krbConfLocation); 41 | } 42 | 43 | } 44 | 45 | /** 46 | * Enable debug logs from the Sun Kerberos Implementation. Default is false. 47 | * 48 | * @param debug true if debug should be enabled 49 | */ 50 | public void setDebug(boolean debug) { 51 | this.debug = debug; 52 | } 53 | 54 | /** 55 | * Kerberos config file location can be specified here. 56 | * 57 | * @param krbConfLocation the path to krb config file 58 | */ 59 | public void setKrbConfLocation(String krbConfLocation) { 60 | this.krbConfLocation = krbConfLocation; 61 | } 62 | 63 | // The following methods are not used here. This Bean implements only BeanPostProcessor to ensure that it 64 | // is created before any other bean is created, because the system properties needed to be set very early 65 | // in the startup-phase, but after the BeanFactoryPostProcessing. 66 | 67 | @Override 68 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 69 | return bean; 70 | } 71 | 72 | @Override 73 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 74 | return bean; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/sun/JaasUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication.sun; 17 | 18 | import java.security.Principal; 19 | import java.util.HashSet; 20 | 21 | import javax.security.auth.Subject; 22 | 23 | /** 24 | * JAAS utility functions. 25 | * @author Bogdan Mustiata 26 | */ 27 | public class JaasUtil { 28 | /** 29 | * Copy the principal and the credentials into a new Subject. 30 | * @param subject 31 | * @return 32 | */ 33 | public static Subject copySubject(Subject subject) { 34 | Subject subjectCopy = new Subject(false, 35 | new HashSet(subject.getPrincipals()), 36 | new HashSet(subject.getPublicCredentials()), 37 | new HashSet(subject.getPrivateCredentials())); 38 | 39 | return subjectCopy; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/test/java/org/springframework/security/kerberos/authentication/KerberosAuthenticationProviderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.authentication; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertEquals; 19 | import static org.junit.jupiter.api.Assertions.assertNotNull; 20 | import static org.mockito.Mockito.mock; 21 | import static org.mockito.Mockito.verify; 22 | import static org.mockito.Mockito.when; 23 | 24 | import java.util.List; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.junit.jupiter.api.Test; 28 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 29 | import org.springframework.security.core.Authentication; 30 | import org.springframework.security.core.GrantedAuthority; 31 | import org.springframework.security.core.authority.AuthorityUtils; 32 | import org.springframework.security.core.userdetails.User; 33 | import org.springframework.security.core.userdetails.UserDetails; 34 | import org.springframework.security.core.userdetails.UserDetailsService; 35 | 36 | /** 37 | * Test class for {@link KerberosAuthenticationProvider} 38 | * 39 | * @author Mike Wiesner 40 | * @since 1.0 41 | */ 42 | public class KerberosAuthenticationProviderTest { 43 | 44 | private KerberosAuthenticationProvider provider; 45 | private KerberosClient kerberosClient; 46 | private UserDetailsService userDetailsService; 47 | 48 | private static final String TEST_USER = "Testuser@SPRINGSOURCE.ORG"; 49 | private static final String TEST_PASSWORD = "password"; 50 | private static final UsernamePasswordAuthenticationToken INPUT_TOKEN = new UsernamePasswordAuthenticationToken(TEST_USER, TEST_PASSWORD); 51 | private static final List AUTHORITY_LIST = AuthorityUtils.createAuthorityList("ROLE_ADMIN"); 52 | private static final UserDetails USER_DETAILS = new User(TEST_USER, "empty", true, true, true,true, AUTHORITY_LIST); 53 | private static final JaasSubjectHolder JAAS_SUBJECT_HOLDER = new JaasSubjectHolder(null, TEST_USER); 54 | 55 | @BeforeEach 56 | public void before() { 57 | // mocking 58 | this.kerberosClient = mock(KerberosClient.class); 59 | this.userDetailsService = mock(UserDetailsService.class); 60 | this.provider = new KerberosAuthenticationProvider(); 61 | this.provider.setKerberosClient(kerberosClient); 62 | this.provider.setUserDetailsService(userDetailsService); 63 | } 64 | 65 | @Test 66 | public void testLoginOk() throws Exception { 67 | when(userDetailsService.loadUserByUsername(TEST_USER)).thenReturn(USER_DETAILS); 68 | when(kerberosClient.login(TEST_USER, TEST_PASSWORD)).thenReturn(JAAS_SUBJECT_HOLDER); 69 | 70 | Authentication authenticate = provider.authenticate(INPUT_TOKEN); 71 | 72 | verify(kerberosClient).login(TEST_USER, TEST_PASSWORD); 73 | 74 | assertNotNull(authenticate); 75 | assertEquals(TEST_USER, authenticate.getName()); 76 | assertEquals(USER_DETAILS, authenticate.getPrincipal()); 77 | assertEquals(TEST_PASSWORD, authenticate.getCredentials()); 78 | assertEquals(AUTHORITY_LIST, authenticate.getAuthorities()); 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /spring-security-kerberos-core/src/test/java/org/springframework/security/kerberos/authentication/KerberosTicketValidationTest.java: -------------------------------------------------------------------------------- 1 | package org.springframework.security.kerberos.authentication; 2 | 3 | import javax.security.auth.Subject; 4 | 5 | import org.ietf.jgss.GSSContext; 6 | import org.ietf.jgss.GSSCredential; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNull; 11 | import static org.mockito.Mockito.mock; 12 | 13 | public class KerberosTicketValidationTest { 14 | 15 | private String username = "username"; 16 | private Subject subject = new Subject(); 17 | private byte[] responseToken = "token".getBytes(); 18 | private GSSContext gssContext = mock(GSSContext.class); 19 | private GSSCredential delegationCredential = mock(GSSCredential.class); 20 | 21 | @Test 22 | public void createResultOfTicketValidationWithSubject() { 23 | 24 | KerberosTicketValidation ticketValidation = new KerberosTicketValidation( 25 | username, 26 | subject, 27 | responseToken, 28 | gssContext); 29 | 30 | assertEquals(username, ticketValidation.username()); 31 | assertEquals(responseToken, ticketValidation.responseToken()); 32 | assertEquals(gssContext, ticketValidation.getGssContext()); 33 | 34 | assertNull(ticketValidation.getDelegationCredential(), "With no credential delegation"); 35 | } 36 | 37 | @Test 38 | public void createResultOfTicketValidationWithSubjectAndDelegation() { 39 | 40 | KerberosTicketValidation ticketValidation = new KerberosTicketValidation( 41 | username, 42 | subject, 43 | responseToken, 44 | gssContext, 45 | delegationCredential); 46 | 47 | assertEquals(username, ticketValidation.username()); 48 | assertEquals(responseToken, ticketValidation.responseToken()); 49 | assertEquals(gssContext, ticketValidation.getGssContext()); 50 | 51 | assertEquals(delegationCredential, ticketValidation.getDelegationCredential(), "With credential delegation"); 52 | } 53 | } -------------------------------------------------------------------------------- /spring-security-kerberos-docs/antora-playbook.yml: -------------------------------------------------------------------------------- 1 | antora: 2 | extensions: 3 | - require: '@springio/antora-extensions' 4 | root_component_name: 'kerberos' 5 | site: 6 | title: Spring Security Kerberos 7 | url: https://docs.spring.io/spring-security-kerberos/reference 8 | robots: allow 9 | git: 10 | ensure_git_suffix: false 11 | content: 12 | sources: 13 | - url: https://github.com/spring-projects/spring-security-kerberos 14 | # Refname matching: 15 | # https://docs.antora.org/antora/latest/playbook/content-refname-matching/ 16 | branches: [main,'*.x','!1.*.x'] 17 | tags: ['*','!1.*'] 18 | start_path: spring-security-kerberos-docs 19 | asciidoc: 20 | extensions: 21 | - '@asciidoctor/tabs' 22 | - '@springio/asciidoctor-extensions' 23 | - '@springio/asciidoctor-extensions/include-code-extension' 24 | attributes: 25 | page-stackoverflow-url: https://stackoverflow.com/tags/spring-security 26 | page-related-doc-categories: security 27 | page-related-doc-projects: framework,graphql 28 | hide-uri-scheme: '@' 29 | tabs-sync-option: '@' 30 | urls: 31 | latest_version_segment_strategy: redirect:to 32 | latest_version_segment: '' 33 | redirect_facility: httpd 34 | runtime: 35 | log: 36 | failure_level: warn 37 | ui: 38 | bundle: 39 | url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.15/ui-bundle.zip 40 | snapshot: true 41 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: ROOT 2 | version: true 3 | title: Spring Security Kerberos 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | ext: 7 | collector: 8 | run: 9 | command: gradlew -PbuildSrc.skipTests=true "-Dorg.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError" :spring-security-kerberos-docs:generateAntoraYml 10 | local: true 11 | scan: 12 | dir: ./build/generated-antora-resources 13 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/examples/AuthProviderConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 5 | * file except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under 10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | package org.springframework.security.kerberos.docs; 15 | 16 | import org.junit.Test; 17 | import org.junit.runner.RunWith; 18 | import org.springframework.test.context.ContextConfiguration; 19 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 20 | 21 | @RunWith(SpringJUnit4ClassRunner.class) 22 | @ContextConfiguration(locations= {"AuthProviderConfig.xml"}) 23 | public class AuthProviderConfigTest { 24 | 25 | @Test 26 | public void configLoads() {} 27 | } 28 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/examples/DummyUserDetailsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.docs; 17 | 18 | import org.springframework.security.core.authority.AuthorityUtils; 19 | import org.springframework.security.core.userdetails.User; 20 | import org.springframework.security.core.userdetails.UserDetails; 21 | import org.springframework.security.core.userdetails.UserDetailsService; 22 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 23 | 24 | //tag::snippetA[] 25 | public class DummyUserDetailsService implements UserDetailsService { 26 | 27 | @Override 28 | public UserDetails loadUserByUsername(String username) 29 | throws UsernameNotFoundException { 30 | return new User(username, "notUsed", true, true, true, true, 31 | AuthorityUtils.createAuthorityList("ROLE_USER")); 32 | } 33 | 34 | } 35 | //end::snippetA[] 36 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/examples/KerberosLdapContextSourceConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.client.docs; 17 | 18 | import org.springframework.beans.factory.annotation.Value; 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.core.io.FileSystemResource; 21 | import org.springframework.security.kerberos.client.config.SunJaasKrb5LoginConfig; 22 | import org.springframework.security.kerberos.client.ldap.KerberosLdapContextSource; 23 | import org.springframework.security.ldap.search.FilterBasedLdapUserSearch; 24 | import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper; 25 | import org.springframework.security.ldap.userdetails.LdapUserDetailsService; 26 | 27 | public class KerberosLdapContextSourceConfig { 28 | 29 | //tag::snippetA[] 30 | @Value("${app.ad-server}") 31 | private String adServer; 32 | 33 | @Value("${app.service-principal}") 34 | private String servicePrincipal; 35 | 36 | @Value("${app.keytab-location}") 37 | private String keytabLocation; 38 | 39 | @Value("${app.ldap-search-base}") 40 | private String ldapSearchBase; 41 | 42 | @Value("${app.ldap-search-filter}") 43 | private String ldapSearchFilter; 44 | 45 | @Bean 46 | public KerberosLdapContextSource kerberosLdapContextSource() { 47 | KerberosLdapContextSource contextSource = new KerberosLdapContextSource(adServer); 48 | SunJaasKrb5LoginConfig loginConfig = new SunJaasKrb5LoginConfig(); 49 | loginConfig.setKeyTabLocation(new FileSystemResource(keytabLocation)); 50 | loginConfig.setServicePrincipal(servicePrincipal); 51 | loginConfig.setDebug(true); 52 | loginConfig.setIsInitiator(true); 53 | contextSource.setLoginConfig(loginConfig); 54 | return contextSource; 55 | } 56 | 57 | @Bean 58 | public LdapUserDetailsService ldapUserDetailsService() { 59 | FilterBasedLdapUserSearch userSearch = 60 | new FilterBasedLdapUserSearch(ldapSearchBase, ldapSearchFilter, kerberosLdapContextSource()); 61 | LdapUserDetailsService service = new LdapUserDetailsService(userSearch); 62 | service.setUserDetailsMapper(new LdapUserDetailsMapper()); 63 | return service; 64 | } 65 | //end::snippetA[] 66 | 67 | } 68 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/examples/KerberosRestTemplateConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.client.docs; 17 | 18 | import org.springframework.security.kerberos.client.KerberosRestTemplate; 19 | 20 | public class KerberosRestTemplateConfig { 21 | 22 | //tag::snippetA[] 23 | public void doWithTicketCache() { 24 | KerberosRestTemplate restTemplate = 25 | new KerberosRestTemplate(); 26 | restTemplate.getForObject("http://neo.example.org:8080/hello", String.class); 27 | } 28 | //end::snippetA[] 29 | 30 | //tag::snippetB[] 31 | public void doWithKeytabFile() { 32 | KerberosRestTemplate restTemplate = 33 | new KerberosRestTemplate("/tmp/user2.keytab", "user2@EXAMPLE.ORG"); 34 | restTemplate.getForObject("http://neo.example.org:8080/hello", String.class); 35 | } 36 | //end::snippetB[] 37 | 38 | } 39 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc1.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc2.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc3.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/drawio-kerb-cc4.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/ff1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/ff1.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/ff2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/ff2.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/ff3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/ff3.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/ie1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/ie1.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/images/ie2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-security-kerberos/c167e12bf2ff361433aa1828ff2079a59bad4b43/spring-security-kerberos-docs/modules/ROOT/images/ie2.png -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Overview] 2 | * xref:introduction.adoc[Introduction] 3 | * xref:ssk.adoc[Reference] 4 | * xref:samples.adoc[Samples] 5 | * xref:appendix.adoc[Appendices] 6 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Spring Security Kerberos 2 | 3 | Spring Security Kerberos is an extension of Spring Security for 4 | application developers to Kerberos concepts with Spring. 5 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/pages/introduction.adoc: -------------------------------------------------------------------------------- 1 | [[introduction]] 2 | = Introduction 3 | 4 | Spring Security Kerberos {version} is built and tested with JDK 17, 5 | Spring Security {spring-security-version} and Spring Framework {spring-version}. 6 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/modules/ROOT/pages/ssk.adoc: -------------------------------------------------------------------------------- 1 | [[springsecuritykerberos]] 2 | = Spring and Spring Security Kerberos 3 | 4 | This part of the reference documentation explains the core functionality 5 | that Spring Security Kerberos provides to any Spring based application. 6 | 7 | <> describes the authentication provider support. 8 | 9 | <> describes the spnego negotiate support. 10 | 11 | <> describes the RestTemplate support. 12 | 13 | 14 | [[ssk-authprovider]] 15 | == Authentication Provider 16 | 17 | Provider configuration using JavaConfig. 18 | 19 | [source,java,indent=0] 20 | ---- 21 | include::example$AuthProviderConfig.java[tags=snippetA] 22 | ---- 23 | 24 | [[ssk-spnego]] 25 | == Spnego Negotiate 26 | 27 | Spnego configuration using JavaConfig. 28 | 29 | [source,java,indent=0] 30 | ---- 31 | include::example$SpnegoConfig.java[tags=snippetA] 32 | ---- 33 | 34 | [[ssk-resttemplate]] 35 | == Using KerberosRestTemplate 36 | 37 | If there is a need to access Kerberos protected web resources 38 | programmatically we have `KerberosRestTemplate` which extends 39 | `RestTemplate` and does necessary login actions prior to delegating to 40 | actual RestTemplate methods. You basically have few options to 41 | configure this template. 42 | 43 | - Leave keyTabLocation and userPrincipal empty if you want to 44 | use cached ticket. 45 | - Use keyTabLocation and userPrincipal if you want to use 46 | keytab file. 47 | - Use loginOptions if you want to customise Krb5LoginModule options. 48 | - Use a customised httpClient. 49 | 50 | With ticket cache. 51 | [source,java,indent=0] 52 | ---- 53 | include::example$KerberosRestTemplateConfig.java[tags=snippetA] 54 | ---- 55 | 56 | With keytab file. 57 | [source,java,indent=0] 58 | ---- 59 | include::example$KerberosRestTemplateConfig.java[tags=snippetB] 60 | ---- 61 | 62 | [[ssk-kerberosldap]] 63 | == Authentication with LDAP Services 64 | 65 | With most of your samples we're using `DummyUserDetailsService` 66 | because there is not necessarily need to query a real user details 67 | once kerberos authentication is successful and we can use kerberos 68 | principal info to create that dummy user. However there is a way to 69 | access kerberized LDAP services in a say way and query user details 70 | from there. 71 | 72 | `KerberosLdapContextSource` can be used to bind into LDAP via kerberos 73 | which is at least proven to work well with Windows AD services. 74 | 75 | [source,java,indent=0] 76 | ---- 77 | include::example$KerberosLdapContextSourceConfig.java[tags=snippetA] 78 | ---- 79 | 80 | [TIP] 81 | ==== 82 | Sample xref:samples.adoc#samples-sec-server-win-auth[Security Server Windows Auth Sample] 83 | is currently configured to query user details from AD if authentication happen via kerberos. 84 | ==== 85 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "antora": "3.2.0-alpha.4", 4 | "@antora/atlas-extension": "1.0.0-alpha.2", 5 | "@antora/collector-extension": "1.0.0-alpha.3", 6 | "@asciidoctor/tabs": "1.0.0-beta.6", 7 | "@springio/antora-extensions": "1.10.0", 8 | "@springio/asciidoctor-extensions": "1.0.0-alpha.10" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-docs/spring-security-kerberos-docs.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.docs' 3 | id 'org.antora' version '1.0.0' 4 | id 'io.spring.antora.generate-antora-yml' version '0.0.1' 5 | id 'java' 6 | } 7 | 8 | description = 'Spring Security Kerberos Documentation' 9 | 10 | dependencies { 11 | management platform(project(":spring-security-kerberos-management")) 12 | testImplementation 'org.springframework:spring-core' 13 | testImplementation 'org.springframework.security:spring-security-core' 14 | } 15 | 16 | antora { 17 | options = [clean: true, fetch: !project.gradle.startParameter.offline, stacktrace: true] 18 | environment = [ 19 | 'BUILD_REFNAME': 'HEAD', 20 | 'BUILD_VERSION': project.version, 21 | ] 22 | } 23 | 24 | 25 | 26 | tasks.named("generateAntoraYml") { 27 | asciidocAttributes = project.provider( { generateAttributes() } ) 28 | } 29 | 30 | def generateAttributes() { 31 | return [ 32 | "version": project.version 33 | ] + resolvedVersions(project.configurations.testRuntimeClasspath) 34 | } 35 | 36 | def resolvedVersions(Configuration configuration) { 37 | return configuration.resolvedConfiguration 38 | .resolvedArtifacts 39 | .collectEntries { [(it.name.replace('-core','') + '-version'): it.moduleVersion.id.version] } 40 | } 41 | 42 | docsZip { 43 | from (api) { 44 | into "api" 45 | } 46 | } -------------------------------------------------------------------------------- /spring-security-kerberos-management/spring-security-kerberos-management.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-platform' 3 | } 4 | 5 | javaPlatform { 6 | allowDependencies() 7 | } 8 | 9 | description = 'Spring Security Kerberos Management' 10 | 11 | dependencies { 12 | api platform(libs.spring.framework.bom) 13 | api platform(libs.spring.security.bom) 14 | api platform(libs.junit.bom) 15 | api platform(libs.mockito.bom) 16 | constraints { 17 | api libs.httpclient5 18 | api libs.assertj.core 19 | api libs.servlet.api 20 | api libs.kerby 21 | api libs.okhttp3.mockwebserver 22 | api libs.okhttp3 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-client-rest-template/sec-client-rest-template.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.security.kerberos.sample' 3 | alias libs.plugins.spring.boot 4 | alias libs.plugins.dependency.management 5 | } 6 | 7 | description = 'Security Client RestTemplate Sample' 8 | 9 | dependencies { 10 | management platform(project(":spring-security-kerberos-management")) 11 | implementation project(':spring-security-kerberos-client') 12 | implementation 'org.springframework.boot:spring-boot-starter' 13 | testImplementation 'org.springframework:spring-test' 14 | testImplementation 'org.junit.jupiter:junit-jupiter' 15 | testImplementation 'org.mockito:mockito-junit-jupiter' 16 | testImplementation 'org.assertj:assertj-core' 17 | } 18 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-client-rest-template/src/main/java/demo/app/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.beans.factory.annotation.Value; 19 | import org.springframework.boot.CommandLineRunner; 20 | import org.springframework.boot.WebApplicationType; 21 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 22 | import org.springframework.boot.autoconfigure.SpringBootApplication; 23 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; 24 | import org.springframework.boot.builder.SpringApplicationBuilder; 25 | import org.springframework.security.kerberos.client.KerberosRestTemplate; 26 | 27 | @SpringBootApplication 28 | @EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) 29 | public class Application implements CommandLineRunner { 30 | 31 | @Value("${app.user-principal}") 32 | private String userPrincipal; 33 | 34 | @Value("${app.keytab-location}") 35 | private String keytabLocation; 36 | 37 | @Value("${app.access-url}") 38 | private String accessUrl; 39 | 40 | @Override 41 | public void run(String... args) throws Exception { 42 | KerberosRestTemplate restTemplate = 43 | new KerberosRestTemplate(keytabLocation, userPrincipal); 44 | String response = restTemplate.getForObject(accessUrl, String.class); 45 | System.out.println(response); 46 | } 47 | 48 | public static void main(String[] args) throws Throwable { 49 | new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-client-rest-template/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | app: 2 | user-principal: user2@KERBOS.COM 3 | keytab-location: /tmp/user2.keytab 4 | access-url: http://cypher.localdomain:8080/hello 5 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/sec-server-client-auth.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.security.kerberos.sample' 3 | alias libs.plugins.spring.boot 4 | alias libs.plugins.dependency.management 5 | } 6 | 7 | description = 'Security Server Client Auth Sample' 8 | 9 | dependencies { 10 | management platform(project(":spring-security-kerberos-management")) 11 | implementation project(':spring-security-kerberos-core') 12 | implementation project(':spring-security-kerberos-web') 13 | implementation 'org.springframework.security:spring-security-config' 14 | implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' 15 | implementation 'org.springframework.boot:spring-boot-starter' 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 18 | testImplementation 'org.springframework:spring-test' 19 | testImplementation 'org.junit.jupiter:junit-jupiter' 20 | testImplementation 'org.mockito:mockito-junit-jupiter' 21 | testImplementation 'org.assertj:assertj-core' 22 | } 23 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/java/demo/app/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | 21 | @SpringBootApplication 22 | public class Application { 23 | 24 | public static void main(String[] args) throws Throwable { 25 | SpringApplication.run(Application.class, args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/java/demo/app/DummyUserDetailsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.security.core.authority.AuthorityUtils; 19 | import org.springframework.security.core.userdetails.User; 20 | import org.springframework.security.core.userdetails.UserDetails; 21 | import org.springframework.security.core.userdetails.UserDetailsService; 22 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 23 | 24 | public class DummyUserDetailsService implements UserDetailsService { 25 | 26 | @Override 27 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 28 | return new User(username, "{noop}notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER")); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/java/demo/app/MvcConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 20 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 21 | 22 | @Configuration 23 | public class MvcConfig implements WebMvcConfigurer { 24 | 25 | @Override 26 | public void addViewControllers(ViewControllerRegistry registry) { 27 | registry.addViewController("/home").setViewName("home"); 28 | registry.addViewController("/").setViewName("home"); 29 | registry.addViewController("/hello").setViewName("hello"); 30 | registry.addViewController("/login").setViewName("login"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/java/demo/app/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 21 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 22 | import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; 23 | import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; 24 | import org.springframework.security.web.SecurityFilterChain; 25 | 26 | @Configuration 27 | @EnableWebSecurity 28 | public class WebSecurityConfig { 29 | 30 | @Bean 31 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 32 | http 33 | .authorizeHttpRequests((authz) -> authz 34 | .requestMatchers("/", "/home").permitAll() 35 | .anyRequest().authenticated() 36 | ) 37 | .formLogin((form) -> form 38 | .loginPage("/login").permitAll() 39 | ) 40 | .logout((logout) -> logout 41 | .permitAll() 42 | ) 43 | .authenticationProvider(kerberosAuthenticationProvider()); 44 | return http.build(); 45 | } 46 | 47 | @Bean 48 | public KerberosAuthenticationProvider kerberosAuthenticationProvider() { 49 | KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider(); 50 | SunJaasKerberosClient client = new SunJaasKerberosClient(); 51 | client.setDebug(true); 52 | provider.setKerberosClient(client); 53 | provider.setUserDetailsService(dummyUserDetailsService()); 54 | return provider; 55 | } 56 | 57 | @Bean 58 | public DummyUserDetailsService dummyUserDetailsService() { 59 | return new DummyUserDetailsService(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/resources/templates/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Security Kerberos Example 6 | 7 | 8 |

Hello [[${#httpServletRequest.remoteUser}]]!

9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Spring Security Kerberos Example 5 | 6 | 7 |

Welcome!

8 |

Click here to see a greeting.

9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-client-auth/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Security Kerberos Example 6 | 7 | 8 |
9 | Invalid username and password. 10 |
11 |
12 | You have been logged out. 13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/sec-server-spnego-form-auth.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.security.kerberos.sample' 3 | alias libs.plugins.spring.boot 4 | alias libs.plugins.dependency.management 5 | } 6 | 7 | description = 'Security Server Spnego and Form Auth Sample' 8 | 9 | dependencies { 10 | management platform(project(":spring-security-kerberos-management")) 11 | implementation project(':spring-security-kerberos-core') 12 | implementation project(':spring-security-kerberos-web') 13 | implementation 'org.springframework.security:spring-security-config' 14 | implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' 15 | implementation 'org.springframework.boot:spring-boot-starter' 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 18 | testImplementation 'org.springframework:spring-test' 19 | testImplementation 'org.junit.jupiter:junit-jupiter' 20 | testImplementation 'org.mockito:mockito-junit-jupiter' 21 | testImplementation 'org.assertj:assertj-core' 22 | } 23 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/java/demo/app/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | 21 | @SpringBootApplication 22 | public class Application { 23 | 24 | public static void main(String[] args) throws Throwable { 25 | SpringApplication.run(Application.class, args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/java/demo/app/DummyUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package demo.app; 2 | 3 | import org.springframework.security.core.authority.AuthorityUtils; 4 | import org.springframework.security.core.userdetails.User; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | 9 | public class DummyUserDetailsService implements UserDetailsService { 10 | 11 | @Override 12 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 13 | return new User(username, "{noop}notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER")); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/java/demo/app/MvcConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 20 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 21 | 22 | @Configuration 23 | public class MvcConfig implements WebMvcConfigurer { 24 | 25 | @Override 26 | public void addViewControllers(ViewControllerRegistry registry) { 27 | registry.addViewController("/home").setViewName("home"); 28 | registry.addViewController("/").setViewName("home"); 29 | registry.addViewController("/hello").setViewName("hello"); 30 | registry.addViewController("/login").setViewName("login"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | app: 4 | service-principal: HTTP/cypher.localdomain@KERBOS.COM 5 | keytab-location: /tmp/tomcat.keytab 6 | logging: 7 | level: 8 | root: debug -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/resources/templates/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Security Kerberos Example 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Spring Security Kerberos Example 5 | 6 | 7 |

Welcome!

8 |

Click here to see a greeting.

9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Security Kerberos Example 6 | 7 | 8 |
9 | Invalid username and password. 10 |
11 |
12 | You have been logged out. 13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-spnego-form-auth/src/main/resources/xlogback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/sec-server-win-auth.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.security.kerberos.sample' 3 | alias libs.plugins.spring.boot 4 | alias libs.plugins.dependency.management 5 | } 6 | 7 | description = 'Security Server Win Auth Sample' 8 | 9 | dependencies { 10 | management platform(project(":spring-security-kerberos-management")) 11 | implementation project(':spring-security-kerberos-core') 12 | implementation project(':spring-security-kerberos-web') 13 | implementation project(':spring-security-kerberos-client') 14 | implementation 'org.springframework.security:spring-security-ldap' 15 | implementation 'org.springframework.security:spring-security-config' 16 | implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' 17 | implementation 'org.springframework.boot:spring-boot-starter' 18 | implementation 'org.springframework.boot:spring-boot-starter-web' 19 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 20 | testImplementation 'org.springframework:spring-test' 21 | testImplementation 'org.junit.jupiter:junit-jupiter' 22 | testImplementation 'org.mockito:mockito-junit-jupiter' 23 | testImplementation 'org.assertj:assertj-core' 24 | } 25 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/java/demo/app/ActiveDirectoryLdapAuthoritiesPopulator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.ldap.core.DirContextOperations; 19 | import org.springframework.ldap.core.DistinguishedName; 20 | import org.springframework.security.core.GrantedAuthority; 21 | import org.springframework.security.core.authority.AuthorityUtils; 22 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 23 | import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator; 24 | 25 | import java.util.ArrayList; 26 | import java.util.Collection; 27 | 28 | public class ActiveDirectoryLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator { 29 | 30 | @Override 31 | public Collection getGrantedAuthorities(DirContextOperations userData, String username) { 32 | String[] groups = userData.getStringAttributes("memberOf"); 33 | 34 | if (groups == null) { 35 | return AuthorityUtils.NO_AUTHORITIES; 36 | } 37 | 38 | ArrayList authorities = new ArrayList( 39 | groups.length); 40 | 41 | for (String group : groups) { 42 | authorities.add(new SimpleGrantedAuthority(new DistinguishedName(group) 43 | .removeLast().getValue())); 44 | } 45 | 46 | return authorities; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/java/demo/app/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | 21 | @SpringBootApplication 22 | public class Application { 23 | 24 | public static void main(String[] args) throws Throwable { 25 | SpringApplication.run(Application.class, args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/java/demo/app/MvcConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package demo.app; 17 | 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 20 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 21 | 22 | @Configuration 23 | public class MvcConfig implements WebMvcConfigurer { 24 | 25 | @Override 26 | public void addViewControllers(ViewControllerRegistry registry) { 27 | registry.addViewController("/home").setViewName("home"); 28 | registry.addViewController("/").setViewName("home"); 29 | registry.addViewController("/hello").setViewName("hello"); 30 | registry.addViewController("/login").setViewName("login"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | app: 4 | ad-domain: example.org 5 | ad-server: ldap://vagrantvm.example.org 6 | service-principal: HTTP/cypher.example.org@EXAMPLE.ORG 7 | keytab-location: /tmp/tomcat.keytab 8 | ldap-search-base: dc=example,dc=org 9 | ldap-search-filter: "(| (userPrincipalName={0}) (sAMAccountName={0}))" 10 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/resources/templates/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Security Kerberos Example 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Spring Security Kerberos Example 5 | 6 | 7 |

Welcome!

8 |

Click here to see a greeting.

9 | 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/sec-server-win-auth/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Spring Security Kerberos Example 6 | 7 | 8 |
9 | Invalid username and password. 10 |
11 |
12 | You have been logged out. 13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-security-kerberos-samples/src/main/java/demo/DummyUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import org.springframework.security.core.authority.AuthorityUtils; 4 | import org.springframework.security.core.userdetails.User; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | 9 | public class DummyUserDetailsService implements UserDetailsService { 10 | 11 | @Override 12 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 13 | return new User(username, "notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER")); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /spring-security-kerberos-test/spring-security-kerberos-test.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.spring-module' 3 | } 4 | 5 | description = 'Spring Security Kerberos Test' 6 | 7 | dependencies { 8 | management platform(project(":spring-security-kerberos-management")) 9 | api 'org.apache.kerby:kerb-simplekdc' 10 | api 'org.junit.jupiter:junit-jupiter' 11 | testImplementation 'org.springframework:spring-test' 12 | testImplementation 'org.mockito:mockito-junit-jupiter' 13 | testImplementation 'org.assertj:assertj-core' 14 | } 15 | -------------------------------------------------------------------------------- /spring-security-kerberos-test/src/main/java/org/springframework/security/kerberos/test/KerberosSecurityTestcase.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.springframework.security.kerberos.test; 19 | 20 | import java.io.File; 21 | import java.util.Properties; 22 | 23 | import org.junit.jupiter.api.AfterEach; 24 | import org.junit.jupiter.api.BeforeEach; 25 | 26 | /** 27 | * KerberosSecurityTestcase provides a base class for using MiniKdc with other 28 | * testcases. KerberosSecurityTestcase starts the MiniKdc (@Before) before 29 | * running tests, and stop the MiniKdc (@After) after the testcases, using 30 | * default settings (working dir and kdc configurations). 31 | *

32 | * Users can directly inherit this class and implement their own test functions 33 | * using the default settings, or override functions getTestDir() and 34 | * createMiniKdcConf() to provide new settings. 35 | * 36 | */ 37 | public class KerberosSecurityTestcase { 38 | private MiniKdc kdc; 39 | private File workDir; 40 | private Properties conf; 41 | 42 | @BeforeEach 43 | public void startMiniKdc() throws Exception { 44 | createTestDir(); 45 | createMiniKdcConf(); 46 | 47 | kdc = new MiniKdc(conf, workDir); 48 | kdc.start(); 49 | } 50 | 51 | /** 52 | * Create a working directory, it should be the build directory. Under 53 | * this directory an ApacheDS working directory will be created, this 54 | * directory will be deleted when the MiniKdc stops. 55 | */ 56 | public void createTestDir() { 57 | workDir = new File(System.getProperty("test.dir", "target")); 58 | } 59 | 60 | /** 61 | * Create a Kdc configuration 62 | */ 63 | public void createMiniKdcConf() { 64 | conf = MiniKdc.createConf(); 65 | } 66 | 67 | @AfterEach 68 | public void stopMiniKdc() { 69 | if (kdc != null) { 70 | kdc.stop(); 71 | } 72 | } 73 | 74 | public MiniKdc getKdc() { 75 | return kdc; 76 | } 77 | 78 | public File getWorkDir() { 79 | return workDir; 80 | } 81 | 82 | public Properties getConf() { 83 | return conf; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /spring-security-kerberos-test/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=INFO, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2} - %m%n 6 | 7 | log4j.category.org.springframework.boot=INFO 8 | xlog4j.category.org.apache.http.wire=TRACE 9 | xlog4j.category.org.apache.http.headers=TRACE 10 | 11 | -------------------------------------------------------------------------------- /spring-security-kerberos-test/src/test/resources/minikdc-krb5.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | [libdefaults] 19 | default_realm = {0} 20 | udp_preference_limit = 1 21 | 22 | [realms] 23 | {0} = '{' 24 | kdc = {1}:{2} 25 | '}' -------------------------------------------------------------------------------- /spring-security-kerberos-test/src/test/resources/minikdc.ldiff: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | dn: ou=users,dc=${0},dc=${1} 19 | objectClass: organizationalUnit 20 | objectClass: top 21 | ou: users 22 | 23 | dn: uid=krbtgt,ou=users,dc=${0},dc=${1} 24 | objectClass: top 25 | objectClass: person 26 | objectClass: inetOrgPerson 27 | objectClass: krb5principal 28 | objectClass: krb5kdcentry 29 | cn: KDC Service 30 | sn: Service 31 | uid: krbtgt 32 | userPassword: secret 33 | krb5PrincipalName: krbtgt/${2}.${3}@${2}.${3} 34 | krb5KeyVersionNumber: 0 35 | 36 | dn: uid=ldap,ou=users,dc=${0},dc=${1} 37 | objectClass: top 38 | objectClass: person 39 | objectClass: inetOrgPerson 40 | objectClass: krb5principal 41 | objectClass: krb5kdcentry 42 | cn: LDAP 43 | sn: Service 44 | uid: ldap 45 | userPassword: secret 46 | krb5PrincipalName: ldap/${4}@${2}.${3} 47 | krb5KeyVersionNumber: 0 -------------------------------------------------------------------------------- /spring-security-kerberos-web/spring-security-kerberos-web.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'io.spring.convention.spring-module' 3 | } 4 | 5 | description = 'Spring Security Kerberos Web' 6 | 7 | dependencies { 8 | management platform(project(":spring-security-kerberos-management")) 9 | implementation project(':spring-security-kerberos-core') 10 | api('org.springframework.security:spring-security-web') 11 | api(libs.servlet.api) 12 | testImplementation 'org.springframework:spring-test' 13 | testImplementation 'org.springframework.security:spring-security-config' 14 | testImplementation 'org.junit.jupiter:junit-jupiter' 15 | testImplementation 'org.mockito:mockito-junit-jupiter' 16 | testImplementation libs.assertj.core 17 | } 18 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/main/java/org/springframework/security/kerberos/web/authentication/ResponseHeaderSettingKerberosAuthenticationSuccessHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.web.authentication; 17 | 18 | import java.io.IOException; 19 | 20 | import jakarta.servlet.ServletException; 21 | import jakarta.servlet.http.HttpServletRequest; 22 | import jakarta.servlet.http.HttpServletResponse; 23 | 24 | import org.springframework.security.core.Authentication; 25 | import org.springframework.security.kerberos.authentication.KerberosServiceRequestToken; 26 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; 27 | 28 | /** 29 | * Adds a WWW-Authenticate (or other) header to the response following 30 | * successful authentication. 31 | * 32 | * @author Jeremy Stone 33 | */ 34 | public class ResponseHeaderSettingKerberosAuthenticationSuccessHandler implements AuthenticationSuccessHandler { 35 | 36 | private static final String NEGOTIATE_PREFIX = "Negotiate "; 37 | 38 | private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; 39 | 40 | private String headerName = WWW_AUTHENTICATE; 41 | 42 | private String headerPrefix = NEGOTIATE_PREFIX; 43 | 44 | /** 45 | * Sets the name of the header to set. By default this is 'WWW-Authenticate'. 46 | * 47 | * @param headerName the www authenticate header name 48 | */ 49 | public void setHeaderName(String headerName) { 50 | this.headerName = headerName; 51 | } 52 | 53 | /** 54 | * Sets the value of the prefix for the encoded response token value. By 55 | * default this is 'Negotiate '. 56 | * 57 | * @param headerPrefix the negotiate prefix 58 | */ 59 | public void setHeaderPrefix(String headerPrefix) { 60 | this.headerPrefix = headerPrefix; 61 | } 62 | 63 | @Override 64 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 65 | Authentication authentication) throws IOException, ServletException { 66 | KerberosServiceRequestToken auth = (KerberosServiceRequestToken) authentication; 67 | if (auth.hasResponseToken()) { 68 | response.addHeader(headerName, headerPrefix + auth.getEncodedResponseToken()); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/docs/AuthProviderConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.docs; 17 | 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; 21 | import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; 22 | 23 | //tag::snippetA[] 24 | @Configuration 25 | public class AuthProviderConfig { 26 | 27 | @Bean 28 | public KerberosAuthenticationProvider kerberosAuthenticationProvider() { 29 | KerberosAuthenticationProvider provider = 30 | new KerberosAuthenticationProvider(); 31 | SunJaasKerberosClient client = new SunJaasKerberosClient(); 32 | client.setDebug(true); 33 | provider.setKerberosClient(client); 34 | provider.setUserDetailsService(dummyUserDetailsService()); 35 | return provider; 36 | } 37 | 38 | @Bean 39 | public DummyUserDetailsService dummyUserDetailsService() { 40 | return new DummyUserDetailsService(); 41 | } 42 | 43 | } 44 | //end::snippetA[] 45 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/docs/AuthProviderConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 5 | * file except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under 10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | package org.springframework.security.kerberos.docs; 15 | 16 | import org.junit.jupiter.api.Test; 17 | import org.junit.jupiter.api.extension.ExtendWith; 18 | 19 | import org.springframework.test.context.ContextConfiguration; 20 | import org.springframework.test.context.junit.jupiter.SpringExtension; 21 | 22 | @ExtendWith(SpringExtension.class) 23 | @ContextConfiguration(locations= {"AuthProviderConfig.xml"}) 24 | public class AuthProviderConfigTest { 25 | 26 | @Test 27 | public void configLoads() {} 28 | } 29 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/docs/DummyUserDetailsService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.docs; 17 | 18 | import org.springframework.security.core.authority.AuthorityUtils; 19 | import org.springframework.security.core.userdetails.User; 20 | import org.springframework.security.core.userdetails.UserDetails; 21 | import org.springframework.security.core.userdetails.UserDetailsService; 22 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 23 | 24 | //tag::snippetA[] 25 | public class DummyUserDetailsService implements UserDetailsService { 26 | 27 | @Override 28 | public UserDetails loadUserByUsername(String username) 29 | throws UsernameNotFoundException { 30 | return new User(username, "notUsed", true, true, true, true, 31 | AuthorityUtils.createAuthorityList("ROLE_USER")); 32 | } 33 | 34 | } 35 | //end::snippetA[] 36 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/docs/SpnegoConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2023 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.security.kerberos.docs; 17 | 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.core.io.FileSystemResource; 21 | import org.springframework.security.authentication.AuthenticationManager; 22 | import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; 23 | import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider; 24 | import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; 25 | import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator; 26 | import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter; 27 | import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint; 28 | 29 | //tag::snippetA[] 30 | @Configuration 31 | public class SpnegoConfig { 32 | 33 | @Bean 34 | public KerberosAuthenticationProvider kerberosAuthenticationProvider() { 35 | KerberosAuthenticationProvider provider = 36 | new KerberosAuthenticationProvider(); 37 | SunJaasKerberosClient client = new SunJaasKerberosClient(); 38 | client.setDebug(true); 39 | provider.setKerberosClient(client); 40 | provider.setUserDetailsService(dummyUserDetailsService()); 41 | return provider; 42 | } 43 | 44 | @Bean 45 | public SpnegoEntryPoint spnegoEntryPoint() { 46 | return new SpnegoEntryPoint("/login"); 47 | } 48 | 49 | @Bean 50 | public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter( 51 | AuthenticationManager authenticationManager) { 52 | SpnegoAuthenticationProcessingFilter filter = 53 | new SpnegoAuthenticationProcessingFilter(); 54 | filter.setAuthenticationManager(authenticationManager); 55 | return filter; 56 | } 57 | 58 | @Bean 59 | public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() { 60 | KerberosServiceAuthenticationProvider provider = 61 | new KerberosServiceAuthenticationProvider(); 62 | provider.setTicketValidator(sunJaasKerberosTicketValidator()); 63 | provider.setUserDetailsService(dummyUserDetailsService()); 64 | return provider; 65 | } 66 | 67 | @Bean 68 | public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { 69 | SunJaasKerberosTicketValidator ticketValidator = 70 | new SunJaasKerberosTicketValidator(); 71 | ticketValidator.setServicePrincipal("HTTP/servicehost.example.org@EXAMPLE.ORG"); 72 | ticketValidator.setKeyTabLocation(new FileSystemResource("/tmp/service.keytab")); 73 | ticketValidator.setDebug(true); 74 | return ticketValidator; 75 | } 76 | 77 | @Bean 78 | public DummyUserDetailsService dummyUserDetailsService() { 79 | return new DummyUserDetailsService(); 80 | } 81 | 82 | } 83 | //end::snippetA[] 84 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/resources/org/springframework/security/kerberos/docs/AuthProviderConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/resources/org/springframework/security/kerberos/docs/SpnegoConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 43 | 44 | 45 | 46 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /spring-security-kerberos-web/src/test/resources/org/springframework/security/kerberos/docs/appproperties.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------