diff --git a/.codecov.yml b/.codecov.yml
deleted file mode 100644
index 4a94c8f..0000000
--- a/.codecov.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-coverage:
- precision: 2
- round: down
- range: "70...100"
- status:
- patch:
- default:
- threshold: 2%
- if_no_uploads: error
- changes: true
- project:
- default:
- target: auto
- threshold: 2%
- if_no_uploads: error
-comment: false
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 60f116c..63af35e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @auth0/dx-sdks-engineer
+* @OpenGov/platform-access-control
diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml
deleted file mode 100644
index 19ed08d..0000000
--- a/.github/ISSUE_TEMPLATE/Bug Report.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-name: 🐞 Report a bug
-description: Have you found a bug or issue? Create a bug report for this library
-labels: ["bug"]
-
-body:
- - type: markdown
- attributes:
- value: |
- **Please do not report security vulnerabilities here**. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues.
-
- - type: checkboxes
- id: checklist
- attributes:
- label: Checklist
- options:
- - label: The issue can be reproduced in the [mvc-auth-commons sample app](https://github.com/auth0-samples/auth0-servlet-sample/tree/master/01-Login) (or N/A).
- required: true
- - label: I have looked into the [Readme](https://github.com/auth0/auth0-java-mvc-common#readme) and the [Examples](https://github.com/auth0/auth0-java-mvc-common/blob/master/EXAMPLES.md), and have not found a suitable solution or answer.
- required: true
- - label: I have looked into the [API documentation](https://javadoc.io/doc/com.auth0/mvc-auth-commons/latest/index.html) and have not found a suitable solution or answer.
- required: true
- - label: I have searched the [issues](https://github.com/auth0/auth0-java-mvc-common/issues) and have not found a suitable solution or answer.
- required: true
- - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer.
- required: true
- - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).
- required: true
-
- - type: textarea
- id: description
- attributes:
- label: Description
- description: Provide a clear and concise description of the issue, including what you expected to happen.
- validations:
- required: true
-
- - type: textarea
- id: reproduction
- attributes:
- label: Reproduction
- description: Detail the steps taken to reproduce this error, and whether this issue can be reproduced consistently or if it is intermittent.
- placeholder: |
- 1. Step 1...
- 2. Step 2...
- 3. ...
- validations:
- required: true
-
- - type: textarea
- id: additional-context
- attributes:
- label: Additional context
- description: Other libraries that might be involved, or any other relevant information you think would be useful.
- validations:
- required: false
-
- - type: input
- id: environment-version
- attributes:
- label: mvc-auth-commons version
- validations:
- required: true
-
- - type: input
- id: environment-java-version
- attributes:
- label: Java version
- validations:
- required: true
diff --git a/.github/ISSUE_TEMPLATE/Feature Request.yml b/.github/ISSUE_TEMPLATE/Feature Request.yml
deleted file mode 100644
index 1844d7a..0000000
--- a/.github/ISSUE_TEMPLATE/Feature Request.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: 🧩 Feature request
-description: Suggest an idea or a feature for this library
-labels: ["feature request"]
-
-body:
- - type: checkboxes
- id: checklist
- attributes:
- label: Checklist
- options:
- - label: I have looked into the [Readme](https://github.com/auth0/auth0-java-mvc-common#readme) and the [Examples](https://github.com/auth0/auth0-java-mvc-common/blob/master/EXAMPLES.md), and have not found a suitable solution or answer.
- required: true
- - label: I have looked into the [API documentation](https://javadoc.io/doc/com.auth0/mvc-auth-commons/latest/index.html) and have not found a suitable solution or answer.
- required: true
- - label: I have searched the [issues](https://github.com/auth0/auth0-java-mvc-common/issues) and have not found a suitable solution or answer.
- required: true
- - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer.
- required: true
- - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).
- required: true
-
- - type: textarea
- id: description
- attributes:
- label: Describe the problem you'd like to have solved
- description: A clear and concise description of what the problem is.
- placeholder: I'm always frustrated when...
- validations:
- required: true
-
- - type: textarea
- id: ideal-solution
- attributes:
- label: Describe the ideal solution
- description: A clear and concise description of what you want to happen.
- validations:
- required: true
-
- - type: textarea
- id: alternatives-and-workarounds
- attributes:
- label: Alternatives and current workarounds
- description: A clear and concise description of any alternatives you've considered or any workarounds that are currently in place.
- validations:
- required: false
-
- - type: textarea
- id: additional-context
- attributes:
- label: Additional context
- description: Add any other context or screenshots about the feature request here.
- validations:
- required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index 65c99a9..0000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-blank_issues_enabled: false
-contact_links:
- - name: Auth0 Community
- url: https://community.auth0.com
- about: Discuss this SDK in the Auth0 Community forums
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 8675fc7..0000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,31 +0,0 @@
-### Changes
-
-Please describe both what is changing and why this is important. Include:
-
-- Endpoints added, deleted, deprecated, or changed
-- Classes and methods added, deleted, deprecated, or changed
-- Screenshots of new or changed UI, if applicable
-- A summary of usage if this is a new feature or change to a public API (this should also be added to relevant documentation once released)
-- Any alternative designs or approaches considered
-
-### References
-
-Please include relevant links supporting this change such as a:
-
-- support ticket
-- community post
-- StackOverflow post
-- support forum thread
-
-### Testing
-
-Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors.
-
-- [ ] This change adds test coverage
-- [ ] This change has been tested on the latest version of Java or why not
-
-### Checklist
-
-- [ ] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
-- [ ] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
-- [ ] All existing and new tests complete without errors
diff --git a/.github/actions/get-prerelease/action.yml b/.github/actions/get-prerelease/action.yml
deleted file mode 100644
index ce7acdc..0000000
--- a/.github/actions/get-prerelease/action.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Return a boolean indicating if the version contains prerelease identifiers
-
-#
-# Returns a simple true/false boolean indicating whether the version indicates it's a prerelease or not.
-#
-# TODO: Remove once the common repo is public.
-#
-
-inputs:
- version:
- required: true
-
-outputs:
- prerelease:
- value: ${{ steps.get_prerelease.outputs.PRERELEASE }}
-
-runs:
- using: composite
-
- steps:
- - id: get_prerelease
- shell: bash
- run: |
- if [[ "${VERSION}" == *"beta"* || "${VERSION}" == *"alpha"* ]]; then
- echo "PRERELEASE=true" >> $GITHUB_OUTPUT
- else
- echo "PRERELEASE=false" >> $GITHUB_OUTPUT
- fi
- env:
- VERSION: ${{ inputs.version }}
diff --git a/.github/actions/get-release-notes/action.yml b/.github/actions/get-release-notes/action.yml
deleted file mode 100644
index 287d206..0000000
--- a/.github/actions/get-release-notes/action.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: Return the release notes extracted from the body of the PR associated with the release.
-
-#
-# Returns the release notes from the content of a pull request linked to a release branch. It expects the branch name to be in the format release/vX.Y.Z, release/X.Y.Z, release/vX.Y.Z-beta.N. etc.
-#
-# TODO: Remove once the common repo is public.
-#
-inputs:
- version:
- required: true
- repo_name:
- required: false
- repo_owner:
- required: true
- token:
- required: true
-
-outputs:
- release-notes:
- value: ${{ steps.get_release_notes.outputs.RELEASE_NOTES }}
-
-runs:
- using: composite
-
- steps:
- - uses: actions/github-script@v7
- id: get_release_notes
- with:
- result-encoding: string
- script: |
- const { data: pulls } = await github.rest.pulls.list({
- owner: process.env.REPO_OWNER,
- repo: process.env.REPO_NAME,
- state: 'all',
- head: `${process.env.REPO_OWNER}:release/${process.env.VERSION}`,
- });
- core.setOutput('RELEASE_NOTES', pulls[0].body);
- env:
- GITHUB_TOKEN: ${{ inputs.token }}
- REPO_OWNER: ${{ inputs.repo_owner }}
- REPO_NAME: ${{ inputs.repo_name }}
- VERSION: ${{ inputs.version }}
diff --git a/.github/actions/get-version/action.yml b/.github/actions/get-version/action.yml
deleted file mode 100644
index 9440ec9..0000000
--- a/.github/actions/get-version/action.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Return the version extracted from the branch name
-
-#
-# Returns the version from the .version file.
-#
-# TODO: Remove once the common repo is public.
-#
-
-outputs:
- version:
- value: ${{ steps.get_version.outputs.VERSION }}
-
-runs:
- using: composite
-
- steps:
- - id: get_version
- shell: bash
- run: |
- VERSION=$(head -1 .version)
- echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
diff --git a/.github/actions/maven-publish/action.yml b/.github/actions/maven-publish/action.yml
deleted file mode 100644
index ee47706..0000000
--- a/.github/actions/maven-publish/action.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-name: Publish release to Java
-
-inputs:
- ossr-username:
- required: true
- ossr-password:
- required: true
- signing-key:
- required: true
- signing-password:
- required: true
- java-version:
- required: true
- is-android:
- required: true
- version:
- required: true
-
-runs:
- using: composite
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Setup Java
- shell: bash
- run: |
- curl -s "https://get.sdkman.io" | bash
- source "/home/runner/.sdkman/bin/sdkman-init.sh"
- sdk list java
- sdk install java ${{ inputs.java-version }} && sdk default java ${{ inputs.java-version }}
-
- - uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4 # pin@1.1.0
-
- - name: Publish Java
- shell: bash
- if: inputs.is-android == 'false'
- run: ./gradlew clean assemble sign publishMavenJavaPublicationToMavenRepository -PisSnapshot=false -Pversion="${{ inputs.version }}" -PossrhUsername="${{ inputs.ossr-username }}" -PossrhPassword="${{ inputs.ossr-password }}" -PsigningKey="${{ inputs.signing-key }}" -PsigningPassword="${{ inputs.signing-password }}"
-
- - name: Publish Android
- shell: bash
- if: inputs.is-android == 'true'
- run: ./gradlew clean assemble sign publishAndroidLibraryPublicationToMavenRepository -PisSnapshot=false -Pversion="${{ inputs.version }}" -PossrhUsername="${{ inputs.ossr-username }}" -PossrhPassword="${{ inputs.ossr-password }}" -PsigningKey="${{ inputs.signing-key }}" -PsigningPassword="${{ inputs.signing-password }}"
diff --git a/.github/actions/release-create/action.yml b/.github/actions/release-create/action.yml
deleted file mode 100644
index 6a2bf80..0000000
--- a/.github/actions/release-create/action.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-name: Create a GitHub release
-
-#
-# Creates a GitHub release with the given version.
-#
-# TODO: Remove once the common repo is public.
-#
-
-inputs:
- token:
- required: true
- files:
- required: false
- name:
- required: true
- body:
- required: true
- tag:
- required: true
- commit:
- required: true
- draft:
- default: false
- required: false
- prerelease:
- default: false
- required: false
- fail_on_unmatched_files:
- default: true
- required: false
-
-runs:
- using: composite
-
- steps:
- - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
- with:
- body: ${{ inputs.body }}
- name: ${{ inputs.name }}
- tag_name: ${{ inputs.tag }}
- target_commitish: ${{ inputs.commit }}
- draft: ${{ inputs.draft }}
- prerelease: ${{ inputs.prerelease }}
- fail_on_unmatched_files: ${{ inputs.fail_on_unmatched_files }}
- files: ${{ inputs.files }}
- env:
- GITHUB_TOKEN: ${{ inputs.token }}
diff --git a/.github/actions/tag-exists/action.yml b/.github/actions/tag-exists/action.yml
deleted file mode 100644
index b5fbdb7..0000000
--- a/.github/actions/tag-exists/action.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: Return a boolean indicating if a tag already exists for the repository
-
-#
-# Returns a simple true/false boolean indicating whether the tag exists or not.
-#
-# TODO: Remove once the common repo is public.
-#
-
-inputs:
- token:
- required: true
- tag:
- required: true
-
-outputs:
- exists:
- description: 'Whether the tag exists or not'
- value: ${{ steps.tag-exists.outputs.EXISTS }}
-
-runs:
- using: composite
-
- steps:
- - id: tag-exists
- shell: bash
- run: |
- GET_API_URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/git/ref/tags/${TAG_NAME}"
- http_status_code=$(curl -LI $GET_API_URL -o /dev/null -w '%{http_code}\n' -s -H "Authorization: token ${GITHUB_TOKEN}")
- if [ "$http_status_code" -ne "404" ] ; then
- echo "EXISTS=true" >> $GITHUB_OUTPUT
- else
- echo "EXISTS=false" >> $GITHUB_OUTPUT
- fi
- env:
- TAG_NAME: ${{ inputs.tag }}
- GITHUB_TOKEN: ${{ inputs.token }}
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index b2e13fc..0000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# Configuration for probot-stale - https://github.com/probot/stale
-
-# Number of days of inactivity before an Issue or Pull Request becomes stale
-daysUntilStale: 90
-
-# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
-daysUntilClose: 7
-
-# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
-exemptLabels: []
-
-# Set to true to ignore issues with an assignee (defaults to false)
-exemptAssignees: true
-
-# Label to use when marking as stale
-staleLabel: closed:stale
-
-# Comment to post when marking as stale. Set to `false` to disable
-markComment: >
- This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇♂️
\ No newline at end of file
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
deleted file mode 100644
index 25155e8..0000000
--- a/.github/workflows/build-and-test.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-name: auth0/auth0-java-mvc-common/build-and-test
-
-on:
- pull_request:
- merge_group:
- push:
- branches: ["master", "main", "v1"]
-
-jobs:
- gradle:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-java@v3
- with:
- distribution: temurin
- java-version: 8
- - uses: gradle/gradle-build-action@a4cf152f482c7ca97ef56ead29bf08bcd953284c
- with:
- arguments: assemble apiDiff check jacocoTestReport --continue --console=plain
- - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
- with:
- flags: unittests
- - uses: actions/upload-artifact@v3
- with:
- name: Reports
- path: lib/build/reports
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..43bf525
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,37 @@
+name: ci
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - '*'
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ INTERNAL_MAVEN_USER: ${{ secrets.JF_ARTIFACTORY_USER_INTEGRATION }}
+ INTERNAL_MAVEN_PASS: ${{ secrets.JF_ARTIFACTORY_API_KEY_INTEGRATION }}
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v3
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ - name: Cache Gradle
+ uses: actions/cache@v3
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Run Linting and Tests
+ run: ./gradlew check
+ - name: Run SonarQube
+ run: ./gradlew sonarqube -Dsonar.host.url='${{ secrets.SONAR_EXTERNAL_URL }}' -Dsonar.login=${{ secrets.SONAR_API_TOKEN }}
+ - name: Kill Gradle Daemons for caching
+ run: ./gradlew --stop
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
deleted file mode 100644
index 8e62d8d..0000000
--- a/.github/workflows/codeql.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: "CodeQL"
-
-on:
- push:
- branches: [ "master", "2.0.0-dev" ]
- pull_request:
- branches: [ "master" ]
- schedule:
- - cron: "30 19 * * 6"
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: read
- security-events: write
-
- strategy:
- fail-fast: false
- matrix:
- language: [ java ]
-
- steps:
- - name: Checkout
- uses: actions/checkout@v3
-
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v2
- with:
- languages: ${{ matrix.language }}
- queries: +security-and-quality
-
- - name: Autobuild
- uses: github/codeql-action/autobuild@v2
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
- with:
- category: "/language:${{ matrix.language }}"
diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml
deleted file mode 100644
index f91f71d..0000000
--- a/.github/workflows/dependabot.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-version: 2
-updates:
- - package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "daily"
-
- - package-ecosystem: "gradle"
- directory: "/"
- schedule:
- interval: "daily"
- ignore:
- - dependency-name: "*"
- update-types: ["version-update:semver-major"]
\ No newline at end of file
diff --git a/.github/workflows/java-release.yml b/.github/workflows/java-release.yml
deleted file mode 100644
index 3f81eb1..0000000
--- a/.github/workflows/java-release.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-name: Create Java and GitHub Release
-
-on:
- workflow_call:
- inputs:
- java-version:
- required: true
- type: string
- is-android:
- required: true
- type: string
- secrets:
- ossr-username:
- required: true
- ossr-password:
- required: true
- signing-key:
- required: true
- signing-password:
- required: true
- github-token:
- required: true
-
-### TODO: Replace instances of './.github/actions/' w/ `auth0/dx-sdk-actions/` and append `@latest` after the common `dx-sdk-actions` repo is made public.
-### TODO: Also remove `get-prerelease`, `get-version`, `release-create`, `tag-create` and `tag-exists` actions from this repo's .github/actions folder once the repo is public.
-
-jobs:
- release:
- if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged && startsWith(github.event.pull_request.head.ref, 'release/'))
- runs-on: ubuntu-latest
- environment: release
-
- steps:
- # Checkout the code
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- # Get the version from the branch name
- - id: get_version
- uses: ./.github/actions/get-version
-
- # Get the prerelease flag from the branch name
- - id: get_prerelease
- uses: ./.github/actions/get-prerelease
- with:
- version: ${{ steps.get_version.outputs.version }}
-
- # Get the release notes
- - id: get_release_notes
- uses: ./.github/actions/get-release-notes
- with:
- token: ${{ secrets.github-token }}
- version: ${{ steps.get_version.outputs.version }}
- repo_owner: ${{ github.repository_owner }}
- repo_name: ${{ github.event.repository.name }}
-
- # Check if the tag already exists
- - id: tag_exists
- uses: ./.github/actions/tag-exists
- with:
- tag: ${{ steps.get_version.outputs.version }}
- token: ${{ secrets.github-token }}
-
- # If the tag already exists, exit with an error
- - if: steps.tag_exists.outputs.exists == 'true'
- run: exit 1
-
- # Publish the release to Maven
- - uses: ./.github/actions/maven-publish
- with:
- java-version: ${{ inputs.java-version }}
- is-android: ${{ inputs.is-android }}
- version: ${{ steps.get_version.outputs.version }}
- ossr-username: ${{ secrets.ossr-username }}
- ossr-password: ${{ secrets.ossr-password }}
- signing-key: ${{ secrets.signing-key }}
- signing-password: ${{ secrets.signing-password }}
-
- # Create a release for the tag
- - uses: ./.github/actions/release-create
- with:
- token: ${{ secrets.github-token }}
- name: ${{ steps.get_version.outputs.version }}
- body: ${{ steps.get_release_notes.outputs.release-notes }}
- tag: ${{ steps.get_version.outputs.version }}
- commit: ${{ github.sha }}
- prerelease: ${{ steps.get_prerelease.outputs.prerelease }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 63482cc..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-name: Create GitHub Release
-
-on:
- pull_request:
- types:
- - closed
- workflow_dispatch:
-
-permissions:
- contents: write
-
-### TODO: Replace instances of './.github/workflows/' w/ `auth0/dx-sdk-actions/workflows/` and append `@latest` after the common `dx-sdk-actions` repo is made public.
-### TODO: Also remove `get-prerelease`, `get-release-notes`, `get-version`, `maven-publish`, `release-create`, and `tag-exists` actions from this repo's .github/actions folder once the repo is public.
-### TODO: Also remove `java-release` workflow from this repo's .github/workflows folder once the repo is public.
-
-jobs:
- release:
- uses: ./.github/workflows/java-release.yml
- with:
- java-version: 8.0.382-tem
- is-android: false
- secrets:
- ossr-username: ${{ secrets.OSSR_USERNAME }}
- ossr-password: ${{ secrets.OSSR_PASSWORD }}
- signing-key: ${{ secrets.SIGNING_KEY }}
- signing-password: ${{ secrets.SIGNING_PASSWORD }}
- github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml
deleted file mode 100644
index e0227e3..0000000
--- a/.github/workflows/semgrep.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Semgrep
-
-on:
- pull_request: {}
-
- push:
- branches: ["master", "main"]
-
- schedule:
- - cron: '30 0 1,15 * *'
-
-jobs:
- semgrep:
- name: Scan
- runs-on: ubuntu-latest
- container:
- image: returntocorp/semgrep
- if: (github.actor != 'dependabot[bot]')
- steps:
- - uses: actions/checkout@v3
-
- - run: semgrep ci
- env:
- SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.shiprc b/.shiprc
deleted file mode 100644
index edfe142..0000000
--- a/.shiprc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "files": {
- "README.md": [],
- ".version": [],
- "build.gradle": ["version = \"{MAJOR}.{MINOR}.{PATCH}\""]
- },
- "prefixVersion": false
-}
\ No newline at end of file
diff --git a/.version b/.version
deleted file mode 100644
index 169f19b..0000000
--- a/.version
+++ /dev/null
@@ -1 +0,0 @@
-1.11.0
\ No newline at end of file
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 975df40..e318aef 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -96,11 +96,3 @@ AuthenticationController authController = AuthenticationController.newBuilder("Y
.build();
```
-## HTTP logging
-
-Once you have created the instance of the `AuthenticationController`, you can enable HTTP logging for all Requests and Responses to debug a specific endpoint.
-**This will log everything including sensitive information** - do not use it in a production environment.
-
-```java
-authController.setLoggingEnabled(true);
-```
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index f7c61ba..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Auth0, Inc. (http://auth0.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index 1ee3030..a12929a 100644
--- a/README.md
+++ b/README.md
@@ -1,161 +1 @@
-
-
-
-[](https://codecov.io/github/auth0/auth0-java-mvc-common)
-[](https://doge.mit-license.org/)
-[](https://mvnrepository.com/artifact/com.auth0/mvc-auth-commons)
-[](https://javadoc.io/doc/com.auth0/mvc-auth-commons)
-
-> **Note**
-> As part of our ongoing commitment to best security practices, we have rotated the signing keys used to sign previous releases of this SDK. As a result, new patch builds have been released using the new signing key. Please upgrade at your earliest convenience.
->
-> While this change won't affect most developers, if you have implemented a dependency signature validation step in your build process, you may notice a warning that past releases can't be verified. This is expected, and a result of the key rotation process. Updating to the latest version will resolve this for you.
-
-:books: [Documentation](#documentation) - :rocket: [Getting Started](#getting-started) - :computer: [API Reference](#api-reference) :speech_balloon: [Feedback](#feedback)
-
-## Documentation
-
-- [Quickstart](https://auth0.com/docs/quickstart/webapp/java) - our interactive guide for quickly adding login, logout and user information to a Java Servlet application using Auth0.
-- [Sample App](https://github.com/auth0-samples/auth0-servlet-sample/tree/master/01-Login) - a sample Java Servlet application integrated with Auth0.
-- [Examples](./EXAMPLES.md) - code samples for common scenarios.
-- [Docs site](https://www.auth0.com/docs) - explore our docs site and learn more about Auth0.
-
-## Getting Started
-
-### Requirements
-
-Java 8 or above and `javax.servlet` version 3.
-
-> If you are using Spring, we recommend leveraging Spring's OIDC and OAuth2 support, as demonstrated by the [Spring Boot Quickstart](https://auth0.com/docs/quickstart/webapp/java-spring-boot).
-
-### Installation
-
-Add the dependency via Maven:
-
-```xml
-
- com.auth0
- mvc-auth-commons
- 1.11.0
-
-```
-
-or Gradle:
-
-```gradle
-implementation 'com.auth0:mvc-auth-commons:1.11.0'
-```
-
-### Configure Auth0
-
-Create a **Regular Web Application** in the [Auth0 Dashboard](https://manage.auth0.com/#/applications). Verify that the "Token Endpoint Authentication Method" is set to `POST`.
-
-Next, configure the callback and logout URLs for your application under the "Application URIs" section of the "Settings" page:
-
-- **Allowed Callback URLs**: The URL of your application where Auth0 will redirect to during authentication, e.g., `http://localhost:3000/callback`.
-- **Allowed Logout URLs**: The URL of your application where Auth0 will redirect to after user logout, e.g., `http://localhost:3000/login`.
-
-Note the **Domain**, **Client ID**, and **Client Secret**. These values will be used later.
-
-### Add login to your application
-
-Create a new `AuthenticationController` using your Auth0 domain, and Auth0 application client ID and secret.
-Configure the builder with a `JwkProvider` for your Auth0 domain.
-
-```java
-public class AuthenticationControllerProvider {
- private String domain = "YOUR-AUTH0-DOMAIN";
- private String clientId = "YOUR-CLIENT-ID";
- private String clientSecret = "YOUR-CLIENT-SECRET";
-
- private AuthenticationController authenticationController;
-
- static {
- JwkProvider jwkProvider = new JwkProviderBuilder("YOUR-AUTH0-DOMAIN").build();
- authenticationController = AuthenticationController.newBuilder(domain, clientId, clientSecret)
- .withJwkProvider(jwkProvider)
- .build();
- }
-
- public getInstance() {
- return authenticationController;
- }
-}
-```
-
-> Note: The `AuthenticationController.Builder` is not to be reused, and an `IllegalStateException` will be thrown if `build()` is called more than once.
-
-Redirect users to the Auth0 login page using the `AuthenticationController`:
-
-```java
-@WebServlet(urlPatterns = {"/login"})
-public class LoginServlet extends HttpServlet {
-
- @Override
- protected void doGet(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
- // Where your application will handle the authoriztion callback
- String redirectUrl = "http://localhost:3000/callback";
-
- String authorizeUrl = AuthenticationControllerProvider
- .getInstance()
- .buildAuthorizeUrl(req, res, redirectUrl)
- .build();
- res.sendRedirect(authorizeUrl);
- }
-}
-```
-
-Finally, complete the authentication and obtain the tokens by calling `handle()` on the `AuthenticationController`.
-
-```java
-@WebServlet(urlPatterns = {"/callback"})
-public class CallbackServlet extends HttpServlet {
-
- @Override
- public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
- try {
- // authentication complete; the tokens can be stored as needed
- Tokens tokens = AuthenticationControllerProvider
- .getInstance()
- .handle(req, res);
- res.sendRedirect("URL-AFTER-AUTHENTICATED");
- } catch (IdentityVerificationException e) {
- // handle authentication error
- }
- }
-}
-```
-
-That's it! You have authenticated the user using Auth0.
-
-## API Reference
-
-- [JavaDocs](https://javadoc.io/doc/com.auth0/mvc-auth-commons)
-
-## Feedback
-
-### Contributing
-
-We appreciate feedback and contribution to this repo! Before you get started, please see the following:
-
-- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
-- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
-
-### Raise an issue
-To provide feedback or report a bug, [please raise an issue on our issue tracker](https://github.com/auth0/auth0-java-mvc-common/issues).
-
-### Vulnerability Reporting
-Please do not report security vulnerabilities on the public Github issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues.
-
----
-
-
-
-
-
-
-
-
-
Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?
-
-This project is licensed under the MIT license. See the LICENSE file for more info.
Important: When using this API, you must also use {@link AuthenticationController#buildAuthorizeUrl(HttpServletRequest, HttpServletResponse, String)}
+ *
Important: When using this API, you must also use the {@link AuthenticationController#buildAuthorizeUrl(ServerWebExchange, String)}
* when building the {@link AuthorizeUrl} that the user will be redirected to to login. Failure to do so may result
* in a broken login experience for the user.
*
- * @param request the received request to process.
- * @param response the received response to process.
- * @return the Tokens obtained after the user authentication.
- * @throws InvalidRequestException if the error is result of making an invalid authentication request.
- * @throws IdentityVerificationException if an error occurred while verifying the request tokens.
- */
- public Tokens handle(HttpServletRequest request, HttpServletResponse response) throws IdentityVerificationException {
- Validate.notNull(request, "request must not be null");
- Validate.notNull(response, "response must not be null");
-
- return requestProcessor.process(request, response);
- }
-
- /**
- * Process a request to obtain a set of {@link Tokens} that represent successful authentication or authorization.
- *
- * This method should be called when processing the callback request to your application. It will validate
- * authentication-related request parameters, handle performing a Code Exchange request if using
- * the "code" response type, and verify the integrity of the ID token (if present).
- *
- *
Important: When using this API, you must also use the {@link AuthenticationController#buildAuthorizeUrl(HttpServletRequest, String)}
- * when building the {@link AuthorizeUrl} that the user will be redirected to to login. Failure to do so may result
- * in a broken login experience for the user.
- *
- * @deprecated This method uses the {@link javax.servlet.http.HttpSession} for auth-based data, and is incompatible
+ * @deprecated This method uses the {@link jakarta.servlet.http.HttpSession} for auth-based data, and is incompatible
* with clients that are using the "id_token" or "token" responseType with browsers that enforce SameSite cookie
* restrictions. This method will be removed in version 2.0.0. Use
- * {@link AuthenticationController#handle(HttpServletRequest, HttpServletResponse)} instead.
+ * {@link AuthenticationController#handle(ServerWebExchange)} instead.
*
- * @param request the received request to process.
+ * @param serverWebExchange the received serverWebExchange to process.
* @return the Tokens obtained after the user authentication.
* @throws InvalidRequestException if the error is result of making an invalid authentication request.
* @throws IdentityVerificationException if an error occurred while verifying the request tokens.
*/
@Deprecated
- public Tokens handle(HttpServletRequest request) throws IdentityVerificationException {
- Validate.notNull(request, "request must not be null");
+ public Mono handle(ServerWebExchange serverWebExchange) {
+ Validate.notNull(serverWebExchange, "serverWebExchange must not be null");
- return requestProcessor.process(request, null);
+ return requestProcessor.process(serverWebExchange);
}
/**
* Pre builds an Auth0 Authorize Url with the given redirect URI using a random state and a random nonce if applicable.
*
*
Important: When using this API, you must also obtain the tokens using the
- * {@link AuthenticationController#handle(HttpServletRequest)} method. Failure to do so may result in a broken login
+ * {@link AuthenticationController#handle(ServerWebExchange)} method. Failure to do so may result in a broken login
* experience for users.
*
- * @deprecated This method stores data in the {@link javax.servlet.http.HttpSession}, and is incompatible with clients
+ * @deprecated This method stores data in the {@link jakarta.servlet.http.HttpSession}, and is incompatible with clients
* that are using the "id_token" or "token" responseType with browsers that enforce SameSite cookie restrictions.
* This method will be removed in version 2.0.0. Use
- * {@link AuthenticationController#buildAuthorizeUrl(HttpServletRequest, HttpServletResponse, String)} instead.
+ * {@link AuthenticationController#buildAuthorizeUrl(ServerWebExchange, String)} instead.
*
- * @param request the caller request. Used to keep the session context.
+ * @param serverWebExchange the caller serverWebExchange. Used to keep the session context.
* @param redirectUri the url to call back with the authentication result.
* @return the authorize url builder to continue any further parameter customization.
*/
@Deprecated
- public AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, String redirectUri) {
- Validate.notNull(request, "request must not be null");
+ public AuthorizeUrl buildAuthorizeUrl(ServerWebExchange serverWebExchange, String redirectUri) {
+ Validate.notNull(serverWebExchange, "serverWebExchange must not be null");
Validate.notNull(redirectUri, "redirectUri must not be null");
String state = StorageUtils.secureRandomString();
String nonce = StorageUtils.secureRandomString();
- return requestProcessor.buildAuthorizeUrl(request, null, redirectUri, state, nonce);
+ return requestProcessor.buildAuthorizeUrl(serverWebExchange, redirectUri, state, nonce);
}
-
- /**
- * Pre builds an Auth0 Authorize Url with the given redirect URI using a random state and a random nonce if applicable.
- *
- *
Important: When using this API, you must also obtain the tokens using the
- * {@link AuthenticationController#handle(HttpServletRequest, HttpServletResponse)} method. Failure to do so will result in a broken login
- * experience for users.
- *
- * @param request the HTTP request
- * @param response the HTTP response. Used to store auth-based cookies.
- * @param redirectUri the url to call back with the authentication result.
- * @return the authorize url builder to continue any further parameter customization.
- */
- public AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, HttpServletResponse response, String redirectUri) {
- Validate.notNull(request, "request must not be null");
- Validate.notNull(response, "response must not be null");
- Validate.notNull(redirectUri, "redirectUri must not be null");
-
- String state = StorageUtils.secureRandomString();
- String nonce = StorageUtils.secureRandomString();
-
- return requestProcessor.buildAuthorizeUrl(request, response, redirectUri, state, nonce);
- }
-
}
diff --git a/src/main/java/com/auth0/AuthorizeUrl.java b/main/src/main/java/com/auth0/AuthorizeUrl.java
similarity index 71%
rename from src/main/java/com/auth0/AuthorizeUrl.java
rename to main/src/main/java/com/auth0/AuthorizeUrl.java
index e871ca6..e79423d 100644
--- a/src/main/java/com/auth0/AuthorizeUrl.java
+++ b/main/src/main/java/com/auth0/AuthorizeUrl.java
@@ -1,15 +1,22 @@
package com.auth0;
+import static com.auth0.IdentityVerificationException.API_ERROR;
+
import com.auth0.client.auth.AuthAPI;
import com.auth0.client.auth.AuthorizeUrlBuilder;
import com.auth0.exception.Auth0Exception;
import com.auth0.json.auth.PushedAuthorizationResponse;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.*;
-
-import static com.auth0.IdentityVerificationException.API_ERROR;
+import com.auth0.net.Response;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.springframework.http.server.reactive.AbstractServerHttpResponse;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
/**
* Class to create and customize an Auth0 Authorize URL.
@@ -20,8 +27,7 @@ public class AuthorizeUrl {
private static final String SCOPE_OPENID = "openid";
- private HttpServletResponse response;
- private HttpServletRequest request;
+ private ServerWebExchange serverWebExchange;
private final String responseType;
private boolean useLegacySameSiteCookie = true;
private boolean setSecureCookie = false;
@@ -37,20 +43,18 @@ public class AuthorizeUrl {
/**
* Creates a new instance that can be used to build an Auth0 Authorization URL.
*
- * Using this constructor with a non-null {@link HttpServletResponse} will store the state and nonce as
+ * Using this constructor with a non-null {@link AbstractServerHttpResponse} will store the state and nonce as
* cookies when the {@link AuthorizeUrl#build()} method is called, with the appropriate SameSite attribute depending
- * on the responseType. State and nonce will also be stored in the {@link javax.servlet.http.HttpSession} as a fallback,
+ * on the responseType. State and nonce will also be stored in the {@link jakarta.servlet.http.HttpSession} as a fallback,
* but this behavior will be removed in a future release, and only cookies will be used.
*
* @param client the Auth0 Authentication API client
* @parem request the HTTP request. Used to store state and nonce as a fallback if cookies not set.
- * @param response the response where the state and nonce will be stored as cookies
* @param redirectUri the url to redirect to after authentication
* @param responseType the response type to use
*/
- AuthorizeUrl(AuthAPI client, HttpServletRequest request, HttpServletResponse response, String redirectUri, String responseType) {
- this.request = request;
- this.response = response;
+ AuthorizeUrl(AuthAPI client, ServerWebExchange serverWebExchange, String redirectUri, String responseType) {
+ this.serverWebExchange = serverWebExchange;
this.responseType = responseType;
this.authAPI = client;
this.redirectUri = redirectUri;
@@ -111,7 +115,7 @@ public AuthorizeUrl withSecureCookie(boolean secureCookie) {
/**
* Sets whether a fallback cookie should be used for clients that do not support "SameSite=None".
- * Only applicable when this instance is created with {@link AuthorizeUrl#AuthorizeUrl(AuthAPI, HttpServletRequest, HttpServletResponse, String, String)}.
+ * Only applicable when this instance is created with {@link AuthorizeUrl#AuthorizeUrl(AuthAPI, ServerWebExchange, String, String)}.
*
* @param useLegacySameSiteCookie whether or not to set fallback auth cookies for clients that do not support "SameSite=None"
* @return the builder instance
@@ -205,11 +209,13 @@ public AuthorizeUrl withParameter(String name, String value) {
* @return the string URL
* @throws IllegalStateException if it's called more than once
*/
- public String build() throws IllegalStateException {
- storeTransient();
- AuthorizeUrlBuilder builder = authAPI.authorizeUrl(redirectUri).withResponseType(responseType);
- params.forEach(builder::withParameter);
- return builder.build();
+ public Mono build() throws IllegalStateException {
+ return storeTransient()
+ .then(Mono.fromCallable(() -> {
+ AuthorizeUrlBuilder builder = authAPI.authorizeUrl(redirectUri).withResponseType(responseType);
+ params.forEach(builder::withParameter);
+ return builder.build();
+ }));
}
/**
@@ -220,29 +226,35 @@ public String build() throws IllegalStateException {
* @throws InvalidRequestException if there is an error when making the request.
* @see RFC 9126
*/
- public String fromPushedAuthorizationRequest() throws InvalidRequestException {
- storeTransient();
-
- try {
- PushedAuthorizationResponse pushedAuthResponse = authAPI.pushedAuthorizationRequest(redirectUri, responseType, params).execute();
- String requestUri = pushedAuthResponse.getRequestURI();
- if (requestUri == null || requestUri.isEmpty()) {
- throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing or empty request_uri value");
- }
- if (pushedAuthResponse.getExpiresIn() == null) {
- throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing expires_in value");
- }
- return authAPI.authorizeUrlWithPAR(pushedAuthResponse.getRequestURI());
- } catch (Auth0Exception e) {
- throw new InvalidRequestException(API_ERROR, e.getMessage(), e);
- }
+ public Mono fromPushedAuthorizationRequest() throws InvalidRequestException {
+ return storeTransient()
+ .then(Mono.fromCallable(() -> {
+ try {
+ Response pushedAuthResponse = authAPI.pushedAuthorizationRequest(redirectUri, responseType, params).execute();
+ if (pushedAuthResponse == null || pushedAuthResponse.getBody() == null) {
+ throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing or empty response");
+ }
+ String requestUri = pushedAuthResponse.getBody().getRequestURI();
+ if (requestUri == null || requestUri.isEmpty()) {
+ throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing or empty request_uri value");
+ }
+ if (pushedAuthResponse.getBody().getExpiresIn() == null) {
+ throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing expires_in value");
+ }
+ return authAPI.authorizeUrlWithPAR(pushedAuthResponse.getBody().getRequestURI());
+ } catch (Auth0Exception e) {
+ throw new InvalidRequestException(API_ERROR, e.getMessage(), e);
+ }
+ }));
}
- private void storeTransient() {
+ private Mono storeTransient() {
if (used) {
throw new IllegalStateException("The AuthorizeUrl instance must not be reused.");
}
+ ServerHttpResponse response = serverWebExchange.getResponse();
+ ServerHttpRequest request = serverWebExchange.getRequest();
if (response != null) {
SameSite sameSiteValue = containsFormPost() ? SameSite.NONE : SameSite.LAX;
@@ -250,12 +262,12 @@ private void storeTransient() {
TransientCookieStore.storeNonce(response, nonce, sameSiteValue, useLegacySameSiteCookie, setSecureCookie, cookiePath);
}
- // Also store in Session just in case developer uses deprecated
- // AuthenticationController.handle(HttpServletRequest) API
- RandomStorage.setSessionState(request, state);
- RandomStorage.setSessionNonce(request, nonce);
-
- used = true;
+ return Mono.fromCallable(() -> RandomStorage.setSessionState(serverWebExchange, state))
+ .flatMap(webSessionMono -> RandomStorage.setSessionNonce(serverWebExchange, nonce))
+ .flatMap(webSessionMono -> {
+ used = true;
+ return Mono.empty();
+ });
}
private boolean containsFormPost() {
diff --git a/src/main/java/com/auth0/IdTokenVerifier.java b/main/src/main/java/com/auth0/IdTokenVerifier.java
similarity index 99%
rename from src/main/java/com/auth0/IdTokenVerifier.java
rename to main/src/main/java/com/auth0/IdTokenVerifier.java
index d163e71..96a47e3 100644
--- a/src/main/java/com/auth0/IdTokenVerifier.java
+++ b/main/src/main/java/com/auth0/IdTokenVerifier.java
@@ -1,11 +1,10 @@
package com.auth0;
import com.auth0.jwt.interfaces.DecodedJWT;
-import org.apache.commons.lang3.Validate;
-
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import org.apache.commons.lang3.Validate;
/**
* Token verification utility class.
diff --git a/src/main/java/com/auth0/IdentityVerificationException.java b/main/src/main/java/com/auth0/IdentityVerificationException.java
similarity index 100%
rename from src/main/java/com/auth0/IdentityVerificationException.java
rename to main/src/main/java/com/auth0/IdentityVerificationException.java
diff --git a/src/main/java/com/auth0/InvalidRequestException.java b/main/src/main/java/com/auth0/InvalidRequestException.java
similarity index 100%
rename from src/main/java/com/auth0/InvalidRequestException.java
rename to main/src/main/java/com/auth0/InvalidRequestException.java
diff --git a/main/src/main/java/com/auth0/RandomStorage.java b/main/src/main/java/com/auth0/RandomStorage.java
new file mode 100644
index 0000000..033addc
--- /dev/null
+++ b/main/src/main/java/com/auth0/RandomStorage.java
@@ -0,0 +1,56 @@
+package com.auth0;
+
+
+import jakarta.servlet.http.HttpSession;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebSession;
+import reactor.core.publisher.Mono;
+
+class RandomStorage extends SessionUtils {
+
+ /**
+ * Check's if the request {@link HttpSession} saved state is equal to the given state.
+ * After the check, the value will be removed from the session.
+ *
+ * @param exchange the serverWebExchange
+ * @param state the state value to compare against.
+ * @return whether the state matches the expected one or not.
+ */
+ static Mono checkSessionState(ServerWebExchange exchange, String state) {
+ return remove(exchange, StorageUtils.STATE_KEY)
+ .map(currentState -> ((currentState == null && state == null) || currentState != null && currentState.equals(state)));
+ }
+
+ /**
+ * Saves the given state in the request {@link HttpSession}.
+ * If a state is already bound to the session, the value is replaced.
+ *
+ * @param exchange the serverWebExchange.
+ * @param state the state value to set.
+ */
+ static Mono setSessionState(ServerWebExchange exchange, String state) {
+ return set(exchange, StorageUtils.STATE_KEY, state);
+ }
+
+ /**
+ * Saves the given nonce in the request {@link HttpSession}.
+ * If a nonce is already bound to the session, the value is replaced.
+ *
+ * @param exchange the serverWebExchange.
+ * @param nonce the nonce value to set.
+ */
+ static Mono setSessionNonce(ServerWebExchange exchange, String nonce) {
+ return set(exchange, StorageUtils.NONCE_KEY, nonce);
+ }
+
+ /**
+ * Removes the nonce present in the request {@link HttpSession} and then returns it.
+ *
+ * @param exchange the serverWebExchange.
+ * @return the nonce value or null if it was not set.
+ */
+ static Mono removeSessionNonce(ServerWebExchange exchange) {
+ return remove(exchange, StorageUtils.NONCE_KEY)
+ .map(nonce -> nonce != null ? nonce.toString() : null);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/auth0/RequestProcessor.java b/main/src/main/java/com/auth0/RequestProcessor.java
similarity index 66%
rename from src/main/java/com/auth0/RequestProcessor.java
rename to main/src/main/java/com/auth0/RequestProcessor.java
index 6796982..b39f903 100644
--- a/src/main/java/com/auth0/RequestProcessor.java
+++ b/main/src/main/java/com/auth0/RequestProcessor.java
@@ -1,16 +1,22 @@
package com.auth0;
+import static com.auth0.InvalidRequestException.API_ERROR;
+import static com.auth0.InvalidRequestException.INVALID_STATE_ERROR;
+import static com.auth0.InvalidRequestException.JWT_VERIFICATION_ERROR;
+import static com.auth0.InvalidRequestException.MISSING_ACCESS_TOKEN;
+import static com.auth0.InvalidRequestException.MISSING_ID_TOKEN;
+
import com.auth0.client.auth.AuthAPI;
import com.auth0.exception.Auth0Exception;
import com.auth0.json.auth.TokenHolder;
-import org.apache.commons.lang3.Validate;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import com.auth0.net.Response;
import java.util.Arrays;
import java.util.List;
-
-import static com.auth0.InvalidRequestException.*;
+import org.apache.commons.lang3.Validate;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
/**
* Main class to handle the Authorize Redirect request.
@@ -121,17 +127,16 @@ AuthAPI getClient() {
/**
* Pre builds an Auth0 Authorize Url with the given redirect URI, state and nonce parameters.
*
- * @param request the request, used to store state and nonce in the Session
- * @param response the response, used to set state and nonce as cookies. If null, session will be used instead.
+ * @param serverWebExchange the serverWebExchange, used to store state and nonce in the Session
* @param redirectUri the url to call with the authentication result.
* @param state a valid state value.
* @param nonce the nonce value that will be used if the response type contains 'id_token'. Can be null.
* @return the authorize url builder to continue any further parameter customization.
*/
- AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, HttpServletResponse response, String redirectUri,
+ AuthorizeUrl buildAuthorizeUrl(ServerWebExchange serverWebExchange, String redirectUri,
String state, String nonce) {
- AuthorizeUrl creator = new AuthorizeUrl(client, request, response, redirectUri, responseType)
+ AuthorizeUrl creator = new AuthorizeUrl(client, serverWebExchange, redirectUri, responseType)
.withState(state);
if (this.organization != null) {
@@ -145,7 +150,7 @@ AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, HttpServletResponse r
}
// null response means state and nonce will be stored in session, so legacy cookie flag does not apply
- if (response != null) {
+ if (serverWebExchange.getResponse() != null) {
creator.withLegacySameSiteCookie(useLegacySameSiteCookie);
}
@@ -162,20 +167,27 @@ AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, HttpServletResponse r
* 4). Clearing the stored state, nonce and max_age values.
* 5). Handling success and any failure outcomes.
*
- * @throws IdentityVerificationException if an error occurred while processing the request
*/
- Tokens process(HttpServletRequest request, HttpServletResponse response) throws IdentityVerificationException {
- assertNoError(request);
- assertValidState(request, response);
+ Mono process(ServerWebExchange serverWebExchange) {
+
+ ServerHttpRequest request = serverWebExchange.getRequest();
+ ServerHttpResponse response = serverWebExchange.getResponse();
+
+ return assertNoError(request)
+ .then(assertValidState(serverWebExchange))
+ .then(getTokens(serverWebExchange, request, response));
+ }
+ private Mono getTokens(ServerWebExchange serverWebExchange,
+ ServerHttpRequest request, ServerHttpResponse response) {
Tokens frontChannelTokens = getFrontChannelTokens(request);
List responseTypeList = getResponseType();
if (responseTypeList.contains(KEY_ID_TOKEN) && frontChannelTokens.getIdToken() == null) {
- throw new InvalidRequestException(MISSING_ID_TOKEN, "ID Token is missing from the response.");
+ return Mono.error(new InvalidRequestException(MISSING_ID_TOKEN, "ID Token is missing from the response."));
}
if (responseTypeList.contains(KEY_TOKEN) && frontChannelTokens.getAccessToken() == null) {
- throw new InvalidRequestException(MISSING_ACCESS_TOKEN, "Access Token is missing from the response.");
+ return Mono.error(new InvalidRequestException(MISSING_ACCESS_TOKEN, "Access Token is missing from the response."));
}
String nonce;
@@ -185,15 +197,24 @@ Tokens process(HttpServletRequest request, HttpServletResponse response) throws
// Just in case the developer created the authorizeUrl that stores state/nonce in the session
if (nonce == null) {
- nonce = RandomStorage.removeSessionNonce(request);
+ return RandomStorage.removeSessionNonce(serverWebExchange)
+ .flatMap(newNonce -> {
+ verifyOptions.setNonce(newNonce);
+ return getVerifiedTokens(serverWebExchange, frontChannelTokens,
+ responseTypeList);
+ });
+ } else {
+ verifyOptions.setNonce(nonce);
+ return getVerifiedTokens(serverWebExchange, frontChannelTokens, responseTypeList);
}
} else {
- nonce = RandomStorage.removeSessionNonce(request);
+ return RandomStorage.removeSessionNonce(serverWebExchange)
+ .flatMap(newNonce -> {
+ verifyOptions.setNonce(newNonce);
+ return getVerifiedTokens(serverWebExchange, frontChannelTokens,
+ responseTypeList);
+ });
}
-
- verifyOptions.setNonce(nonce);
-
- return getVerifiedTokens(request, frontChannelTokens, responseTypeList);
}
static boolean requiresFormPostResponseMode(List responseType) {
@@ -203,16 +224,15 @@ static boolean requiresFormPostResponseMode(List responseType) {
/**
* Obtains code request tokens (if using Code flow) and validates the ID token.
- * @param request the HTTP request
+ * @param exchange the ServerWebExchange
* @param frontChannelTokens the tokens obtained from the front channel
* @param responseTypeList the reponse types
* @return a Tokens object that wraps the values obtained from the front-channel and/or the code request response.
- * @throws IdentityVerificationException
*/
- private Tokens getVerifiedTokens(HttpServletRequest request, Tokens frontChannelTokens, List responseTypeList)
- throws IdentityVerificationException {
+ private Mono getVerifiedTokens(ServerWebExchange exchange, Tokens frontChannelTokens, List responseTypeList) {
+ ServerHttpRequest request = exchange.getRequest();
- String authorizationCode = request.getParameter(KEY_CODE);
+ String authorizationCode = request.getQueryParams().getFirst(KEY_CODE);
Tokens codeExchangeTokens = null;
try {
@@ -222,7 +242,7 @@ private Tokens getVerifiedTokens(HttpServletRequest request, Tokens frontChannel
}
if (responseTypeList.contains(KEY_CODE)) {
// Code/Hybrid flow
- String redirectUri = request.getRequestURL().toString();
+ String redirectUri = request.getURI().toString();
codeExchangeTokens = exchangeCodeForTokens(authorizationCode, redirectUri);
if (!responseTypeList.contains(KEY_ID_TOKEN)) {
// If we already verified the front-channel token, don't verify it again.
@@ -233,9 +253,9 @@ private Tokens getVerifiedTokens(HttpServletRequest request, Tokens frontChannel
}
}
} catch (TokenValidationException e) {
- throw new IdentityVerificationException(JWT_VERIFICATION_ERROR, "An error occurred while trying to verify the ID Token.", e);
+ return Mono.error(new IdentityVerificationException(JWT_VERIFICATION_ERROR, "An error occurred while trying to verify the ID Token.", e));
} catch (Auth0Exception e) {
- throw new IdentityVerificationException(API_ERROR, "An error occurred while exchanging the authorization code.", e);
+ return Mono.error(new IdentityVerificationException(API_ERROR, "An error occurred while exchanging the authorization code.", e));
}
// Keep the front-channel ID Token and the code-exchange Access Token.
return mergeTokens(frontChannelTokens, codeExchangeTokens);
@@ -265,9 +285,9 @@ private AuthorizeUrl getAuthorizeUrl(String nonce, AuthorizeUrl creator) {
* @param request the request
* @return a new instance of Tokens wrapping the values present in the request parameters.
*/
- private Tokens getFrontChannelTokens(HttpServletRequest request) {
- Long expiresIn = request.getParameter(KEY_EXPIRES_IN) == null ? null : Long.parseLong(request.getParameter(KEY_EXPIRES_IN));
- return new Tokens(request.getParameter(KEY_ACCESS_TOKEN), request.getParameter(KEY_ID_TOKEN), null, request.getParameter(KEY_TOKEN_TYPE), expiresIn);
+ private Tokens getFrontChannelTokens(ServerHttpRequest request) {
+ Long expiresIn = request.getQueryParams().getFirst(KEY_EXPIRES_IN) == null ? null : Long.parseLong(request.getQueryParams().getFirst(KEY_EXPIRES_IN));
+ return new Tokens(request.getQueryParams().getFirst(KEY_ACCESS_TOKEN), request.getQueryParams().getFirst(KEY_ID_TOKEN), null, request.getQueryParams().getFirst(KEY_TOKEN_TYPE), expiresIn);
}
/**
@@ -276,38 +296,35 @@ private Tokens getFrontChannelTokens(HttpServletRequest request) {
* @param request the request
* @throws InvalidRequestException if the request contains an error
*/
- private void assertNoError(HttpServletRequest request) throws InvalidRequestException {
- String error = request.getParameter(KEY_ERROR);
+ private Mono assertNoError(ServerHttpRequest request) {
+ String error = request.getQueryParams().getFirst(KEY_ERROR);
if (error != null) {
- String errorDescription = request.getParameter(KEY_ERROR_DESCRIPTION);
- throw new InvalidRequestException(error, errorDescription);
+ String errorDescription = request.getQueryParams().getFirst(KEY_ERROR_DESCRIPTION);
+ return Mono.error(new InvalidRequestException(error, errorDescription));
}
+ return Mono.empty();
}
/**
* Checks whether the state received in the request parameters is the same as the one in the state cookie or session
* for this request.
*
- * @param request the request
+ * @param serverWebExchange the serverWebExchange
* @throws InvalidRequestException if the request contains a different state from the expected one
*/
- private void assertValidState(HttpServletRequest request, HttpServletResponse response) throws InvalidRequestException {
- // TODO in v2:
- // - only store state/nonce in cookies, remove session storage
- // - create specific exception classes for various state validation failures (missing from auth response, missing
- // state cookie, mismatch)
-
- String stateFromRequest = request.getParameter(KEY_STATE);
+ private Mono assertValidState(ServerWebExchange serverWebExchange) {
+ ServerHttpRequest request = serverWebExchange.getRequest();
+ ServerHttpResponse response = serverWebExchange.getResponse();
+ String stateFromRequest = request.getQueryParams().getFirst(KEY_STATE);
if (stateFromRequest == null) {
- throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state parameter was found on the authorization response.");
+ return Mono.error(new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state parameter was found on the authorization response."));
}
// If response is null, check the Session.
// This can happen when the deprecated handle method that only takes the request parameter is called
if (response == null) {
- checkSessionState(request, stateFromRequest);
- return;
+ return checkSessionState(serverWebExchange, stateFromRequest);
}
String cookieState = TransientCookieStore.getState(request, response);
@@ -315,23 +332,30 @@ private void assertValidState(HttpServletRequest request, HttpServletResponse re
// Just in case state was stored in Session by building auth URL with deprecated method, but then called the
// supported handle method with the request and response
if (cookieState == null) {
- if (SessionUtils.get(request, StorageUtils.STATE_KEY) == null) {
- throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state cookie or state session attribute found. Check that you are using non-deprecated methods and that cookies are not being removed on the server.");
- }
- checkSessionState(request, stateFromRequest);
- return;
+ return SessionUtils.get(serverWebExchange, StorageUtils.STATE_KEY)
+ .flatMap(state -> {
+ if (state == null) {
+ return Mono.error(new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state cookie or state session attribute found. Check that you are using non-deprecated methods and that cookies are not being removed on the server."));
+ }
+ return checkSessionState(serverWebExchange, stateFromRequest);
+ });
}
if (!cookieState.equals(stateFromRequest)) {
- throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one.");
+ return Mono.error(new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one."));
}
+
+ return Mono.empty();
}
- private void checkSessionState(HttpServletRequest request, String stateFromRequest) throws InvalidRequestException {
- boolean valid = RandomStorage.checkSessionState(request, stateFromRequest);
- if (!valid) {
- throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one.");
- }
+ private Mono checkSessionState(ServerWebExchange serverWebExchange, String stateFromRequest) {
+ return RandomStorage.checkSessionState(serverWebExchange, stateFromRequest)
+ .flatMap(valid -> {
+ if (!valid) {
+ return Mono.error(new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one."));
+ }
+ return Mono.empty();
+ });
}
/**
@@ -344,9 +368,10 @@ private void checkSessionState(HttpServletRequest request, String stateFromReque
* @see AuthAPI#exchangeCode(String, String)
*/
private Tokens exchangeCodeForTokens(String authorizationCode, String redirectUri) throws Auth0Exception {
- TokenHolder holder = client
+ Response tokenHolderResponse = client
.exchangeCode(authorizationCode, redirectUri)
.execute();
+ TokenHolder holder = tokenHolderResponse.getBody();
return new Tokens(holder.getAccessToken(), holder.getIdToken(), holder.getRefreshToken(), holder.getTokenType(), holder.getExpiresIn());
}
@@ -358,9 +383,9 @@ private Tokens exchangeCodeForTokens(String authorizationCode, String redirectUr
* @param codeExchangeTokens the code-exchange obtained tokens.
* @return a merged version of Tokens using the best tokens when possible.
*/
- private Tokens mergeTokens(Tokens frontChannelTokens, Tokens codeExchangeTokens) {
+ private Mono mergeTokens(Tokens frontChannelTokens, Tokens codeExchangeTokens) {
if (codeExchangeTokens == null) {
- return frontChannelTokens;
+ return Mono.just(frontChannelTokens);
}
// Prefer access token from the code exchange
@@ -384,7 +409,7 @@ private Tokens mergeTokens(Tokens frontChannelTokens, Tokens codeExchangeTokens)
// Refresh token only available from the code exchange
String refreshToken = codeExchangeTokens.getRefreshToken();
- return new Tokens(accessToken, idToken, refreshToken, type, expiresIn);
+ return Mono.just(new Tokens(accessToken, idToken, refreshToken, type, expiresIn));
}
}
\ No newline at end of file
diff --git a/src/main/java/com/auth0/SameSite.java b/main/src/main/java/com/auth0/SameSite.java
similarity index 92%
rename from src/main/java/com/auth0/SameSite.java
rename to main/src/main/java/com/auth0/SameSite.java
index f714d74..fc3059b 100644
--- a/src/main/java/com/auth0/SameSite.java
+++ b/main/src/main/java/com/auth0/SameSite.java
@@ -10,7 +10,7 @@ enum SameSite {
NONE("None"),
STRICT("Strict");
- private String value;
+ private final String value;
String getValue() {
return this.value;
diff --git a/main/src/main/java/com/auth0/SessionUtils.java b/main/src/main/java/com/auth0/SessionUtils.java
new file mode 100644
index 0000000..b926b3e
--- /dev/null
+++ b/main/src/main/java/com/auth0/SessionUtils.java
@@ -0,0 +1,69 @@
+package com.auth0;
+
+import org.apache.commons.lang3.Validate;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebSession;
+import reactor.core.publisher.Mono;
+
+/**
+ * Helper class to handle easy session key-value storage.
+ */
+@SuppressWarnings({"WeakerAccess", "unused"})
+public abstract class SessionUtils {
+
+ /**
+ * Extracts the HttpSession from the given request.
+ *
+ * @param serverWebExchange a valid request to get the session from
+ * @return the session of the request
+ */
+ protected static Mono getSession(ServerWebExchange serverWebExchange) {
+ return serverWebExchange.getSession();
+ }
+
+ /**
+ * Set's the attribute value to the request session.
+ *
+ * @param serverWebExchange a valid request to get the session from
+ * @param name the name of the attribute
+ * @param value the value to set
+ */
+ public static Mono set(ServerWebExchange serverWebExchange, String name, Object value) {
+ Validate.notNull(serverWebExchange);
+ Validate.notNull(name);
+ return serverWebExchange.getSession().map(session -> {
+ session.getAttributes().put(name, value);
+ return session;
+ });
+ }
+
+ /**
+ * Get the attribute with the given name from the request session.
+ *
+ * @param serverWebExchange a valid request to get the session from
+ * @param name the name of the attribute
+ * @return the attribute stored in the session or null if it doesn't exists
+ */
+ public static Mono