Skip to content

Commit

Permalink
Update README.md file in the azure-spring-boot-sample-active-director…
Browse files Browse the repository at this point in the history
…y-resource-server (#18361)
  • Loading branch information
ZhuXiaoBing-cn authored Dec 29, 2020
1 parent ae0c6a1 commit 34a28f2
Show file tree
Hide file tree
Showing 17 changed files with 49 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,22 @@
## Key concepts
This sample illustrates how to protect a Java web API by restricting access to its resources to authorized accounts only.

1. The bearer token is obtained from the request header.
2. `JwtDecoder` is used to parse the token into `Jwt`.
3. Claims, headers etc in `Jwt` will be extracted, they will be wrapped in `AzureOAuth2AuthenticatedPrincipal` object.
4. `AzureOAuth2AuthenticatedPrincipal` will eventually be set into SecurityContext.
1. Obtain the access token from the HTTP request header.
2. Use `JwtDecoder` to parse the access token into `Jwt`.
3. Verify `aud`, `iss`, `nbf`, `exp` claims in access token.
4. Extract information from JWT in `AADOAuth2AuthenticatedPrincipal` object after a successful verification.
5. Save the `AADOAuth2AuthenticatedPrincipal` into SecurityContext.

### Protocol diagram
![Aad resource server protocol diagram](docs/image-add-resource-server.png "Aad resource server protocol diagram")

## Getting started

### Environment checklist
We need to ensure that this [environment checklist][ready-to-run-checklist] is completed before the run.

To run this sample, you'll need:
- An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see [How to get an Azure AD tenant][How to get an Azure AD tenant]
- You register your web APP in App registrations in the Azure portal.
- A Web APP runtime that requires access to a Web API.


## Include the package
### Include the package
```xml
<dependencies>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-active-directory</artifactId>
Expand All @@ -35,64 +31,46 @@ To run this sample, you'll need:
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
</dependencies>
</dependencies>
```

## Register your web API
In this section, you register your web API in App registrations in the Azure portal.

### Choose your Azure AD tenant

To register your apps manually, choose the Azure Active Directory (Azure AD) tenant where you want to create your apps.

1. Sign in to the [Azure portal](https://portal.azure.com/) with either a work or school account or a personal Microsoft account.
2. If your account is present in more than one Azure AD tenant, select your profile at the upper right, and then select **Switch directory**.
3. Change your portal session to the Azure AD tenant you want to use.

### Register the web API

1. Go to the Microsoft identity platform for developers App registrations portal.
### Configure Web API
1. In this section, you register your web API in App registrations in the Azure portal.
2. Search for and select your tenant in **Azure Active Directory**.
3. Under **Manage** In the same tenant, select **App registrations** -> **New registration**.![Protal manage](docs/image-protal-manage.png "Protal manage")
4. The registered application name is filled into `webapi`, select **Accounts in this organizational directory only**, click the **register** button.![Register a web api](docs/image-register-a-web-api.png "Register a web api")
5. Under **webapi** application, select **Certificates & secrets** -> **new client secret**, expires select **Never**, click the **add** button, remember to save the secrets here and use them later.![Creat secrets](docs/image-creat-secrets-api.png "Creat secrets")
6. Under **webapi** application, select **Expose an API** -> **Add a scope**, Use the default Application ID URI, click **Save and continue** button.![Set application id url](docs/image-set-application-id-url.png "Set application id url")
7. After step five, the page will refresh again. Then set the **Scope name** to `File.Read`.![Add a scope](docs/image-add-a-scope.png "Add a scope")
8. Finally, the api exposed in `webapi`.![Finally, the API exposed in webAPI](docs/image-expose-api.png "Finally, the API exposed in webAPI")

2. Select New registration.
![Select New registration](docs/image-select-new-registration.png "Select new registration")

3. When the Register an application page opens, enter your application's registration information:
![Scope Config](docs/image-register-an-application.png "Register an application")

4. In the **Expose an API** section, select **Add a scope**, accept the proposed Application ID URI `(api://{clientId})` (back up the Application ID URI here, which will be used in the properties file) by selecting **Save and Continue**.
![App-Id-Uri Config](docs/image-app-id-uri-config.png "App-id-uri Config")
Then enter the following information:
- For **Scope name**, enter **File.read**.
- For **Who can consent**, ensure that the **Admins and users** option is selected.
- In the **Admin consent display name** box, enter **Access File.read as a user**.
- In the **Admin consent description** box, enter **Accesses the File.read web API as a user**.
- In the **User consent display name** box, enter **Access File.read as a user**.
- In the **User consent description** box, enter **Accesses the File.read web API as a user**.
- For **State**, keep **Enabled**.
- Select **Add scope**.
![Scope Config](docs/image-scope-configurations.png "Scope Config")

If you still don't understand, you can look at this [register app or web api][Register app or web API] and another [expose scoped permission to web api][Expose scoped permission to web API]. I believe it will also help you.
See [Expose scoped permission to web api] for more information about web api.

## Examples

### Configure application.properties

```properties
azure.activedirectory.client-id=xxxxxx-your-client-id-xxxxxx
azure.activedirectory.app-id-uri=xxxxxxxx-app-id-uri-xxxxxxxxxx
azure.activedirectory.session-stateless=true
### Configure application.yml
```yaml
#If we configure the azure.activedirectory.client-id or azure.activedirectory.app-id-uri will be to check the audience.
#In v2.0 tokens, this is always client id of the app, while in v1.0 tokens it can be the client id or the application id url used in the request.
#If you are using v1.0 tokens, configure both to properly complete the audience validation.

azure:
activedirectory:
client-id: <client-id>
app-id-uri: <app-id-uri>
```
### Run with Maven
### Run with Maven
```shell
# Under sdk/spring project root directory
cd azure-spring-boot-samples/azure-spring-boot-sample-active-directory-spring-oauth2-resource-server
cd azure-spring-boot-samples/azure-spring-boot-sample-active-directory-resource-server
mvn spring-boot:run
```

### Access the Web API
We could use Postman to simulate a Web APP to send a request to a Web API.

**NOTE**: The `aud` in access token should be the current Web API.

```http request
GET /file HTTP/1.1
Authorization: Bearer eyJ0eXAiO ... 0X2tnSQLEANnSPHY0gKcgw
Expand All @@ -102,10 +80,9 @@ GET /user HTTP/1.1
Authorization: Bearer eyJ0eXAiO ... 0X2tnSQLEANnSPHY0gKcgw
```

### Check authorization

1. Access `file read` link, should success.
2. Access `user read` link, should fail.
### Check the authentication and authorization
1. Access `http://localhost:<your-Configured-server-port>/file` link: success.
2. Access `http://localhost:<your-Configured-server-port>/user` link: fail with error message.

## Troubleshooting

Expand All @@ -114,6 +91,4 @@ Authorization: Bearer eyJ0eXAiO ... 0X2tnSQLEANnSPHY0gKcgw
<!-- LINKS -->
[jdk_link]: https://docs.microsoft.com/java/azure/jdk/?view=azure-java-stable
[ready-to-run-checklist]: https://github.com/Azure/azure-sdk-for-java/blob/master/sdk/spring/azure-spring-boot-samples/README.md#ready-to-run-checklist
[Register app or web API]: https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app
[Expose scoped permission to web API]: https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-expose-web-apis
[How to get an Azure AD tenant]: https://azure.microsoft.com/documentation/articles/active-directory-howto-tenant
[Expose scoped permission to web api]: https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-expose-web-apis
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ public class HomeController {

@GetMapping("/file")
@ResponseBody
@PreAuthorize("hasAuthority('SCOPE_File.read')")
public String group1() {
return "file read success.";
@PreAuthorize("hasAuthority('SCOPE_File.Read')")
public String file() {
return "File read success.";
}

@GetMapping("/user")
@ResponseBody
@PreAuthorize("hasAuthority('SCOPE_User.read')")
public String group2() {
return "user read success.";
@PreAuthorize("hasAuthority('SCOPE_User.Read')")
public String user() {
return "User read success.";
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# If we configure the azure.activedirectory.client-id or azure.activedirectory.app-id-uri will be to check the audience.
# 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.
# If you are using v1.0 tokens, configure both to properly complete the audience validation.
# For azure.activedirectory.session-stateless, it is now compatible with previous versions and will be removed later.

#azure.activedirectory.client-id=xxxxxx-your-client-id-xxxxxx
#azure.activedirectory.app-id-uri=xxxxxxxx-app-id-uri-xxxxxxxxxx
#azure:
# activedirectory:
# client-id: <client-id>
# app-id-uri: <app-id-uri>

0 comments on commit 34a28f2

Please sign in to comment.