├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── 1-Authentication-sign-in-b2c.yml │ ├── 1-Authentication-sign-in.yml │ ├── 2-Authorization-I-call-graph.yml │ ├── 3-Authorization-II-groups.yml │ ├── 3-Authorization-II-protect-web-api-resource-api.yml │ ├── 3-Authorization-II-protect-web-api-webapp.yml │ └── 3-Authorization-II-roles.yml ├── .gitignore ├── 1-Authentication ├── sign-in-b2c │ ├── .classpath │ ├── .project │ ├── README.md │ ├── ReadmeFiles │ │ ├── app.png │ │ └── topology.png │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── microsoft │ │ │ │ └── azuresamples │ │ │ │ └── msal4j │ │ │ │ └── msidentityspringbootwebapp │ │ │ │ ├── MsIdentitySpringBootWebappApplication.java │ │ │ │ ├── SampleController.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ └── Utilities.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── additional-spring-configuration-metadata.json │ │ │ ├── application.yml │ │ │ ├── static │ │ │ ├── favicon.ico │ │ │ └── style.css │ │ │ └── templates │ │ │ ├── base.html │ │ │ ├── content │ │ │ ├── 401.html │ │ │ ├── 500.html │ │ │ ├── status.html │ │ │ ├── survey.html │ │ │ └── token.html │ │ │ ├── footer.html │ │ │ └── navbar.html │ │ └── test │ │ └── java │ │ └── com │ │ └── microsoft │ │ └── azuresamples │ │ └── msal4j │ │ └── msidentityspringbootwebapp │ │ └── MsIdentitySpringBootWebappApplicationTests.java └── sign-in │ ├── .classpath │ ├── .project │ ├── AppCreationScripts │ ├── AppCreationScripts.md │ ├── Cleanup.ps1 │ ├── Configure.ps1 │ └── sample.json │ ├── README.md │ ├── ReadmeFiles │ ├── app.png │ └── topology.png │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── azuresamples │ │ │ └── msal4j │ │ │ └── msidentityspringbootwebapp │ │ │ ├── MsIdentitySpringBootWebappApplication.java │ │ │ ├── SampleController.java │ │ │ ├── SecurityConfig.java │ │ │ └── Utilities.java │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ ├── static │ │ ├── favicon.ico │ │ └── style.css │ │ └── templates │ │ ├── base.html │ │ ├── content │ │ ├── 401.html │ │ ├── 500.html │ │ ├── graph.html │ │ ├── status.html │ │ ├── survey.html │ │ └── token.html │ │ ├── footer.html │ │ └── navbar.html │ └── test │ └── java │ └── com │ └── microsoft │ └── azuresamples │ └── msal4j │ └── msidentityspringbootwebapp │ └── MsIdentitySpringBootWebappApplicationTests.java ├── 2-Authorization-I └── call-graph │ ├── .classpath │ ├── .project │ ├── AppCreationScripts │ ├── AppCreationScripts.md │ ├── Cleanup.ps1 │ ├── Configure.ps1 │ └── sample.json │ ├── README.md │ ├── ReadmeFiles │ ├── app.png │ └── topology.png │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── azuresamples │ │ │ └── msal4j │ │ │ └── msidentityspringbootwebapp │ │ │ ├── MsIdentitySpringBootWebappApplication.java │ │ │ ├── SampleController.java │ │ │ ├── SecurityConfig.java │ │ │ └── Utilities.java │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ ├── static │ │ ├── favicon.ico │ │ └── style.css │ │ └── templates │ │ ├── base.html │ │ ├── content │ │ ├── 401.html │ │ ├── 500.html │ │ ├── graph.html │ │ ├── status.html │ │ ├── survey.html │ │ └── token.html │ │ ├── footer.html │ │ └── navbar.html │ └── test │ └── java │ └── com │ └── microsoft │ └── azuresamples │ └── msal4j │ └── msidentityspringbootwebapp │ └── MsIdentitySpringBootWebappApplicationTests.java ├── 3-Authorization-II ├── groups │ ├── .classpath │ ├── .project │ ├── AppCreationScripts │ │ ├── AppCreationScripts.md │ │ ├── Cleanup.ps1 │ │ ├── Configure.ps1 │ │ └── sample.json │ ├── README.md │ ├── ReadmeFiles │ │ ├── app.png │ │ └── topology.png │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── azuresamples │ │ │ └── msal4j │ │ │ └── msidentityspringbootwebapp │ │ │ ├── MsIdentitySpringBootWebappApplication.java │ │ │ ├── SampleController.java │ │ │ ├── SecurityConfig.java │ │ │ └── Utilities.java │ │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ ├── static │ │ ├── favicon.ico │ │ └── style.css │ │ └── templates │ │ ├── base.html │ │ ├── content │ │ ├── 401.html │ │ ├── 403.html │ │ ├── 500.html │ │ ├── graph.html │ │ ├── group.html │ │ ├── status.html │ │ ├── survey.html │ │ └── token.html │ │ ├── footer.html │ │ └── navbar.html ├── protect-web-api │ ├── AppCreationScripts │ │ ├── AppCreationScripts.md │ │ ├── Cleanup.ps1 │ │ ├── Configure.ps1 │ │ └── sample.json │ ├── README.md │ ├── ReadmeFiles │ │ ├── app.png │ │ └── topology.png │ ├── resource-api │ │ ├── .classpath │ │ ├── .gitignore │ │ ├── .project │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── microsoft │ │ │ │ └── azuresamples │ │ │ │ └── msal4j │ │ │ │ └── msidentityspringbootwebapi │ │ │ │ ├── MsIdentitySpringBootWebApi.java │ │ │ │ ├── SampleController.java │ │ │ │ └── SecurityConfig.java │ │ │ └── resources │ │ │ └── application.yml │ └── webapp │ │ ├── .classpath │ │ ├── .gitignore │ │ ├── .project │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── microsoft │ │ │ └── azuresamples │ │ │ └── msal4j │ │ │ └── msidentityspringbootwebapp │ │ │ ├── MsIdentitySpringBootWebappApplication.java │ │ │ ├── SampleController.java │ │ │ ├── SecurityConfig.java │ │ │ └── Utilities.java │ │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ ├── static │ │ ├── favicon.ico │ │ └── style.css │ │ └── templates │ │ ├── base.html │ │ ├── content │ │ ├── 401.html │ │ ├── 500.html │ │ ├── api.html │ │ ├── status.html │ │ ├── survey.html │ │ └── token.html │ │ ├── footer.html │ │ └── navbar.html └── roles │ ├── .classpath │ ├── .project │ ├── AppCreationScripts │ ├── AppCreationScripts.md │ ├── Cleanup.ps1 │ ├── CleanupUsersAndRoles.ps1 │ ├── Configure.ps1 │ ├── CreateUsersAndAssignRoles.ps1 │ ├── apps.json │ └── sample.json │ ├── README.md │ ├── ReadmeFiles │ ├── app.png │ └── topology.png │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── com │ │ └── microsoft │ │ └── azuresamples │ │ └── msal4j │ │ └── msidentityspringbootwebapp │ │ ├── MsIdentitySpringBootWebappApplication.java │ │ ├── SampleController.java │ │ ├── SecurityConfig.java │ │ └── Utilities.java │ └── resources │ ├── META-INF │ └── additional-spring-configuration-metadata.json │ ├── application.yml │ ├── static │ ├── favicon.ico │ └── style.css │ └── templates │ ├── base.html │ ├── content │ ├── 401.html │ ├── 403.html │ ├── 500.html │ ├── graph.html │ ├── role.html │ ├── status.html │ ├── survey.html │ └── token.html │ ├── footer.html │ └── navbar.html ├── 4-Deployment └── deploy-to-azure-app-service │ ├── README.md │ └── ReadmeFiles │ ├── disable_easy_auth.png │ └── topology.png ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md └── ReadmeFiles ├── call-graph.png └── sign-in.png /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | 3 | * ... 4 | 5 | ## Does this introduce a breaking change? 6 | 7 | ``` 8 | [ ] Yes 9 | [ ] No 10 | ``` 11 | 12 | ## Pull Request Type 13 | What kind of change does this Pull Request introduce? 14 | 15 | 16 | ``` 17 | [ ] Bugfix 18 | [ ] Feature 19 | [ ] Code style update (formatting, local variables) 20 | [ ] Refactoring (no functional changes, no api changes) 21 | [ ] Documentation content changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## How to Test 26 | * Get the code 27 | 28 | ``` 29 | git clone [repo-address] 30 | cd [repo-name] 31 | git checkout [branch-name] 32 | npm install 33 | ``` 34 | 35 | * Test the code 36 | 37 | ``` 38 | ``` 39 | 40 | ## What to Check 41 | Verify that the following are valid 42 | * ... 43 | 44 | ## Other Information 45 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: "/1-Authentication/sign-in" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: maven 9 | directory: "/1-Authentication/sign-in-b2c" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | - package-ecosystem: maven 14 | directory: "/2-Authorization-I/call-graph" 15 | schedule: 16 | interval: daily 17 | open-pull-requests-limit: 10 18 | - package-ecosystem: maven 19 | directory: "/3-Authorization-II/groups" 20 | schedule: 21 | interval: daily 22 | open-pull-requests-limit: 10 23 | - package-ecosystem: maven 24 | directory: "/3-Authorization-II/protect-web-api/resource-api" 25 | schedule: 26 | interval: daily 27 | open-pull-requests-limit: 10 28 | - package-ecosystem: maven 29 | directory: "/3-Authorization-II/protect-web-api/webapp" 30 | schedule: 31 | interval: daily 32 | open-pull-requests-limit: 10 33 | - package-ecosystem: maven 34 | directory: "/3-Authorization-II/roles" 35 | schedule: 36 | interval: daily 37 | open-pull-requests-limit: 10 38 | -------------------------------------------------------------------------------- /.github/workflows/1-Authentication-sign-in-b2c.yml: -------------------------------------------------------------------------------- 1 | name: Sign-in B2C 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['1-Authentication/sign-in-b2c/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['1-Authentication/sign-in-b2c/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./1-Authentication/sign-in-b2c 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.github/workflows/1-Authentication-sign-in.yml: -------------------------------------------------------------------------------- 1 | name: Sign-in Sample CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['1-Authentication/sign-in/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['1-Authentication/sign-in/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./1-Authentication/sign-in 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.github/workflows/2-Authorization-I-call-graph.yml: -------------------------------------------------------------------------------- 1 | name: Call Graph Sample CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['2-Authorization-I/call-graph/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['2-Authorization-I/call-graph/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./2-Authorization-I/call-graph 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.github/workflows/3-Authorization-II-groups.yml: -------------------------------------------------------------------------------- 1 | name: 3 II Groups Sample CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['3-Authorization-II/groups/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['3-Authorization-II/groups/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./3-Authorization-II/groups 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.github/workflows/3-Authorization-II-protect-web-api-resource-api.yml: -------------------------------------------------------------------------------- 1 | name: 3 II Protect Web API Resource Sample CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['3-Authorization-II/protect-web-api/resource-api/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['3-Authorization-II/protect-web-api/resource-api/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./3-Authorization-II/protect-web-api/resource-api 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.github/workflows/3-Authorization-II-protect-web-api-webapp.yml: -------------------------------------------------------------------------------- 1 | name: 3 II Protect Web App Sample CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['3-Authorization-II/protect-web-api/webapp/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['3-Authorization-II/protect-web-api/webapp/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./3-Authorization-II/protect-web-api/webapp 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.github/workflows/3-Authorization-II-roles.yml: -------------------------------------------------------------------------------- 1 | name: 3 II Roles Sample CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths: ['3-Authorization-II/roles/**', '.github/workflows/**'] 7 | pull_request: 8 | branches: [ main ] 9 | paths: ['3-Authorization-II/roles/**', '.github/workflows/**'] 10 | 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | env: 17 | relativePath: ./3-Authorization-II/roles 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: actions/setup-java@v2 22 | with: 23 | distribution: 'adopt' 24 | java-version: 16 25 | - name: Build with Maven 26 | run: mvn --batch-mode --update-snapshots verify 27 | working-directory: ${{ env.relativePath }} 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | .vscode/ 26 | .settings/ 27 | .DS_Store 28 | target/ 29 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1619220380229 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/ReadmeFiles/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/1-Authentication/sign-in-b2c/ReadmeFiles/app.png -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/1-Authentication/sign-in-b2c/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | com.microsoft.azuresamples.msal4j 12 | ms-identity-spring-boot-webapp 13 | 0.0.1-SNAPSHOT 14 | ms-identity-spring-boot-webapp 15 | Microsoft identity platform Spring Boot sample 16 | 17 | 11 18 | 3.9.0 19 | 20 | 21 | 22 | 23 | com.azure.spring 24 | azure-spring-boot-starter-active-directory-b2c 25 | ${azure.version} 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-oauth2-client 32 | 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-web 38 | 39 | 40 | 41 | 42 | com.microsoft.graph 43 | microsoft-graph 44 | 5.5.0 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-thymeleaf 51 | 52 | 53 | org.thymeleaf.extras 54 | thymeleaf-extras-springsecurity5 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-test 60 | test 61 | 62 | 63 | org.junit.vintage 64 | junit-vintage-engine 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplication.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebappApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebappApplication.class, args); 13 | } 14 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SampleController.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.ui.Model; 12 | 13 | @Controller 14 | public class SampleController { 15 | /** 16 | * Add HTML partial fragment from /templates/content folder to request and serve base html 17 | * @param model Model used for placing user param and bodyContent param in request before serving UI. 18 | * @param fragment used to determine which partial to put into UI 19 | */ 20 | private String hydrateUI(Model model, String fragment) { 21 | model.addAttribute("bodyContent", String.format("content/%s.html", fragment)); 22 | return "base"; //base.html in /templates folder 23 | } 24 | 25 | /** 26 | * Sign in status endpoint 27 | * The page demonstrates sign-in status. For full details, see the src/main/webapp/content/status.html file. 28 | * 29 | * @param model Model used for placing bodyContent param in request before serving UI. 30 | * @return String the UI. 31 | */ 32 | @GetMapping(value = {"/", "sign_in_status", "/index"}) 33 | public String status(Model model) { 34 | return hydrateUI(model, "status"); 35 | } 36 | 37 | /** 38 | * Token details endpoint 39 | * Demonstrates how to extract and make use of token details 40 | * For full details, see method: Utilities.filterclaims(OidcUser principal) 41 | * 42 | * @param model Model used for placing claims param and bodyContent param in request before serving UI. 43 | * @param principal OidcUser this object contains all ID token claims about the user. See utilities file. 44 | * @return String the UI. 45 | */ 46 | @GetMapping(path = "/token_details") 47 | public String tokenDetails(Model model, @AuthenticationPrincipal OidcUser principal) { 48 | model.addAttribute("claims", Utilities.filterClaims(principal)); 49 | return hydrateUI(model, "token"); 50 | } 51 | 52 | // survey endpoint - did the sample address your needs? 53 | // not an integral a part of this tutorial. 54 | @GetMapping(path = "/survey") 55 | public String survey(Model model) { 56 | return hydrateUI(model, "survey"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import com.azure.spring.autoconfigure.b2c.AADB2COidcLoginConfigurer; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | 12 | /** 13 | * update comments here 14 | */ 15 | 16 | @EnableWebSecurity 17 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 18 | 19 | @Value("${app.protect.authenticated}") 20 | private String[] protectedRoutes; 21 | 22 | private final AADB2COidcLoginConfigurer configurer; 23 | 24 | public SecurityConfig(AADB2COidcLoginConfigurer configurer) { 25 | this.configurer = configurer; 26 | } 27 | 28 | @Override 29 | protected void configure(HttpSecurity http) throws Exception { 30 | // @formatter:off 31 | http.authorizeRequests() 32 | .antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details) 33 | .antMatchers("/**").permitAll() // allow all other routes. 34 | .and() 35 | .apply(configurer) 36 | ; 37 | // @formatter:off 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/Utilities.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import java.util.Arrays; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 12 | 13 | public class Utilities { 14 | private Utilities() { 15 | throw new IllegalStateException("Utility class. Don't instantiate"); 16 | } 17 | 18 | /** 19 | * Take a subset of ID Token claims and put them into KV pairs for UI to 20 | * display. 21 | * 22 | * @param principal OidcUser (see SampleController for details) 23 | * @return Map of filteredClaims 24 | */ 25 | public static Map filterClaims(OidcUser principal) { 26 | final String[] claimKeys = { "sub", "aud", "ver", "iss", "oid", "name", "city", "jobTitle" }; 27 | final List includeClaims = Arrays.asList(claimKeys); 28 | 29 | Map filteredClaims = new HashMap<>(); 30 | includeClaims.forEach(claim -> { 31 | if (principal.getIdToken().getClaims().containsKey(claim)) { 32 | filteredClaims.put(claim, principal.getIdToken().getClaimAsString(claim)); 33 | } 34 | }); 35 | return filteredClaims; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": [ 3 | { 4 | "name": "app.protect.authenticated", 5 | "type": "java.lang.String[]", 6 | "description": "limit these pages to authenticated users. Use '=/route1' for a single route. Use '=/route1, /route2' for multiple." 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | activedirectory: 3 | b2c: 4 | base-uri: https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/ 5 | client-id: 373ac824-ac4f-4b35-a5a3-1547722fba77 6 | client-secret: 7.18gt132wO-t.~Cf.mfZCy_C7rHmicnuO 7 | logout-success-url: http://localhost:8080/ 8 | user-flows: 9 | sign-up-or-sign-in: b2c_1_susi 10 | profile-edit: b2c_1_edit_profile 11 | password-reset: b2c_1_reset 12 | user-name-attribute-name: name 13 | 14 | app: 15 | protect: 16 | authenticated: /token_details 17 | 18 | 19 | # un-comment the following lines if you are deploying to a reverse proxy (e.g. Azure App Service) 20 | # server: 21 | # forward-headers-strategy: native 22 | # tomcat: 23 | # remoteip: 24 | # protocol-header: "X-Forwarded-Proto" 25 | # remote-ip-header: "X-Forwarded-For" 26 | # internal-proxies: ".*" 27 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/1-Authentication/sign-in-b2c/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/static/style.css: -------------------------------------------------------------------------------- 1 | .body-content { 2 | padding-top: 15px; 3 | padding-bottom: 15px; 4 | padding-left: 15px; 5 | padding-right: 15px; 6 | } 7 | 8 | .dl-horizontal dt { 9 | white-space: normal; 10 | } 11 | 12 | .flashToast { 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | } 17 | 18 | 19 | .card { 20 | width: 50vw; 21 | margin:auto; 22 | background:#f0f0f0; 23 | border:1px solid black; 24 | } 25 | 26 | .card-header { 27 | /* background: darkseagreen; */ 28 | color: rgba(255,255,255,0.85); 29 | background: #0078d4; 30 | font-weight: 300; 31 | } 32 | 33 | .card-text { 34 | align-content: center 35 | } 36 | 37 | #wrapper { 38 | display: flex; 39 | } 40 | 41 | #left { 42 | flex: content; 43 | margin-right: 0.5em; 44 | 45 | } 46 | 47 | #right { 48 | flex: 1; 49 | } 50 | 51 | #footer { 52 | width: 50vw; 53 | margin: auto; 54 | text-align: left; 55 | margin-top: 1em; 56 | } 57 | 58 | .smiley, .frowny { 59 | height: 1.5em; 60 | width: 1.5em; 61 | margin: auto; 62 | fill: #0078d4 63 | } 64 | 65 | .smiley:hover, .frowny:hover{ 66 | height: 1.5em; 67 | width: 1.5em; 68 | margin: auto; 69 | fill: white; 70 | border: 1px solid #0078d4; 71 | background-color: #0078d4; 72 | border-radius: 50%; 73 | } 74 | 75 | #check-icon { 76 | height: 1.25em; 77 | width: 1.25em; 78 | margin: auto; 79 | fill: green; 80 | } 81 | 82 | a.nostyle:link { 83 | text-decoration: inherit; 84 | color: inherit; 85 | } 86 | 87 | a.nostyle:visited { 88 | text-decoration: inherit; 89 | color: inherit; 90 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Authentication: Use Azure Active Directory B2C Spring Boot Starter to sign in users 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/content/401.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 401: Unauthorized 5 |
6 |
7 |

8 | Visiting this page requires you to be authenticated. Use the button on the top right to sign in. 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/content/500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 500: Auth Error 5 |
6 |
7 |

8 | ${details}
9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/content/status.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | You're signed in! 5 |
6 |
7 | You're not signed in. 8 |
9 |
10 |
11 |

12 |

13 | ID Token Details 14 |
15 |
16 | Use the button on the top right to sign in. 17 | Attempts to go to a protected page, such as the ID Token Details page will result in automatic redirection to Microsoft identity platform sign in page. 18 |
19 |

20 |
21 |
22 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/content/survey.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Tell us how we did! 4 |
5 |
6 | Click here if the survey question does not load automatically. 7 |

8 | 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/content/token.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | ID Token Details 4 |
5 |
6 |

7 | The following is a limited subset of some important claims in your ID Token. 8 |
9 | 10 | : 11 | 12 |
13 |
14 |
15 | Sign-in Status 16 |

17 |
18 |
19 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |  Have you updated your app's redirect URI on Azure Portal? 5 |
6 | Redirect URI: 7 | 8 |
9 |
10 | 11 | 12 | 13 |   Does this sample address your learning objective? 14 | 15 |
16 |

17 |

© 2021

18 |

-------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /1-Authentication/sign-in-b2c/src/test/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MsIdentitySpringBootWebappApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1615934394943 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/AppCreationScripts/Cleanup.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [CmdletBinding()] 7 | param( 8 | [PSCredential] $Credential, 9 | [Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')] 10 | [string] $tenantId, 11 | [Parameter(Mandatory=$False, HelpMessage='Azure environment to use while running the script (it defaults to AzureCloud)')] 12 | [string] $azureEnvironmentName 13 | ) 14 | 15 | #Requires -Modules AzureAD -RunAsAdministrator 16 | 17 | 18 | 19 | if ($null -eq (Get-Module -ListAvailable -Name "AzureAD")) { 20 | Install-Module "AzureAD" -Scope CurrentUser 21 | } 22 | Import-Module AzureAD 23 | $ErrorActionPreference = "Stop" 24 | 25 | Function Cleanup 26 | { 27 | if (!$azureEnvironmentName) 28 | { 29 | $azureEnvironmentName = "AzureCloud" 30 | } 31 | 32 | <# 33 | .Description 34 | This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script 35 | #> 36 | 37 | # $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant 38 | # into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD. 39 | 40 | # Login to Azure PowerShell (interactive if credentials are not already provided: 41 | # you'll need to sign-in with creds enabling your to create apps in the tenant) 42 | if (!$Credential -and $TenantId) 43 | { 44 | $creds = Connect-AzureAD -TenantId $tenantId -AzureEnvironmentName $azureEnvironmentName 45 | } 46 | else 47 | { 48 | if (!$TenantId) 49 | { 50 | $creds = Connect-AzureAD -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 51 | } 52 | else 53 | { 54 | $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 55 | } 56 | } 57 | 58 | if (!$tenantId) 59 | { 60 | $tenantId = $creds.Tenant.Id 61 | } 62 | $tenant = Get-AzureADTenantDetail 63 | $tenantName = ($tenant.VerifiedDomains | Where-Object { $_._Default -eq $True }).Name 64 | 65 | # Removes the applications 66 | Write-Host "Cleaning-up applications from tenant '$tenantName'" 67 | 68 | 69 | Write-Host "Removing 'webApp' (java-spring-webapp-auth) if needed" 70 | Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-auth'" | ForEach-Object {Remove-AzureADApplication -ObjectId $_.ObjectId } 71 | $apps = Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-auth'" 72 | if ($apps) 73 | { 74 | Remove-AzureADApplication -ObjectId $apps.ObjectId 75 | } 76 | 77 | foreach ($app in $apps) 78 | { 79 | Remove-AzureADApplication -ObjectId $app.ObjectId 80 | Write-Host "Removed java-spring-webapp-auth.." 81 | } 82 | # also remove service principals of this app 83 | Get-AzureADServicePrincipal -filter "DisplayName eq 'java-spring-webapp-auth'" | ForEach-Object {Remove-AzureADServicePrincipal -ObjectId $_.Id -Confirm:$false} 84 | 85 | 86 | } 87 | 88 | Cleanup -Credential $Credential -tenantId $TenantId -------------------------------------------------------------------------------- /1-Authentication/sign-in/AppCreationScripts/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sample": { 3 | "Title": "Enable your Java Spring Boot web app to sign in users on your Azure Active Directory tenant with the Microsoft identity platform", 4 | "Level": 100, 5 | "Client": "Java Spring Boot web app", 6 | "RepositoryUrl": "ms-identity-java-spring-tutorial", 7 | "Endpoint": "AAD v2.0" 8 | }, 9 | "AADApps": [ 10 | { 11 | "Id": "webApp", 12 | "Name": "java-spring-webapp-auth", 13 | "Kind": "WebApp", 14 | "Audience": "AzureADMyOrg", 15 | "PasswordCredentials": "Auto", 16 | "AllowImplicitFlow": false, 17 | "HomePage": "http://localhost:8080/", 18 | "ReplyUrls": "http://localhost:8080/login/oauth2/code/", 19 | "RequiredResourcesAccess": [] 20 | } 21 | ], 22 | "CodeConfiguration": [ 23 | { 24 | "App": "webApp", 25 | "SettingKind": "Replace", 26 | "SettingFile": "\\..\\src\\main\\resources\\application.yml", 27 | "Mappings": [ 28 | { 29 | "key": "Enter_Your_Tenant_ID_Here", 30 | "value": "$tenantId" 31 | }, 32 | { 33 | "key": "Enter_Your_Client_ID_Here", 34 | "value": "webApp.AppId" 35 | }, 36 | { 37 | "key": "Enter_Your_Client_Secret_Here", 38 | "value": ".AppKey" 39 | } 40 | ] 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in/ReadmeFiles/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/1-Authentication/sign-in/ReadmeFiles/app.png -------------------------------------------------------------------------------- /1-Authentication/sign-in/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/1-Authentication/sign-in/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /1-Authentication/sign-in/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | 12 | com.microsoft.azuresamples.msal4j 13 | ms-identity-spring-boot-webapp 14 | 0.0.1-SNAPSHOT 15 | ms-identity-spring-boot-webapp 16 | Microsoft identity platform Spring Boot sample 17 | 18 | 11 19 | 3.9.0 20 | 21 | 22 | 23 | 24 | com.azure.spring 25 | azure-spring-boot-starter-active-directory 26 | ${azure.version} 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-oauth2-client 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-thymeleaf 41 | 42 | 43 | org.thymeleaf.extras 44 | thymeleaf-extras-springsecurity5 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | org.junit.vintage 53 | junit-vintage-engine 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | repackage 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplication.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebappApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebappApplication.class, args); 13 | } 14 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SampleController.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 8 | import org.springframework.security.core.annotation.AuthenticationPrincipal; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | 12 | @Controller 13 | public class SampleController { 14 | /** 15 | * Add HTML partial fragment from /templates/content folder to request and serve base html 16 | * @param model Model used for placing user param and bodyContent param in request before serving UI. 17 | * @param fragment used to determine which partial to put into UI 18 | */ 19 | private String hydrateUI(Model model, String fragment) { 20 | model.addAttribute("bodyContent", String.format("content/%s.html", fragment)); 21 | return "base"; //base.html in /templates folder 22 | } 23 | 24 | /** 25 | * Sign in status endpoint 26 | * The page demonstrates sign-in status. For full details, see the src/main/webapp/content/status.html file. 27 | * 28 | * @param model Model used for placing bodyContent param in request before serving UI. 29 | * @return String the UI. 30 | */ 31 | @GetMapping(value = {"/", "sign_in_status", "/index"}) 32 | public String status(Model model) { 33 | return hydrateUI(model, "status"); 34 | } 35 | 36 | /** 37 | * Token details endpoint 38 | * Demonstrates how to extract and make use of token details 39 | * For full details, see method: Utilities.filterclaims(OidcUser principal) 40 | * 41 | * @param model Model used for placing claims param and bodyContent param in request before serving UI. 42 | * @param principal OidcUser this object contains all ID token claims about the user. See utilities file. 43 | * @return String the UI. 44 | */ 45 | @GetMapping(path = "/token_details") 46 | public String tokenDetails(Model model, @AuthenticationPrincipal OidcUser principal) { 47 | model.addAttribute("claims", Utilities.filterClaims(principal)); 48 | return hydrateUI(model, "token"); 49 | } 50 | 51 | // survey endpoint - did the sample address your needs? 52 | // not an integral a part of this tutorial. 53 | @GetMapping(path = "/survey") 54 | public String survey(Model model) { 55 | return hydrateUI(model, "survey"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import com.azure.spring.aad.webapp.AADWebSecurityConfigurerAdapter; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | 13 | /** 14 | * AADWebSecurityConfigurer (AADWSC) is an extension of Spring's WebSecurityConfigurer (WSC). 15 | * 16 | * You must extend AADWSC to define your own custom configuration in the configure() method. 17 | * Be sure to call super.configure() first. This will set up all of your AuthN/AuthZ properly. 18 | * 19 | * You may omit this by not extending the AADWSC class. 20 | * 21 | * If you don't extend AADWSC or WSC, AAD boot starter will create a DefaultAADWebSecurityConfigurerAdapter 22 | * bean automatically, and define its own default http.authorizeRequests() rule (authorize ALL requests). 23 | * 24 | * See DefaultAADWebSecurityConfigurerAdapter in com.azure.spring.aad.webapp.AADWebAppConfiguration 25 | */ 26 | 27 | @EnableWebSecurity 28 | @EnableGlobalMethodSecurity(prePostEnabled = true) 29 | public class SecurityConfig extends AADWebSecurityConfigurerAdapter{ 30 | @Value( "${app.protect.authenticated}" ) 31 | private String[] protectedRoutes; 32 | 33 | @Override 34 | public void configure(HttpSecurity http) throws Exception { 35 | // use required configuration from AADWebSecurityAdapter.configure: 36 | super.configure(http); 37 | // add custom configuration: 38 | http.authorizeRequests() 39 | .antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details) 40 | .antMatchers("/**").permitAll(); // allow all other routes. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/Utilities.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import java.util.Arrays; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 12 | 13 | public class Utilities { 14 | private Utilities() { 15 | throw new IllegalStateException("Utility class. Don't instantiate"); 16 | } 17 | 18 | /** 19 | * Take a subset of ID Token claims and put them into KV pairs for UI to display. 20 | * @param principal OidcUser (see SampleController for details) 21 | * @return Map of filteredClaims 22 | */ 23 | public static Map filterClaims(OidcUser principal) { 24 | final String[] claimKeys = {"sub", "aud", "ver", "iss", "name", "oid", "preferred_username"}; 25 | final List includeClaims = Arrays.asList(claimKeys); 26 | 27 | Map filteredClaims = new HashMap<>(); 28 | includeClaims.forEach(claim -> { 29 | if (principal.getIdToken().getClaims().containsKey(claim)) { 30 | filteredClaims.put(claim, principal.getIdToken().getClaims().get(claim).toString()); 31 | } 32 | }); 33 | return filteredClaims; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | {"properties": [ 2 | { 3 | "name": "app.ui.base", 4 | "type": "java.lang.String", 5 | "description": "the base UI template page name in src/main/webapp" 6 | }, 7 | { 8 | "name": "app.ui.content", 9 | "type": "java.lang.String", 10 | "description": "content with which to populate app.ui.base, also located in same folder." 11 | }, 12 | { 13 | "name": "app.protect.authenticated", 14 | "type": "java.lang.String[]", 15 | "description": "limit these pages to authenticated users. Use '=/route1' for a single route. Use '=/route1, /route2' for multiple." 16 | } 17 | ]} -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | activedirectory: 3 | # Specifies your Active Directory ID: 4 | tenant-id: Enter_Your_Tenant_ID_Here 5 | # Specifies your App Registration's Application ID: 6 | client-id: Enter_Your_Client_ID_Here 7 | # Specifies your App Registration's secret key: 8 | client-secret: Enter_Your_Client_Secret_Here 9 | # Specifies the post-log-out-redirect-uri, where to return your app after logout. 10 | post-logout-redirect-uri: http://localhost:8080 11 | # Specifies the Microsoft Graph scopes that your app needs access to - not required in this app. 12 | # authorization-clients: 13 | # graph: 14 | # scopes: https://graph.microsoft.com/User.Read 15 | 16 | # which routes to restrict to authenticated users only (see SecurityConfig.java): 17 | # enter String array (comma-separated) or just one route. 18 | # e.g. authenticated: /route1, /route2, /route3 19 | app: 20 | protect: 21 | authenticated: /token_details 22 | 23 | # un-comment the following lines if you are deploying to a reverse proxy (e.g. Azure App Service) 24 | # server: 25 | # forward-headers-strategy: native 26 | # tomcat: 27 | # remoteip: 28 | # protocol-header: "X-Forwarded-Proto" 29 | # remote-ip-header: "X-Forwarded-For" 30 | # internal-proxies: ".*" -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/1-Authentication/sign-in/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/static/style.css: -------------------------------------------------------------------------------- 1 | .body-content { 2 | padding-top: 15px; 3 | padding-bottom: 15px; 4 | padding-left: 15px; 5 | padding-right: 15px; 6 | } 7 | 8 | .dl-horizontal dt { 9 | white-space: normal; 10 | } 11 | 12 | .flashToast { 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | } 17 | 18 | 19 | .card { 20 | width: 50vw; 21 | margin:auto; 22 | background:#f0f0f0; 23 | border:1px solid black; 24 | } 25 | 26 | .card-header { 27 | /* background: darkseagreen; */ 28 | color: rgba(255,255,255,0.85); 29 | background: #0078d4; 30 | font-weight: 300; 31 | } 32 | 33 | .card-text { 34 | align-content: center 35 | } 36 | 37 | #wrapper { 38 | display: flex; 39 | } 40 | 41 | #left { 42 | flex: content; 43 | margin-right: 0.5em; 44 | 45 | } 46 | 47 | #right { 48 | flex: 1; 49 | } 50 | 51 | #footer { 52 | width: 50vw; 53 | margin: auto; 54 | text-align: left; 55 | margin-top: 1em; 56 | } 57 | 58 | .smiley, .frowny { 59 | height: 1.5em; 60 | width: 1.5em; 61 | margin: auto; 62 | fill: #0078d4 63 | } 64 | 65 | .smiley:hover, .frowny:hover{ 66 | height: 1.5em; 67 | width: 1.5em; 68 | margin: auto; 69 | fill: white; 70 | border: 1px solid #0078d4; 71 | background-color: #0078d4; 72 | border-radius: 50%; 73 | } 74 | 75 | #check-icon { 76 | height: 1.25em; 77 | width: 1.25em; 78 | margin: auto; 79 | fill: green; 80 | } 81 | 82 | a.nostyle:link { 83 | text-decoration: inherit; 84 | color: inherit; 85 | } 86 | 87 | a.nostyle:visited { 88 | text-decoration: inherit; 89 | color: inherit; 90 | } -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Authentication: Use Active Directory Spring Boot Starter to sign in users 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/content/401.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 401: Unauthorized 5 |
6 |
7 |

8 | Visiting this page requires you to be authenticated. Use the button on the top right to sign in. 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/content/500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 500: Auth Error 5 |
6 |
7 |

8 | ${details}
9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/content/graph.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Call Graph /me Endpoint 4 |
5 |
6 |

7 | 8 | : 9 | 10 |
11 |
12 |
13 | Sign-in Status 14 | Token Details 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/content/status.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | You're signed in! 5 |
6 |
7 | You're not signed in. 8 |
9 |
10 |
11 |

12 |

13 | ID Token Details 14 |
15 |
16 | Use the button on the top right to sign in. 17 | Attempts to go to a protected page, such as the ID Token Details page will result in automatic redirection to Microsoft identity platform sign in page. 18 |
19 |

20 |
21 |
22 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/content/survey.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Tell us how we did! 4 |
5 |
6 | Click here if the survey question does not load automatically. 7 |

8 | 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/content/token.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | ID Token Details 4 |
5 |
6 |

7 | The following is a limited subset of some important claims in your ID Token. 8 |
9 | 10 | : 11 | 12 |
13 |
14 |
15 | Sign-in Status 16 |

17 |
18 |
19 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |  Have you updated your app's redirect URI on Azure Portal? 6 |
7 | Redirect URI: 8 | 9 |
10 |
11 | 12 | 13 | 14 |   Does this sample address your learning objective? 15 | 16 |
17 |

18 |

© 2021

19 |

-------------------------------------------------------------------------------- /1-Authentication/sign-in/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /1-Authentication/sign-in/src/test/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MsIdentitySpringBootWebappApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1616631328111 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/AppCreationScripts/Cleanup.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [PSCredential] $Credential, 4 | [Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')] 5 | [string] $tenantId, 6 | [Parameter(Mandatory=$False, HelpMessage='Azure environment to use while running the script (it defaults to AzureCloud)')] 7 | [string] $azureEnvironmentName 8 | ) 9 | 10 | #Requires -Modules AzureAD -RunAsAdministrator 11 | 12 | 13 | 14 | if ($null -eq (Get-Module -ListAvailable -Name "AzureAD")) { 15 | Install-Module "AzureAD" -Scope CurrentUser 16 | } 17 | Import-Module AzureAD 18 | $ErrorActionPreference = "Stop" 19 | 20 | Function Cleanup 21 | { 22 | if (!$azureEnvironmentName) 23 | { 24 | $azureEnvironmentName = "AzureCloud" 25 | } 26 | 27 | <# 28 | .Description 29 | This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script 30 | #> 31 | 32 | # $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant 33 | # into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD. 34 | 35 | # Login to Azure PowerShell (interactive if credentials are not already provided: 36 | # you'll need to sign-in with creds enabling your to create apps in the tenant) 37 | if (!$Credential -and $TenantId) 38 | { 39 | $creds = Connect-AzureAD -TenantId $tenantId -AzureEnvironmentName $azureEnvironmentName 40 | } 41 | else 42 | { 43 | if (!$TenantId) 44 | { 45 | $creds = Connect-AzureAD -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 46 | } 47 | else 48 | { 49 | $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 50 | } 51 | } 52 | 53 | if (!$tenantId) 54 | { 55 | $tenantId = $creds.Tenant.Id 56 | } 57 | $tenant = Get-AzureADTenantDetail 58 | $tenantName = ($tenant.VerifiedDomains | Where-Object { $_._Default -eq $True }).Name 59 | 60 | # Removes the applications 61 | Write-Host "Cleaning-up applications from tenant '$tenantName'" 62 | 63 | 64 | Write-Host "Removing 'webApp' (java-spring-webapp-call-graph) if needed" 65 | Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-call-graph'" | ForEach-Object {Remove-AzureADApplication -ObjectId $_.ObjectId } 66 | $apps = Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-call-graph'" 67 | if ($apps) 68 | { 69 | Remove-AzureADApplication -ObjectId $apps.ObjectId 70 | } 71 | 72 | foreach ($app in $apps) 73 | { 74 | Remove-AzureADApplication -ObjectId $app.ObjectId 75 | Write-Host "Removed java-spring-webapp-call-graph.." 76 | } 77 | # also remove service principals of this app 78 | Get-AzureADServicePrincipal -filter "DisplayName eq 'java-spring-webapp-call-graph'" | ForEach-Object {Remove-AzureADServicePrincipal -ObjectId $_.Id -Confirm:$false} 79 | 80 | 81 | } 82 | 83 | Cleanup -Credential $Credential -tenantId $TenantId -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/AppCreationScripts/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sample": { 3 | "Title": "Enable your Java Spring Boot web app to sign in users and call Microsoft Graph with the Microsoft identity platform", 4 | "Level": 100, 5 | "Client": "Java Spring Boot web app", 6 | "RepositoryUrl": "ms-identity-java-spring-tutorial", 7 | "Endpoint": "AAD v2.0" 8 | }, 9 | "AADApps": [ 10 | { 11 | "Id": "webApp", 12 | "Name": "java-spring-webapp-call-graph", 13 | "Kind": "WebApp", 14 | "Audience": "AzureADMyOrg", 15 | "PasswordCredentials": "Auto", 16 | "AllowImplicitFlow": false, 17 | "HomePage": "http://localhost:8080/", 18 | "ReplyUrls": "http://localhost:8080/login/oauth2/code/", 19 | "RequiredResourcesAccess": [ 20 | { 21 | "Resource": "Microsoft Graph", 22 | "DelegatedPermissions": [ 23 | "User.Read" 24 | ] 25 | } 26 | ] 27 | } 28 | ], 29 | "CodeConfiguration": [ 30 | { 31 | "App": "webApp", 32 | "SettingKind": "Replace", 33 | "SettingFile": "\\..\\src\\main\\resources\\application.yml", 34 | "Mappings": [ 35 | { 36 | "key": "Enter_Your_Tenant_ID_Here", 37 | "value": "$tenantId" 38 | }, 39 | { 40 | "key": "Enter_Your_Client_ID_Here", 41 | "value": "webApp.AppId" 42 | }, 43 | { 44 | "key": "Enter_Your_Client_Secret_Here", 45 | "value": ".AppKey" 46 | } 47 | ] 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/ReadmeFiles/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/2-Authorization-I/call-graph/ReadmeFiles/app.png -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/2-Authorization-I/call-graph/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | 12 | com.microsoft.azuresamples.msal4j 13 | ms-identity-spring-boot-webapp 14 | 0.0.1-SNAPSHOT 15 | ms-identity-spring-boot-webapp 16 | Microsoft identity platform Spring Boot sample 17 | 18 | 11 19 | 3.9.0 20 | 21 | 22 | 23 | 24 | com.azure.spring 25 | azure-spring-boot-starter-active-directory 26 | ${azure.version} 27 | 28 | 29 | 30 | com.microsoft.graph 31 | microsoft-graph 32 | 5.5.0 33 | 34 | 35 | 36 | com.google.guava 37 | guava 38 | 31.0.1-jre 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-oauth2-client 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-web 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-thymeleaf 54 | 55 | 56 | 57 | org.thymeleaf.extras 58 | thymeleaf-extras-springsecurity5 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-test 63 | test 64 | 65 | 66 | org.junit.vintage 67 | junit-vintage-engine 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.springframework.boot 76 | spring-boot-maven-plugin 77 | 78 | 79 | 80 | repackage 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplication.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebappApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebappApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import com.azure.spring.aad.webapp.AADWebSecurityConfigurerAdapter; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | 13 | /** 14 | * AADWebSecurityConfigurer (AADWSC) is an extension of Spring's WebSecurityConfigurer (WSC). 15 | * 16 | * You must extend AADWSC to define your own custom configuration in the configure() method. 17 | * Be sure to call super.configure() first. This will set up all of your AuthN/AuthZ properly. 18 | * 19 | * You may omit this by not extending the AADWSC class. 20 | * 21 | * If you don't extend AADWSC or WSC, AAD boot starter will create a DefaultAADWebSecurityConfigurerAdapter 22 | * bean automatically, and define its own default http.authorizeRequests() rule (authorize ALL requests). 23 | * 24 | * See DefaultAADWebSecurityConfigurerAdapter in com.azure.spring.aad.webapp.AADWebAppConfiguration 25 | */ 26 | 27 | @EnableWebSecurity 28 | @EnableGlobalMethodSecurity(prePostEnabled = true) 29 | public class SecurityConfig extends AADWebSecurityConfigurerAdapter{ 30 | @Value( "${app.protect.authenticated}" ) 31 | private String[] protectedRoutes; 32 | 33 | @Override 34 | public void configure(HttpSecurity http) throws Exception { 35 | // use required configuration from AADWebSecurityAdapter.configure: 36 | super.configure(http); 37 | // add custom configuration: 38 | http.authorizeRequests() 39 | .antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details, /call_graph) 40 | .antMatchers("/**").permitAll(); // allow all other routes. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | {"properties": [ 2 | { 3 | "name": "app.ui.base", 4 | "type": "java.lang.String", 5 | "description": "the base UI template page name in src/main/webapp" 6 | }, 7 | { 8 | "name": "app.ui.content", 9 | "type": "java.lang.String", 10 | "description": "content with which to populate app.ui.base, also located in same folder." 11 | }, 12 | { 13 | "name": "app.protect.authenticated", 14 | "type": "java.lang.String[]", 15 | "description": "limit these pages to authenticated users. Use '=/route1' for a single route. Use '=/route1, /route2' for multiple." 16 | } 17 | ]} -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | activedirectory: 3 | # Specifies your Active Directory ID: 4 | tenant-id: Enter_Your_Tenant_ID_Here 5 | # Specifies your App Registration's Application ID: 6 | client-id: Enter_Your_Client_ID_Here 7 | # Specifies your App Registration's secret key: 8 | client-secret: Enter_Your_Client_Secret_Here 9 | # Specifies the post-log-out-redirect-uri, where to return your app after logout. 10 | post-logout-redirect-uri: http://localhost:8080 11 | authorization-clients: 12 | graph: 13 | # Specifies the Microsoft Graph scopes that your app needs access to: 14 | scopes: https://graph.microsoft.com/User.Read 15 | 16 | # which routes to restrict to authenticated users only (see SecurityConfig.java): 17 | # enter String array (comma-separated) or just one route. 18 | # e.g. app.protect.authenticated=/route1, /route2, /route3 19 | app: 20 | protect: 21 | authenticated: /token_details, /call_graph 22 | 23 | # un-comment the following lines if you are deploying to a reverse proxy (e.g. Azure App Service) 24 | # server: 25 | # forward-headers-strategy: native 26 | # tomcat: 27 | # remoteip: 28 | # protocol-header: "X-Forwarded-Proto" 29 | # remote-ip-header: "X-Forwarded-For" 30 | # internal-proxies: ".*" -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/2-Authorization-I/call-graph/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/static/style.css: -------------------------------------------------------------------------------- 1 | .body-content { 2 | padding-top: 15px; 3 | padding-bottom: 15px; 4 | padding-left: 15px; 5 | padding-right: 15px; 6 | } 7 | 8 | .dl-horizontal dt { 9 | white-space: normal; 10 | } 11 | 12 | .flashToast { 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | } 17 | 18 | 19 | .card { 20 | width: 50vw; 21 | margin:auto; 22 | background:#f0f0f0; 23 | border:1px solid black; 24 | } 25 | 26 | .card-header { 27 | /* background: darkseagreen; */ 28 | color: rgba(255,255,255,0.85); 29 | background: #0078d4; 30 | font-weight: 300; 31 | } 32 | 33 | .card-text { 34 | align-content: center 35 | } 36 | 37 | #wrapper { 38 | display: flex; 39 | } 40 | 41 | #left { 42 | flex: content; 43 | margin-right: 0.5em; 44 | 45 | } 46 | 47 | #right { 48 | flex: 1; 49 | } 50 | 51 | #footer { 52 | width: 50vw; 53 | margin: auto; 54 | text-align: left; 55 | margin-top: 1em; 56 | } 57 | 58 | .smiley, .frowny { 59 | height: 1.5em; 60 | width: 1.5em; 61 | margin: auto; 62 | fill: #0078d4 63 | } 64 | 65 | .smiley:hover, .frowny:hover{ 66 | height: 1.5em; 67 | width: 1.5em; 68 | margin: auto; 69 | fill: white; 70 | border: 1px solid #0078d4; 71 | background-color: #0078d4; 72 | border-radius: 50%; 73 | } 74 | 75 | #check-icon { 76 | height: 1.25em; 77 | width: 1.25em; 78 | margin: auto; 79 | fill: green; 80 | } 81 | 82 | a.nostyle:link { 83 | text-decoration: inherit; 84 | color: inherit; 85 | } 86 | 87 | a.nostyle:visited { 88 | text-decoration: inherit; 89 | color: inherit; 90 | } -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Authorization-I: Use Active Directory Spring Boot Starter to sign in and call MS Graph 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/content/401.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 401: Unauthorized 5 |
6 |
7 |

8 | Visiting this page requires you to be authenticated. Use the button on the top right to sign in. 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/content/500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 500: Auth Error 5 |
6 |
7 |

8 | ${details}
9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/content/graph.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Call Graph /me Endpoint 4 |
5 |
6 |

7 | 8 | : 9 | 10 |
11 |
12 |
13 | Sign-in Status 14 | Token Details 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/content/status.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | You're signed in! 5 |
6 |
7 | You're not signed in. 8 |
9 |
10 |
11 |

12 |

13 | ID Token Details 14 | Call Graph 15 |
16 |
17 | Use the button on the top right to sign in. 18 | Attempts to go to a protected page, such as the ID Token Details page or Call Graph page will result in automatic redirection to Microsoft identity platform sign in page. 19 |
20 |

21 |
22 |
23 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/content/survey.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Tell us how we did! 4 |
5 |
6 | Click here if the survey question does not load automatically. 7 |

8 | 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/content/token.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | ID Token Details 4 |
5 |
6 |

7 | The following is a limited subset of some important claims in your ID Token. 8 |
9 | 10 | : 11 | 12 |
13 |
14 |
15 | Sign-in Status 16 | Call Graph 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |  Have you updated your app's redirect URI on Azure Portal? 5 |
6 | Redirect URI: 7 | 8 |
9 |
10 | 11 | 12 | 13 |   Does this sample address your learning objective? 14 | 15 |
16 |

17 |

© 2021

18 |

-------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2-Authorization-I/call-graph/src/test/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MsIdentitySpringBootWebappApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.m2e.core.maven2Builder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Nature 16 | 17 | 18 | 19 | 1616698377300 20 | 21 | 30 22 | 23 | org.eclipse.core.resources.regexFilterMatcher 24 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/AppCreationScripts/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sample": { 3 | "Title": "Enable your Java Spring boot web app to restrict access to routes using security groups with the Microsoft identity platform", 4 | "Level": 100, 5 | "Client": "Java Spring Boot web app", 6 | "RepositoryUrl": "ms-identity-java-spring-tutorial", 7 | "Endpoint": "AAD v2.0" 8 | }, 9 | "AADApps": [ 10 | { 11 | "Id": "webApp", 12 | "Name": "java-spring-webapp-groups", 13 | "Kind": "WebApp", 14 | "Audience": "AzureADMyOrg", 15 | "PasswordCredentials": "Auto", 16 | "AllowImplicitFlow": false, 17 | "HomePage": "http://localhost:8080/", 18 | "ReplyUrls": "http://localhost:8080/login/oauth2/code/", 19 | "GroupMembershipClaims": "SecurityGroup", 20 | "RequiredResourcesAccess": [ 21 | { 22 | "Resource": "Microsoft Graph", 23 | "DelegatedPermissions": [ 24 | "GroupMember.Read.All" 25 | ] 26 | } 27 | ], 28 | "SecurityGroups": [ 29 | { 30 | "Name": "AdminGroup", 31 | "Description": "Admin Security Group" 32 | }, 33 | { 34 | "Name": "UserGroup", 35 | "Description": "User Security Group" 36 | } 37 | ], 38 | "ManualSteps": [ 39 | { 40 | "Comment": "Navigate to the API Permissions blade of your app in the Azure portal, and grant admin consent to GroupMember.Read.All." 41 | } 42 | ] 43 | } 44 | ], 45 | "CodeConfiguration": [ 46 | { 47 | "App": "webApp", 48 | "SettingKind": "Replace", 49 | "SettingFile": "\\..\\src\\main\\resources\\application.yml", 50 | "Mappings": [ 51 | { 52 | "key": "Enter_Your_Tenant_ID_Here", 53 | "value": "$tenantId" 54 | }, 55 | { 56 | "key": "Enter_Your_Client_ID_Here", 57 | "value": "webApp.AppId" 58 | }, 59 | { 60 | "key": "Enter_Your_Client_Secret_Here", 61 | "value": ".AppKey" 62 | }, 63 | { 64 | "key": "Enter_Your_Admin_Group_ID_Here", 65 | "value": "$AdminGroup.objectId" 66 | }, 67 | { 68 | "key": "Enter_Your_User_Group_ID_Here", 69 | "value": "$UserGroup.objectId" 70 | } 71 | ] 72 | }, 73 | { 74 | "App": "webApp", 75 | "SettingKind": "Replace", 76 | "SettingFile": "\\..\\src\\main\\java\\com\\microsoft\\azuresamples\\msal4j\\msidentityspringbootwebapp\\SampleController.java", 77 | "Mappings": [ 78 | { 79 | "key": "Enter_Your_Admin_Group_ID_Here", 80 | "value": "$AdminGroup.objectId" 81 | }, 82 | { 83 | "key": "Enter_Your_User_Group_ID_Here", 84 | "value": "$UserGroup.objectId" 85 | } 86 | ] 87 | } 88 | ] 89 | } -------------------------------------------------------------------------------- /3-Authorization-II/groups/ReadmeFiles/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/groups/ReadmeFiles/app.png -------------------------------------------------------------------------------- /3-Authorization-II/groups/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/groups/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /3-Authorization-II/groups/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | 12 | com.microsoft.azuresamples.msal4j 13 | ms-identity-spring-boot-webapp 14 | 0.0.1-SNAPSHOT 15 | ms-identity-spring-boot-webapp 16 | Microsoft identity platform Spring Boot sample 17 | 18 | 11 19 | 3.9.0 20 | 21 | 22 | 23 | 24 | com.azure.spring 25 | azure-spring-boot-starter-active-directory 26 | ${azure.version} 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-oauth2-client 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-thymeleaf 41 | 42 | 43 | org.thymeleaf.extras 44 | thymeleaf-extras-springsecurity5 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | org.junit.vintage 53 | junit-vintage-engine 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | repackage 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplication.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebappApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebappApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import com.azure.spring.aad.webapp.AADWebSecurityConfigurerAdapter; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | 13 | /** 14 | * AADWebSecurityConfigurer (AADWSC) is an extension of Spring's WebSecurityConfigurer (WSC). 15 | * 16 | * You must extend AADWSC to define your own custom configuration in the configure() method. 17 | * Be sure to call super.configure() first. This will set up all of your AuthN/AuthZ properly. 18 | * 19 | * You may omit this by not extending the AADWSC class. 20 | * 21 | * If you don't extend AADWSC or WSC, AAD boot starter will create a DefaultAADWebSecurityConfigurerAdapter 22 | * bean automatically, and define its own default http.authorizeRequests() rule (authorize ALL requests). 23 | * 24 | * See DefaultAADWebSecurityConfigurerAdapter in com.azure.spring.aad.webapp.AADWebAppConfiguration 25 | */ 26 | 27 | @EnableWebSecurity 28 | @EnableGlobalMethodSecurity(prePostEnabled = true) 29 | public class SecurityConfig extends AADWebSecurityConfigurerAdapter{ 30 | @Value( "${app.protect.authenticated}" ) 31 | private String[] protectedRoutes; 32 | 33 | @Override 34 | public void configure(HttpSecurity http) throws Exception { 35 | // use required configuration from AADWebSecurityAdapter.configure: 36 | super.configure(http); 37 | // add custom configuration: 38 | http.authorizeRequests() 39 | .antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details, /admin_only, /regular_user) 40 | .antMatchers("/**").permitAll(); // allow all other routes. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/Utilities.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import java.util.Arrays; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 11 | 12 | public class Utilities { 13 | private Utilities() { 14 | throw new IllegalStateException("Utility class. Don't instantiate"); 15 | } 16 | 17 | /** 18 | * Take a subset of ID Token claims and put them into KV pairs for UI to 19 | * display. 20 | * 21 | * @param principal OidcUser (see SampleController for details) 22 | * @return Map of filteredClaims 23 | */ 24 | public static Map filterClaims(OidcUser principal) { 25 | final String[] claimKeys = { "sub", "aud", "ver", "iss", "name", "oid", "preferred_username", "groups" }; 26 | final List includeClaims = Arrays.asList(claimKeys); 27 | 28 | Map filteredClaims = new HashMap<>(); 29 | includeClaims.forEach(claim -> { 30 | if (principal.getIdToken().getClaims().containsKey(claim)) { 31 | filteredClaims.put(claim, principal.getIdToken().getClaims().get(claim).toString()); 32 | } else { 33 | filteredClaims.put(claim, "This claim was not found in ID Token."); 34 | } 35 | }); 36 | return filteredClaims; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | {"properties": [ 2 | { 3 | "name": "app.ui.base", 4 | "type": "java.lang.String", 5 | "description": "the base UI template page name in src/main/webapp" 6 | }, 7 | { 8 | "name": "app.ui.content", 9 | "type": "java.lang.String", 10 | "description": "content with which to populate app.ui.base, also located in same folder." 11 | }, 12 | { 13 | "name": "app.protect.authenticated", 14 | "type": "java.lang.String[]", 15 | "description": "limit these pages to authenticated users. Use '=/route1' for a single route. Use '=/route1, /route2' for multiple." 16 | } 17 | ]} -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | activedirectory: 3 | # Specifies your Active Directory ID: 4 | tenant-id: Enter_Your_Tenant_ID_Here 5 | # Specifies your App Registration's Application ID: 6 | client-id: Enter_Your_Client_ID_Here 7 | # Specifies your App Registration's secret key: 8 | client-secret: Enter_Your_Client_Secret_Here 9 | # Specifies the post-log-out-redirect-uri, where to return your app after logout. 10 | post-logout-redirect-uri: http://localhost:8080 11 | # Groups - this enables the getting the full set of groups in Authorities. 12 | user-group: 13 | allowed-group-ids: Enter_Your_Admin_Group_ID_Here, Enter_Your_User_Group_ID_Here 14 | enable-full-list: true 15 | # Specifies the Microsoft Graph scopes that your app needs access to - required in this app in case of too many groups to fit in token (overage) 16 | # authorization-clients: 17 | graph: 18 | scopes: https://graph.microsoft.com/User.Read, https://graph.microsoft.com/GroupMember.Read.All 19 | 20 | # which routes to restrict to authenticated users only (see SecurityConfig.java): 21 | # enter String array (comma-separated) or just one route. 22 | # e.g. authenticated: /route1, /route2, /route3 23 | app: 24 | protect: 25 | authenticated: /token_details, /admin_only, /regular_user 26 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/groups/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/static/style.css: -------------------------------------------------------------------------------- 1 | .body-content { 2 | padding-top: 15px; 3 | padding-bottom: 15px; 4 | padding-left: 15px; 5 | padding-right: 15px; 6 | } 7 | 8 | .dl-horizontal dt { 9 | white-space: normal; 10 | } 11 | 12 | .flashToast { 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | } 17 | 18 | 19 | .card { 20 | width: 50vw; 21 | margin:auto; 22 | background:#f0f0f0; 23 | border:1px solid black; 24 | } 25 | 26 | .card-header { 27 | /* background: darkseagreen; */ 28 | color: rgba(255,255,255,0.85); 29 | background: #0078d4; 30 | font-weight: 300; 31 | } 32 | 33 | .card-text { 34 | align-content: center 35 | } 36 | 37 | #wrapper { 38 | display: flex; 39 | } 40 | 41 | #left { 42 | flex: content; 43 | margin-right: 0.5em; 44 | 45 | } 46 | 47 | #right { 48 | flex: 1; 49 | } 50 | 51 | #footer { 52 | width: 50vw; 53 | margin: auto; 54 | text-align: left; 55 | margin-top: 1em; 56 | } 57 | 58 | .smiley, .frowny { 59 | height: 1.5em; 60 | width: 1.5em; 61 | margin: auto; 62 | fill: #0078d4 63 | } 64 | 65 | .smiley:hover, .frowny:hover{ 66 | height: 1.5em; 67 | width: 1.5em; 68 | margin: auto; 69 | fill: white; 70 | border: 1px solid #0078d4; 71 | background-color: #0078d4; 72 | border-radius: 50%; 73 | } 74 | 75 | #check-icon { 76 | height: 1.25em; 77 | width: 1.25em; 78 | margin: auto; 79 | fill: green; 80 | } 81 | 82 | a.nostyle:link { 83 | text-decoration: inherit; 84 | color: inherit; 85 | } 86 | 87 | a.nostyle:visited { 88 | text-decoration: inherit; 89 | color: inherit; 90 | } -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Authorization II: Use Active Directory Spring Boot Starter to control access by Security Groups 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/401.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 401: Unauthorized 5 |
6 |
7 |

8 | Visiting this page requires you to be authenticated. Use the button on the top right to sign in. 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/403.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 403: Forbidden 4 |
5 |
6 |

7 | Sorry! you are not a member of the security group(s) that are allowed to visit this page. 8 |
9 | This page requires one of the following groups: 10 |

11 | Sign-in Status 12 | ID Token Details 13 | Admins Only 14 | Regular Users 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 500: Auth Error 5 |
6 |
7 |

8 | ${details}
9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/graph.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Call Graph /me Endpoint 4 |
5 |
6 |

7 | 8 | : 9 | 10 |
11 |
12 |
13 | Sign-in Status 14 | Token Details 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/group.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | You are authorized! 4 |
5 |
6 |

7 | Excellent! You are a member of the security group(s) that are allowed to visit this page! 8 |
9 | This page requires one of the following roles: 10 | 11 | 12 |

13 | Sign-in Status 14 | ID Token Details 15 | Admins Only 16 | Regular Users 17 |

18 |
19 |
-------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/status.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | You're signed in! 5 |
6 |
7 | You're not signed in. 8 |
9 |
10 |
11 |

12 |

18 |
19 | Use the button on the top right to sign in. 20 | Attempts to go to one of the protected pages below will result in automatic redirection to Microsoft identity platform sign in endpoint. 21 |
22 | Sign-in Status 23 | ID Token Details 24 | Admins Only 25 | Regular Users 26 |
27 |

28 |
29 |
30 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/survey.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Tell us how we did! 4 |
5 |
6 | Click here if the survey question does not load automatically. 7 |

8 | 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/content/token.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | ID Token Details 4 |
5 |
6 |

7 | The following is a limited subset of some important claims in your ID Token. 8 |
9 | 10 | : 11 | 12 |
13 |
14 |
15 | Sign-in Status 16 | ID Token Details 17 | Admins Only 18 | Regular Users 19 |

20 |
21 |
22 | -------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |  Have you updated your app's redirect URI on Azure Portal? 6 |
7 | Redirect URI: 8 | 9 |
10 |
11 | 12 | 13 | 14 |   Does this sample address your learning objective? 15 | 16 |
17 |

18 |

© 2021

19 |

-------------------------------------------------------------------------------- /3-Authorization-II/groups/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/AppCreationScripts/Cleanup.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [CmdletBinding()] 7 | param( 8 | [PSCredential] $Credential, 9 | [Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')] 10 | [string] $tenantId, 11 | [Parameter(Mandatory=$False, HelpMessage='Azure environment to use while running the script (it defaults to AzureCloud)')] 12 | [string] $azureEnvironmentName 13 | ) 14 | 15 | #Requires -Modules AzureAD -RunAsAdministrator 16 | 17 | 18 | 19 | if ($null -eq (Get-Module -ListAvailable -Name "AzureAD")) { 20 | Install-Module "AzureAD" -Scope CurrentUser 21 | } 22 | Import-Module AzureAD 23 | $ErrorActionPreference = "Stop" 24 | 25 | Function Cleanup 26 | { 27 | if (!$azureEnvironmentName) 28 | { 29 | $azureEnvironmentName = "AzureCloud" 30 | } 31 | 32 | <# 33 | .Description 34 | This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script 35 | #> 36 | 37 | # $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant 38 | # into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD. 39 | 40 | # Login to Azure PowerShell (interactive if credentials are not already provided: 41 | # you'll need to sign-in with creds enabling your to create apps in the tenant) 42 | if (!$Credential -and $TenantId) 43 | { 44 | $creds = Connect-AzureAD -TenantId $tenantId -AzureEnvironmentName $azureEnvironmentName 45 | } 46 | else 47 | { 48 | if (!$TenantId) 49 | { 50 | $creds = Connect-AzureAD -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 51 | } 52 | else 53 | { 54 | $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 55 | } 56 | } 57 | 58 | if (!$tenantId) 59 | { 60 | $tenantId = $creds.Tenant.Id 61 | } 62 | $tenant = Get-AzureADTenantDetail 63 | $tenantName = ($tenant.VerifiedDomains | Where-Object { $_._Default -eq $True }).Name 64 | 65 | # Removes the applications 66 | Write-Host "Cleaning-up applications from tenant '$tenantName'" 67 | 68 | 69 | Write-Host "Removing 'webApp' (java-spring-webapp-auth) if needed" 70 | Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-auth'" | ForEach-Object {Remove-AzureADApplication -ObjectId $_.ObjectId } 71 | $apps = Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-auth'" 72 | if ($apps) 73 | { 74 | Remove-AzureADApplication -ObjectId $apps.ObjectId 75 | } 76 | 77 | foreach ($app in $apps) 78 | { 79 | Remove-AzureADApplication -ObjectId $app.ObjectId 80 | Write-Host "Removed java-spring-webapp-auth.." 81 | } 82 | # also remove service principals of this app 83 | Get-AzureADServicePrincipal -filter "DisplayName eq 'java-spring-webapp-auth'" | ForEach-Object {Remove-AzureADServicePrincipal -ObjectId $_.Id -Confirm:$false} 84 | 85 | 86 | } 87 | 88 | Cleanup -Credential $Credential -tenantId $TenantId -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/AppCreationScripts/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sample": { 3 | "Title": "Enable your Java Spring Boot web app to sign in users on your Azure Active Directory tenant with the Microsoft identity platform", 4 | "Level": 100, 5 | "Client": "Java Spring Boot web app", 6 | "RepositoryUrl": "ms-identity-java-spring-tutorial", 7 | "Endpoint": "AAD v2.0" 8 | }, 9 | "AADApps": [ 10 | { 11 | "Id": "webApp", 12 | "Name": "java-spring-webapp-auth", 13 | "Kind": "WebApp", 14 | "Audience": "AzureADMyOrg", 15 | "PasswordCredentials": "Auto", 16 | "AllowImplicitFlow": false, 17 | "HomePage": "http://localhost:8080/", 18 | "ReplyUrls": "http://localhost:8080/login/oauth2/code/", 19 | "RequiredResourcesAccess": [] 20 | } 21 | ], 22 | "CodeConfiguration": [ 23 | { 24 | "App": "webApp", 25 | "SettingKind": "Replace", 26 | "SettingFile": "\\..\\src\\main\\resources\\application.yml", 27 | "Mappings": [ 28 | { 29 | "key": "Enter_Your_Tenant_ID_Here", 30 | "value": "$tenantId" 31 | }, 32 | { 33 | "key": "Enter_Your_Client_ID_Here", 34 | "value": "webApp.AppId" 35 | }, 36 | { 37 | "key": "Enter_Your_Client_Secret_Here", 38 | "value": ".AppKey" 39 | } 40 | ] 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/ReadmeFiles/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/protect-web-api/ReadmeFiles/app.png -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/protect-web-api/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | .vscode/ 26 | .settings/ 27 | .DS_Store 28 | target/ 29 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1615934394943 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.5.6 10 | 11 | 12 | com.azure.spring 13 | azure-spring-boot-sample-active-directory-resource-server 14 | 1.0.0 15 | jar 16 | 17 | 18 | 19 | 20 | com.azure 21 | azure-core 22 | 1.21.0 23 | 24 | 25 | 26 | 27 | 28 | 29 | com.azure.spring 30 | azure-spring-boot-starter-active-directory 31 | 3.9.0 32 | 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-oauth2-resource-server 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-web 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-maven-plugin 49 | 50 | 51 | 52 | repackage 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapi/MsIdentitySpringBootWebApi.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapi; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebApi { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebApi.class, args); 13 | } 14 | } -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapi/SampleController.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapi; 5 | 6 | import java.util.Date; 7 | 8 | import org.springframework.security.access.prepost.PreAuthorize; 9 | // import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; 10 | // import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | @RestController 16 | public class SampleController { 17 | 18 | @GetMapping("/api/date") 19 | @ResponseBody 20 | @PreAuthorize("hasAuthority('SCOPE_access_as_user')") 21 | public String date(/**BearerTokenAuthentication bearerTokenAuth*/) { 22 | /** 23 | //uncomment the parameter in the function params above and the line below to get access to the principal. 24 | OAuth2AuthenticatedPrincipal principal = (OAuth2AuthenticatedPrincipal) bearerTokenAuth.getPrincipal(); 25 | // You can then access attributes of the principal, e.g., attributes (claims), the raw tokenValue, and authorities. 26 | // For example: 27 | principal.getAttribute("scp"); 28 | */ 29 | return new DateResponse().toString(); 30 | } 31 | 32 | private class DateResponse { 33 | private String humanReadable; 34 | private String timeStamp; 35 | 36 | public DateResponse() { 37 | Date now = new Date(); 38 | this.humanReadable = now.toString(); 39 | this.timeStamp = Long.toString(now.getTime()); 40 | } 41 | 42 | public String toString() { 43 | return String.format("{\"humanReadable\": \"%s\", \"timeStamp\": \"%s\"}", humanReadable, timeStamp); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapi/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapi; 5 | 6 | import com.azure.spring.aad.webapi.AADResourceServerWebSecurityConfigurerAdapter; 7 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | 11 | @EnableWebSecurity 12 | @EnableGlobalMethodSecurity(prePostEnabled = true) 13 | public class SecurityConfig extends AADResourceServerWebSecurityConfigurerAdapter { 14 | /** 15 | * Add configuration logic as needed. 16 | */ 17 | @Override 18 | protected void configure(HttpSecurity http) throws Exception { 19 | super.configure(http); 20 | http.authorizeRequests((requests) -> requests.anyRequest().authenticated()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/resource-api/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # If we configure the azure.activedirectory.client-id or azure.activedirectory.app-id-uri will be to check the audience. 2 | # In v2.0 tokens, this is always the client ID of the API, while in v1.0 tokens it can be the client ID or the resource URI used in the request. 3 | # If you are using v1.0 tokens, configure both to properly complete the audience validation. 4 | 5 | server: 6 | port: 8082 7 | 8 | azure: 9 | activedirectory: 10 | client-id: Enter_Your_Client_ID_Here 11 | app-id-uri: api://Enter_Your_Client_ID_Here -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | .vscode/ 26 | .settings/ 27 | .DS_Store 28 | target/ 29 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1615934394943 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | 12 | com.microsoft.azuresamples.msal4j 13 | ms-identity-spring-boot-webapp 14 | 0.0.1-SNAPSHOT 15 | ms-identity-spring-boot-webapp 16 | Microsoft identity platform Spring Boot sample 17 | 18 | 11 19 | 3.9.0 20 | 21 | 22 | 23 | 24 | com.azure.spring 25 | azure-spring-boot-starter-active-directory 26 | ${azure.version} 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-oauth2-client 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-thymeleaf 41 | 42 | 43 | org.thymeleaf.extras 44 | thymeleaf-extras-springsecurity5 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | repackage 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplication.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebappApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebappApplication.class, args); 13 | } 14 | } -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import com.azure.spring.aad.webapp.AADWebSecurityConfigurerAdapter; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | 13 | /** 14 | * AADWebSecurityConfigurer (AADWSC) is an extension of Spring's WebSecurityConfigurer (WSC). 15 | * 16 | * You must extend AADWSC to define your own custom configuration in the configure() method. 17 | * Be sure to call super.configure() first. This will set up all of your AuthN/AuthZ properly. 18 | * 19 | * You may omit this by not extending the AADWSC class. 20 | * 21 | * If you don't extend AADWSC or WSC, AAD boot starter will create a DefaultAADWebSecurityConfigurerAdapter 22 | * bean automatically, and define its own default http.authorizeRequests() rule (authorize ALL requests). 23 | * 24 | * See DefaultAADWebSecurityConfigurerAdapter in com.azure.spring.aad.webapp.AADWebAppConfiguration 25 | */ 26 | 27 | @EnableWebSecurity 28 | @EnableGlobalMethodSecurity(prePostEnabled = true) 29 | public class SecurityConfig extends AADWebSecurityConfigurerAdapter{ 30 | @Value( "${app.protect.authenticated}" ) 31 | private String[] protectedRoutes; 32 | 33 | @Override 34 | public void configure(HttpSecurity http) throws Exception { 35 | // use required configuration from AADWebSecurityAdapter.configure: 36 | super.configure(http); 37 | // add custom configuration: 38 | http.authorizeRequests() 39 | .antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details) 40 | .anyRequest().permitAll() // allow all other routes. 41 | ; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/Utilities.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import java.util.Arrays; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 12 | 13 | public class Utilities { 14 | private Utilities() { 15 | throw new IllegalStateException("Utility class. Don't instantiate"); 16 | } 17 | 18 | /** 19 | * Take a subset of ID Token claims and put them into KV pairs for UI to display. 20 | * @param principal OidcUser (see SampleController for details) 21 | * @return Map of filteredClaims 22 | */ 23 | public static Map filterClaims(OidcUser principal) { 24 | final String[] claimKeys = {"sub", "aud", "ver", "iss", "name", "oid", "preferred_username"}; 25 | final List includeClaims = Arrays.asList(claimKeys); 26 | 27 | Map filteredClaims = new HashMap<>(); 28 | includeClaims.forEach(claim -> { 29 | if (principal.getIdToken().getClaims().containsKey(claim)) { 30 | filteredClaims.put(claim, principal.getIdToken().getClaims().get(claim).toString()); 31 | } 32 | }); 33 | return filteredClaims; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | {"properties": [ 2 | { 3 | "name": "app.protect.authenticated", 4 | "type": "java.lang.String[]", 5 | "description": "limit these pages to authenticated users. Use '=/route1' for a single route. Use '=/route1, /route2' for multiple." 6 | }, 7 | { 8 | "name": "app.api.date-endpoint", 9 | "type": "java.lang.String", 10 | "description": "The get date endpoint on the protected resource API that the app will call." 11 | }, 12 | { 13 | "name": "app.api.base-address", 14 | "type": "java.lang.String", 15 | "description": "The base address of the resource API that the app will call." 16 | } 17 | ]} -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | activedirectory: 3 | # Specifies your Active Directory ID: 4 | tenant-id: Enter_Your_Tenant_ID_Here 5 | # Specifies your App Registration's Application ID: 6 | client-id: Enter_Your_Client_ID_Here 7 | # Specifies your App Registration's secret key: 8 | client-secret: Enter_Your_Client_Secret_Here 9 | # Specifies the post-log-out-redirect-uri, where to return your app after logout. 10 | post-logout-redirect-uri: http://localhost:8080 11 | # Specifies the Microsoft Graph scopes that your app needs access to - not required in this app. 12 | authorization-clients: 13 | web-api: 14 | scopes: api://Enter_Your_WebAPI_Client_ID_Here/access_as_user 15 | 16 | # which routes to restrict to authenticated users only (see SecurityConfig.java): 17 | # enter String array (comma-separated) or just one route. 18 | # e.g. authenticated: /route1, /route2, /route3 19 | app: 20 | protect: 21 | authenticated: /token_details 22 | 23 | # The API to will call, and its endpoint 24 | api: 25 | base-address: http://localhost:8082 26 | date-endpoint: /api/date 27 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/protect-web-api/webapp/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/static/style.css: -------------------------------------------------------------------------------- 1 | .body-content { 2 | padding-top: 15px; 3 | padding-bottom: 15px; 4 | padding-left: 15px; 5 | padding-right: 15px; 6 | } 7 | 8 | .dl-horizontal dt { 9 | white-space: normal; 10 | } 11 | 12 | .flashToast { 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | } 17 | 18 | 19 | .card { 20 | width: 50vw; 21 | margin:auto; 22 | background:#f0f0f0; 23 | border:1px solid black; 24 | } 25 | 26 | .card-header { 27 | /* background: darkseagreen; */ 28 | color: rgba(255,255,255,0.85); 29 | background: #0078d4; 30 | font-weight: 300; 31 | } 32 | 33 | .card-text { 34 | align-content: center 35 | } 36 | 37 | #wrapper { 38 | display: flex; 39 | } 40 | 41 | #left { 42 | flex: content; 43 | margin-right: 0.5em; 44 | 45 | } 46 | 47 | #right { 48 | flex: 1; 49 | } 50 | 51 | #footer { 52 | width: 50vw; 53 | margin: auto; 54 | text-align: left; 55 | margin-top: 1em; 56 | } 57 | 58 | .smiley, .frowny { 59 | height: 1.5em; 60 | width: 1.5em; 61 | margin: auto; 62 | fill: #0078d4 63 | } 64 | 65 | .smiley:hover, .frowny:hover{ 66 | height: 1.5em; 67 | width: 1.5em; 68 | margin: auto; 69 | fill: white; 70 | border: 1px solid #0078d4; 71 | background-color: #0078d4; 72 | border-radius: 50%; 73 | } 74 | 75 | #check-icon { 76 | height: 1.25em; 77 | width: 1.25em; 78 | margin: auto; 79 | fill: green; 80 | } 81 | 82 | a.nostyle:link { 83 | text-decoration: inherit; 84 | color: inherit; 85 | } 86 | 87 | a.nostyle:visited { 88 | text-decoration: inherit; 89 | color: inherit; 90 | } -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Authentication: Use Active Directory Spring Boot Starter to sign in users 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/content/401.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 401: Unauthorized 5 |
6 |
7 |

8 | Visiting this page requires you to be authenticated. Use the button on the top right to sign in. 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/content/500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 500: Auth Error 5 |
6 |
7 |

8 | ${details}
9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/content/api.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Call API: http://localhost:8082/date Endpoint 4 |
5 |
6 |

7 | 8 | : 9 | 10 |
11 |
12 |
13 | Sign-in Status 14 | Token Details 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/content/status.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | You're signed in! 5 |
6 |
7 | You're not signed in. 8 |
9 |
10 |
11 |

12 |

13 | ID Token Details 14 | Call API 15 |
16 |
17 | Use the button on the top right to sign in. 18 | Attempts to go to a protected page, such as the ID Token Details page or Call API will result in automatic redirection to Microsoft identity platform sign in page. 19 |
20 |

21 |
22 |
23 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/content/survey.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Tell us how we did! 4 |
5 |
6 | Click here if the survey question does not load automatically. 7 |

8 | 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/content/token.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | ID Token Details 4 |
5 |
6 |

7 | The following is a limited subset of some important claims in your ID Token. 8 |
9 | 10 | : 11 | 12 |
13 |
14 |
15 | Sign-in Status 16 | Call API 17 |

18 |
19 |
20 | -------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |  Have you updated your app's redirect URI on Azure Portal? 6 |
7 | Redirect URI: 8 | 9 |
10 |
11 | 12 | 13 | 14 |   Does this sample address your learning objective? 15 | 16 |
17 |

18 |

© 2021

19 |

-------------------------------------------------------------------------------- /3-Authorization-II/protect-web-api/webapp/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ms-identity-spring-boot-webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | 25 | 1616698377300 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/AppCreationScripts/Cleanup.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [CmdletBinding()] 7 | param( 8 | [PSCredential] $Credential, 9 | [Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')] 10 | [string] $tenantId, 11 | [Parameter(Mandatory=$False, HelpMessage='Azure environment to use while running the script (it defaults to AzureCloud)')] 12 | [string] $azureEnvironmentName 13 | ) 14 | 15 | #Requires -Modules AzureAD -RunAsAdministrator 16 | 17 | 18 | 19 | if ($null -eq (Get-Module -ListAvailable -Name "AzureAD")) { 20 | Install-Module "AzureAD" -Scope CurrentUser 21 | } 22 | Import-Module AzureAD 23 | $ErrorActionPreference = "Stop" 24 | 25 | Function Cleanup 26 | { 27 | if (!$azureEnvironmentName) 28 | { 29 | $azureEnvironmentName = "AzureCloud" 30 | } 31 | 32 | <# 33 | .Description 34 | This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script 35 | #> 36 | 37 | # $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant 38 | # into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD. 39 | 40 | # Login to Azure PowerShell (interactive if credentials are not already provided: 41 | # you'll need to sign-in with creds enabling your to create apps in the tenant) 42 | if (!$Credential -and $TenantId) 43 | { 44 | $creds = Connect-AzureAD -TenantId $tenantId -AzureEnvironmentName $azureEnvironmentName 45 | } 46 | else 47 | { 48 | if (!$TenantId) 49 | { 50 | $creds = Connect-AzureAD -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 51 | } 52 | else 53 | { 54 | $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential -AzureEnvironmentName $azureEnvironmentName 55 | } 56 | } 57 | 58 | if (!$tenantId) 59 | { 60 | $tenantId = $creds.Tenant.Id 61 | } 62 | $tenant = Get-AzureADTenantDetail 63 | $tenantName = ($tenant.VerifiedDomains | Where-Object { $_._Default -eq $True }).Name 64 | 65 | # Removes the applications 66 | Write-Host "Cleaning-up applications from tenant '$tenantName'" 67 | 68 | 69 | Write-Host "Removing 'webApp' (java-spring-webapp-roles) if needed" 70 | Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-roles'" | ForEach-Object {Remove-AzureADApplication -ObjectId $_.ObjectId } 71 | $apps = Get-AzureADApplication -Filter "DisplayName eq 'java-spring-webapp-roles'" 72 | if ($apps) 73 | { 74 | Remove-AzureADApplication -ObjectId $apps.ObjectId 75 | } 76 | 77 | foreach ($app in $apps) 78 | { 79 | Remove-AzureADApplication -ObjectId $app.ObjectId 80 | Write-Host "Removed java-spring-webapp-roles.." 81 | } 82 | # also remove service principals of this app 83 | Get-AzureADServicePrincipal -filter "DisplayName eq 'java-spring-webapp-roles'" | ForEach-Object {Remove-AzureADServicePrincipal -ObjectId $_.Id -Confirm:$false} 84 | 85 | 86 | } 87 | 88 | Cleanup -Credential $Credential -tenantId $TenantId -------------------------------------------------------------------------------- /3-Authorization-II/roles/AppCreationScripts/CleanupUsersAndRoles.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [PSCredential] $Credential, 4 | [Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')] 5 | [string] $tenantId 6 | ) 7 | 8 | Import-Module AzureAD 9 | $ErrorActionPreference = 'Stop' 10 | 11 | Function RemoveUser([string]$userPrincipal) 12 | { 13 | $user = Get-AzureADUser -Filter "UserPrincipalName eq '$userPrincipal'" 14 | if ($user) 15 | { 16 | Write-Host "Removing User '($userPrincipal)'" 17 | Remove-AzureADUser -ObjectId $user.ObjectId 18 | } 19 | else { 20 | Write-Host "Failed to remove user '($userPrincipal)'" 21 | } 22 | } 23 | 24 | Function CleanupUsers 25 | { 26 | <# 27 | .Description 28 | This function removes the users created in the Azure AD tenant by the CreateUsersAndRoles.ps1 script. 29 | #> 30 | 31 | # $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant 32 | # into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD. 33 | 34 | # Login to Azure PowerShell (interactive if credentials are not already provided: 35 | # you'll need to sign-in with creds enabling your to create apps in the tenant) 36 | if (!$Credential -and $TenantId) 37 | { 38 | $creds = Connect-AzureAD -TenantId $tenantId 39 | } 40 | else 41 | { 42 | if (!$TenantId) 43 | { 44 | $creds = Connect-AzureAD -Credential $Credential 45 | } 46 | else 47 | { 48 | $creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential 49 | } 50 | } 51 | 52 | if (!$tenantId) 53 | { 54 | $tenantId = $creds.Tenant.Id 55 | } 56 | 57 | $tenant = Get-AzureADTenantDetail 58 | 59 | $tenantName = ($tenant.VerifiedDomains | Where { $_._Default -eq $True }).Name 60 | 61 | $appName = "java-spring-webapp-roles" 62 | 63 | # Removes the users created for the application 64 | Write-Host "Removing Users" 65 | RemoveUser -userPrincipal "$appName-PrivilegedAdmin@$tenantName" 66 | RemoveUser -userPrincipal "$appName-RegularUser@$tenantName" 67 | 68 | Write-Host "finished removing users created for this app." 69 | } 70 | 71 | # Pre-requisites 72 | if ((Get-Module -ListAvailable -Name "AzureAD") -eq $null) { 73 | Install-Module "AzureAD" -Scope CurrentUser 74 | } 75 | Import-Module AzureAD 76 | $ErrorActionPreference = 'Stop' 77 | 78 | CleanupUsers -Credential $Credential -tenantId $TenantId 79 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/AppCreationScripts/apps.json: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | { 9 | "Sample": { 10 | "Title": "Enable your Java Spring MVC web app to restrict access to routes using app roles & the roles claim with the Microsoft identity platform", 11 | "Level": 100, 12 | "Client": "Java Spring MVC web app" 13 | }, 14 | "AppRegistrations": [ 15 | 16 | { 17 | "x-ms-id": "webApp", 18 | "x-ms-name": "java-spring-webapp-roles", 19 | "x-ms-version": "2.0", 20 | 21 | "replyUrlsWithType": [ 22 | 23 | { 24 | "url": "http://localhost:8080/login/oauth2/code/azure", 25 | "type": "Web" 26 | } ], 27 | 28 | 29 | "oauth2AllowImplicitFlow": false, 30 | 31 | 32 | "oauth2AllowIdTokenImplicitFlow": false, 33 | 34 | 35 | "codeConfigurations": [ 36 | 37 | { 38 | "settingFile": "/src/main/resources/application.yml", 39 | "replaceTokens": 40 | { 41 | /** 42 | * Note: The following 'key-value' pairs are for illustration only; you may 43 | * not have all of them in your configuration file. Azure portal will replace 44 | * the values (i.e. text) below with the actual app credentials. 45 | * Finally, don't forget to remove this comment. 46 | */ 47 | "appId": "Enter_the_Application_Id_Here", 48 | "redirectUri": "Enter_the_Redirect_Uri_Here", 49 | "tenantId": "Enter_the_Tenant_Info_Here", 50 | "clientSecret": "Enter_the_Client_Secret_Here", 51 | "authorityEndpointHost": "Enter_the_Cloud_Instance_Id_Here", 52 | "msgraphEndpointHost": "Enter_the_Graph_Endpoint_Here", 53 | "signInAudience": "Enter_the_Sign-in_Audience_Here" 54 | } 55 | } ] 56 | } 57 | 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/AppCreationScripts/sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sample": { 3 | "Title": "Enable your Java Spring Boot web app to restrict access to routes using app roles & the roles claim with the Microsoft identity platform", 4 | "Level": 100, 5 | "Client": "Java Spring Boot web app", 6 | "RepositoryUrl": "ms-identity-java-spring-tutorial", 7 | "Endpoint": "AAD v2.0" 8 | }, 9 | "AADApps": [ 10 | { 11 | "Id": "webApp", 12 | "Name": "java-spring-webapp-roles", 13 | "Kind": "WebApp", 14 | "Audience": "AzureADMyOrg", 15 | "PasswordCredentials": "Auto", 16 | "AllowImplicitFlow": false, 17 | "HomePage": "http://localhost:8080/", 18 | "ReplyUrls": "http://localhost:8080/login/oauth2/code/", 19 | "RequiredResourcesAccess": [], 20 | "ManualSteps": [ 21 | { 22 | "Comment": " You can run the ..\\CreateUsersAndAssignRoles.ps1 command to automatically create a number of users, and assign users to these roles or assign users to this application app roles using the portal." 23 | }, 24 | { 25 | "Comment": "To receive the `roles` claim with the name of the app roles this user is assigned to, make sure that the user accounts you plan to sign in to this app is assigned to the app roles of this app. Use this guide for step-by-step directions: https://docs.microsoft.com/azure/active-directory/manage-apps/assign-user-or-group-access-portal#assign-a-user-to-an-app---portal" 26 | } 27 | ] 28 | } 29 | ], 30 | "CodeConfiguration": [ 31 | { 32 | "App": "webApp", 33 | "SettingKind": "Replace", 34 | "SettingFile": "\\..\\src\\main\\resources\\application.yml", 35 | "Mappings": [ 36 | { 37 | "key": "Enter_Your_Tenant_ID_Here", 38 | "value": "$tenantId" 39 | }, 40 | { 41 | "key": "Enter_Your_Client_ID_Here", 42 | "value": "webApp.AppId" 43 | }, 44 | { 45 | "key": "Enter_Your_Client_Secret_Here", 46 | "value": ".AppKey" 47 | } 48 | ] 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /3-Authorization-II/roles/ReadmeFiles/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/roles/ReadmeFiles/app.png -------------------------------------------------------------------------------- /3-Authorization-II/roles/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/roles/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /3-Authorization-II/roles/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.6 9 | 10 | 11 | 12 | com.microsoft.azuresamples.msal4j 13 | ms-identity-spring-boot-webapp 14 | 0.0.1-SNAPSHOT 15 | ms-identity-spring-boot-webapp 16 | Microsoft identity platform Spring Boot sample 17 | 18 | 11 19 | 3.9.0 20 | 21 | 22 | 23 | 24 | com.azure.spring 25 | azure-spring-boot-starter-active-directory 26 | ${azure.version} 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-oauth2-client 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-thymeleaf 41 | 42 | 43 | org.thymeleaf.extras 44 | thymeleaf-extras-springsecurity5 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | org.junit.vintage 53 | junit-vintage-engine 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | repackage 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/MsIdentitySpringBootWebappApplication.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | 9 | @SpringBootApplication 10 | public class MsIdentitySpringBootWebappApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(MsIdentitySpringBootWebappApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import com.azure.spring.aad.webapp.AADWebSecurityConfigurerAdapter; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | 13 | /** 14 | * AADWebSecurityConfigurer (AADWSC) is an extension of Spring's WebSecurityConfigurer (WSC). 15 | * 16 | * You must extend AADWSC to define your own custom configuration in the configure() method. 17 | * Be sure to call super.configure() first. This will set up all of your AuthN/AuthZ properly. 18 | * 19 | * You may omit this by not extending the AADWSC class. 20 | * 21 | * If you don't extend AADWSC or WSC, AAD boot starter will create a DefaultAADWebSecurityConfigurerAdapter 22 | * bean automatically, and define its own default http.authorizeRequests() rule (authorize ALL requests). 23 | * 24 | * See DefaultAADWebSecurityConfigurerAdapter in com.azure.spring.aad.webapp.AADWebAppConfiguration 25 | */ 26 | 27 | @EnableWebSecurity 28 | @EnableGlobalMethodSecurity(prePostEnabled = true) 29 | public class SecurityConfig extends AADWebSecurityConfigurerAdapter{ 30 | @Value( "${app.protect.authenticated}" ) 31 | private String[] protectedRoutes; 32 | 33 | @Override 34 | public void configure(HttpSecurity http) throws Exception { 35 | // use required configuration from AADWebSecurityAdapter.configure: 36 | super.configure(http); 37 | // add custom configuration: 38 | http.authorizeRequests() 39 | .antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details, /admin_only, /regular_user) 40 | .antMatchers("/**").permitAll(); // allow all other routes. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/Utilities.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | package com.microsoft.azuresamples.msal4j.msidentityspringbootwebapp; 5 | 6 | import java.util.Arrays; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 11 | 12 | public class Utilities { 13 | private Utilities() { 14 | throw new IllegalStateException("Utility class. Don't instantiate"); 15 | } 16 | 17 | /** 18 | * Take a subset of ID Token claims and put them into KV pairs for UI to display. 19 | * @param principal OidcUser (see SampleController for details) 20 | * @return Map of filteredClaims 21 | */ 22 | public static Map filterClaims(OidcUser principal) { 23 | final String[] claimKeys = {"sub", "aud", "ver", "iss", "name", "oid", "preferred_username", "roles"}; 24 | final List includeClaims = Arrays.asList(claimKeys); 25 | 26 | Map filteredClaims = new HashMap<>(); 27 | includeClaims.forEach(claim -> { 28 | if (principal.getIdToken().getClaims().containsKey(claim)) { 29 | filteredClaims.put(claim, principal.getIdToken().getClaims().get(claim).toString()); 30 | } else { 31 | filteredClaims.put(claim, "This claim was not found in ID Token."); 32 | } 33 | }); 34 | return filteredClaims; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | {"properties": [ 2 | { 3 | "name": "app.ui.base", 4 | "type": "java.lang.String", 5 | "description": "the base UI template page name in src/main/webapp" 6 | }, 7 | { 8 | "name": "app.ui.content", 9 | "type": "java.lang.String", 10 | "description": "content with which to populate app.ui.base, also located in same folder." 11 | }, 12 | { 13 | "name": "app.protect.authenticated", 14 | "type": "java.lang.String[]", 15 | "description": "limit these pages to authenticated users. Use '=/route1' for a single route. Use '=/route1, /route2' for multiple." 16 | } 17 | ]} -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | activedirectory: 3 | # Specifies your Active Directory ID: 4 | tenant-id: Enter_Your_Tenant_ID_Here 5 | # Specifies your App Registration's Application ID: 6 | client-id: Enter_Your_Client_ID_Here 7 | # Specifies your App Registration's secret key: 8 | client-secret: Enter_Your_Client_Secret_Here 9 | # Specifies the post-log-out-redirect-uri, where to return your app after logout. 10 | post-logout-redirect-uri: http://localhost:8080 11 | # Specifies the Microsoft Graph scopes that your app needs access to - not required in this app. 12 | # authorization-clients: 13 | # graph: 14 | # scopes: https://graph.microsoft.com/User.Read 15 | 16 | # which routes to restrict to authenticated users only (see SecurityConfig.java): 17 | # enter String array (comma-separated) or just one route. 18 | # e.g. authenticated: /route1, /route2, /route3 19 | app: 20 | protect: 21 | authenticated: /token_details, /admin_only, /regular_user 22 | 23 | # un-comment the following lines if you are deploying to a reverse proxy (e.g. Azure App Service) 24 | # server: 25 | # forward-headers-strategy: native 26 | # tomcat: 27 | # remoteip: 28 | # protocol-header: "X-Forwarded-Proto" 29 | # remote-ip-header: "X-Forwarded-For" 30 | # internal-proxies: ".*" -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/3-Authorization-II/roles/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/static/style.css: -------------------------------------------------------------------------------- 1 | .body-content { 2 | padding-top: 15px; 3 | padding-bottom: 15px; 4 | padding-left: 15px; 5 | padding-right: 15px; 6 | } 7 | 8 | .dl-horizontal dt { 9 | white-space: normal; 10 | } 11 | 12 | .flashToast { 13 | position: fixed; 14 | bottom: 0; 15 | left: 0; 16 | } 17 | 18 | 19 | .card { 20 | width: 50vw; 21 | margin:auto; 22 | background:#f0f0f0; 23 | border:1px solid black; 24 | } 25 | 26 | .card-header { 27 | /* background: darkseagreen; */ 28 | color: rgba(255,255,255,0.85); 29 | background: #0078d4; 30 | font-weight: 300; 31 | } 32 | 33 | .card-text { 34 | align-content: center 35 | } 36 | 37 | #wrapper { 38 | display: flex; 39 | } 40 | 41 | #left { 42 | flex: content; 43 | margin-right: 0.5em; 44 | 45 | } 46 | 47 | #right { 48 | flex: 1; 49 | } 50 | 51 | #footer { 52 | width: 50vw; 53 | margin: auto; 54 | text-align: left; 55 | margin-top: 1em; 56 | } 57 | 58 | .smiley, .frowny { 59 | height: 1.5em; 60 | width: 1.5em; 61 | margin: auto; 62 | fill: #0078d4 63 | } 64 | 65 | .smiley:hover, .frowny:hover{ 66 | height: 1.5em; 67 | width: 1.5em; 68 | margin: auto; 69 | fill: white; 70 | border: 1px solid #0078d4; 71 | background-color: #0078d4; 72 | border-radius: 50%; 73 | } 74 | 75 | #check-icon { 76 | height: 1.25em; 77 | width: 1.25em; 78 | margin: auto; 79 | fill: green; 80 | } 81 | 82 | a.nostyle:link { 83 | text-decoration: inherit; 84 | color: inherit; 85 | } 86 | 87 | a.nostyle:visited { 88 | text-decoration: inherit; 89 | color: inherit; 90 | } -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Authorization II: Use Active Directory Spring Boot Starter to control access by app roles 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/401.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 401: Unauthorized 5 |
6 |
7 |

8 | Visiting this page requires you to be authenticated. Use the button on the top right to sign in. 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/403.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 403: Forbidden 4 |
5 |
6 |

7 | Sorry! you are not a member of the app role(s) that are allowed to visit this page. 8 |
9 | This page requires one of the following roles: 10 |

11 | Sign-in Status 12 | ID Token Details 13 | Admins Only 14 | Regular Users 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 500: Auth Error 5 |
6 |
7 |

8 | ${details}
9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/graph.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Call Graph /me Endpoint 4 |
5 |
6 |

7 | 8 | : 9 | 10 |
11 |
12 |
13 | Sign-in Status 14 | Token Details 15 |

16 |
17 |
18 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/role.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | You are authorized! 4 |
5 |
6 |

7 | Excellent! You are a member of the role(s) that are allowed to visit this page! 8 |
9 | This page requires one of the following roles: 10 |

11 | Sign-in Status 12 | ID Token Details 13 | Admins Only 14 | Regular Users 15 |

16 |
17 |
18 | 19 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/status.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | You're signed in! 5 |
6 |
7 | You're not signed in. 8 |
9 |
10 |
11 |

12 |

18 |
19 | Use the button on the top right to sign in. 20 | Attempts to go to one of the protected pages below will result in automatic redirection to Microsoft identity platform sign in endpoint. 21 |
22 | Sign-in Status 23 | ID Token Details 24 | Admins Only 25 | Regular Users 26 |
27 |

28 |
29 |
30 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/survey.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Tell us how we did! 4 |
5 |
6 | Click here if the survey question does not load automatically. 7 |

8 | 9 |

10 |
11 |
12 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/content/token.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | ID Token Details 4 |
5 |
6 |

7 | The following is a limited subset of some important claims in your ID Token. 8 |
9 | 10 | : 11 | 12 |
13 |
14 |
15 | Sign-in Status 16 | ID Token Details 17 | Admins Only 18 | Regular Users 19 |

20 |
21 |
22 | -------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |  Have you updated your app's redirect URI on Azure Portal? 6 |
7 | Redirect URI: 8 | 9 |
10 |
11 | 12 | 13 | 14 |   Does this sample address your learning objective? 15 | 16 |
17 |

18 |

© 2021

19 |

-------------------------------------------------------------------------------- /3-Authorization-II/roles/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /4-Deployment/deploy-to-azure-app-service/ReadmeFiles/disable_easy_auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/4-Deployment/deploy-to-azure-app-service/ReadmeFiles/disable_easy_auth.png -------------------------------------------------------------------------------- /4-Deployment/deploy-to-azure-app-service/ReadmeFiles/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/4-Deployment/deploy-to-azure-app-service/ReadmeFiles/topology.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [project-title] Changelog 2 | 3 | 4 | # x.y.z (yyyy-mm-dd) 5 | 6 | *Features* 7 | * ... 8 | 9 | *Bug Fixes* 10 | * ... 11 | 12 | *Breaking Changes* 13 | * ... 14 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /ReadmeFiles/call-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/ReadmeFiles/call-graph.png -------------------------------------------------------------------------------- /ReadmeFiles/sign-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/ms-identity-java-spring-tutorial/ca17567190ee7e252dea40f1e491ac23e0a1b09f/ReadmeFiles/sign-in.png --------------------------------------------------------------------------------