Skip to content

Commit d938b18

Browse files
authored
Merge pull request #102465 from navyasric/auth-doc-updates
Add Java and Python OBO scenario docs
2 parents ccf1624 + ef84b29 commit d938b18

File tree

5 files changed

+176
-25
lines changed

5 files changed

+176
-25
lines changed

articles/active-directory/develop/index.yml

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
title: Microsoft identity platform (formerly Azure Active Directory for developers)
44
summary: Microsoft identity platform is an evolution of the Azure Active Directory (Azure AD) developer platform. It allows developers to build applications that sign in all Microsoft identities and get tokens to call Microsoft APIs such as Microsoft Graph or APIs that developers have built. It’s a full-featured platform that consists of an OAuth 2.0 and OpenID Connect standard-compliant authentication service, open-source libraries, application registration and configuration, robust conceptual and reference documentation, quickstart samples, code samples, tutorials, and how-to guides.
55

6-
metadata:
6+
metadata:
77
ms.topic: landing-page
88
ms.date: 06/22/2019
99
author: CelesteDG
1010
ms.author: celested
1111
ms.service: active-directory
1212
ms.subservice: develop
13-
ms.workload: identity
13+
ms.workload: identity
1414

1515
landingContent:
1616
- title: About Microsoft identity platform
@@ -46,7 +46,7 @@ landingContent:
4646
- text: JavaScript
4747
url: quickstart-v2-javascript.md
4848
- linkListType: tutorial
49-
links:
49+
links:
5050
- text: JavaScript
5151
url: tutorial-v2-javascript-spa.md
5252
- linkListType: download
@@ -67,27 +67,37 @@ landingContent:
6767
url: quickstart-v2-aspnet-core-webapp.md
6868
- text: ASP.NET
6969
url: quickstart-v2-aspnet-webapp.md
70+
- text: Java
71+
url: quickstart-v2-java-webapp.md
72+
- text: Python
73+
url: quickstart-v2-python-webapp.md
7074
- linkListType: tutorial
71-
links:
75+
links:
7276
- text: ASP.NET Core
7377
url: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2
7478
- linkListType: download
7579
links:
76-
- text: Samples - ASP.NET Core, ASP.NET
80+
- text: Samples - ASP.NET Core, ASP.NET, Java, Python
7781
url: sample-v2-code.md#web-applications
7882
- title: Build a web app that calls web APIs
7983
linkLists:
8084
- linkListType: get-started
8185
links:
8286
- text: Scenario overview
8387
url: scenario-web-app-call-api-overview.md
88+
- linkListType: quickstart
89+
links:
90+
- text: Java
91+
url: quickstart-v2-java-webapp.md
92+
- text: Python
93+
url: quickstart-v2-python-webapp.md
8494
- linkListType: tutorial
85-
links:
95+
links:
8696
- text: ASP.NET Core
8797
url: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2#scope-of-this-tutorial
8898
- linkListType: download
8999
links:
90-
- text: Samples - ASP.NET Core, ASP.NET, Node.js, Ruby
100+
- text: Samples - ASP.NET Core, ASP.NET, Node.js, Ruby, Java, Python
91101
url: sample-v2-code.md#web-applications
92102
- title: Build a protected web API
93103
linkLists:
@@ -96,7 +106,7 @@ landingContent:
96106
- text: Scenario overview
97107
url: scenario-protected-web-api-overview.md
98108
- linkListType: tutorial
99-
links:
109+
links:
100110
- text: ASP.NET Core web API
101111
url: https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2
102112
- linkListType: download
@@ -110,30 +120,32 @@ landingContent:
110120
- text: Scenario overview
111121
url: scenario-web-api-call-api-overview.md
112122
- linkListType: tutorial
113-
links:
123+
links:
114124
- text: ASP.NET Core web API that calls Microsoft Graph
115125
url: https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/tree/master/2.%20Web%20API%20now%20calls%20Microsoft%20Graph
126+
- text: Java web API that calls Microsoft Graph
127+
url: https://github.com/Azure-Samples/ms-identity-java-webapi
116128
- title: Build a desktop app that calls web APIs
117129
linkLists:
118130
- linkListType: get-started
119131
links:
120132
- text: Scenario overview
121133
url: scenario-desktop-overview.md
122134
- linkListType: quickstart
123-
links:
135+
links:
124136
- text: Acquire a token & call Microsoft Graph API (Windows desktop)
125137
url: quickstart-v2-windows-desktop.md
126138
- text: Acquire a token & call Microsoft Graph API (UWP)
127139
url: quickstart-v2-uwp.md
128140
- linkListType: tutorial
129-
links:
141+
links:
130142
- text: Call Microsoft Graph API (Windows desktop)
131143
url: tutorial-v2-windows-desktop.md
132144
- text: Call Microsoft Graph API (UWP)
133145
url: tutorial-v2-windows-uwp.md
134146
- linkListType: download
135147
links:
136-
- text: Sample - .NET, .NET Core
148+
- text: Sample - .NET, .NET Core, Java, Python
137149
url: sample-v2-code.md#desktop-and-mobile-public-client-apps
138150
- title: Build a daemon app that calls web APIs
139151
linkLists:
@@ -142,14 +154,14 @@ landingContent:
142154
- text: Scenario overview
143155
url: scenario-daemon-overview.md
144156
- linkListType: quickstart
145-
links:
157+
links:
146158
- text: Acquire a token & call Microsoft Graph API (.NET Core console)
147159
url: quickstart-v2-netcore-daemon.md
148160
- text: Acquire a token & call Microsoft Graph API (ASP.NET web app)
149161
url: https://github.com/Azure-Samples/ms-identity-aspnet-daemon-webapp
150162
- linkListType: download
151163
links:
152-
- text: Samples - ASP.NET console, ASP.NET web
164+
- text: Samples - ASP.NET console, ASP.NET web, Java, Python
153165
url: sample-v2-code.md#daemon-applications
154166
- title: Build a mobile app that calls web APIs
155167
linkLists:
@@ -158,15 +170,15 @@ landingContent:
158170
- text: Scenario overview
159171
url: scenario-mobile-overview.md
160172
- linkListType: quickstart
161-
links:
173+
links:
162174
- text: Acquire a token & call Microsoft Graph API (Android)
163175
url: quickstart-v2-android.md
164176
- text: Acquire a token & call Microsoft Graph API (iOS)
165177
url: quickstart-v2-ios.md
166178
- text: Acquire a token & call Microsoft Graph API (Xamarin iOS & Android)
167179
url: https://github.com/Azure-Samples/active-directory-xamarin-native-v2
168180
- linkListType: tutorial
169-
links:
181+
links:
170182
- text: Sign in users & call Microsoft Graph API (Android)
171183
url: tutorial-v2-android.md
172184
- text: Sign in users & call Microsoft Graph API (iOS)
@@ -182,7 +194,7 @@ landingContent:
182194
- text: About Microsoft Graph
183195
url: https://docs.microsoft.com/graph/overview
184196
- linkListType: quickstart
185-
links:
197+
links:
186198
- text: Get up and running in 3 minutes
187199
url: https://developer.microsoft.com/graph/get-started
188200
- linkListType: learn
@@ -192,9 +204,9 @@ landingContent:
192204
- text: Microsoft Graph REST API v1.0
193205
url: https://docs.microsoft.com/graph/api/overview?toc=.%2Fref%2Ftoc.json&view=graph-rest-1.0
194206
- text: Microsoft Graph REST API Beta
195-
url: https://docs.microsoft.com/graph/api/overview?toc=.%2Fref%2Ftoc.json&view=graph-rest-beta
207+
url: https://docs.microsoft.com/graph/api/overview?toc=.%2Fref%2Ftoc.json&view=graph-rest-beta
196208
- linkListType: deploy
197-
links:
209+
links:
198210
- text: Graph Explorer
199211
url: https://developer.microsoft.com/graph/graph-explorer/
200212
- title: Build a customer-facing app that signs in social & local identities

articles/active-directory/develop/sample-v2-code.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ The following samples show public client applications (desktop or mobile applica
6969
| ------------------ | -------- | ----------| ---------- | ------------------------- |
7070
| Desktop (WPF) | ![This image shows the .NET/C# logo](media/sample-v2-code/logo_NET.png) | [interactive](msal-authentication-flows.md#interactive)| [dotnet-desktop-msgraph-v2](https://github.com/azure-samples/active-directory-dotnet-desktop-msgraph-v2) | [dotnet-native-aspnetcore-v2](https://aka.ms/msidentity-aspnetcore-webapi) |
7171
| Desktop (Console) | ![This image shows the .NET/C# (Desktop) logo](media/sample-v2-code/logo_NET.png) | [Integrated Windows Authentication](msal-authentication-flows.md#integrated-windows-authentication) | [dotnet-iwa-v2](https://github.com/azure-samples/active-directory-dotnet-iwa-v2) | |
72+
| Desktop (Console) | ![This image shows the Java logo](media/sample-v2-code/logo_java.png) | [Integrated Windows Authentication](msal-authentication-flows.md#integrated-windows-authentication) |[ms-identity-java-desktop](https://github.com/Azure-Samples/ms-identity-java-desktop/) | |
7273
| Desktop (Console) | ![This image shows the .NET/C# (Desktop) logo](media/sample-v2-code/logo_NETcore.png) | [Username/Password](msal-authentication-flows.md#usernamepassword) |[dotnetcore-up-v2](https://github.com/azure-samples/active-directory-dotnetcore-console-up-v2) | |
7374
| Desktop (Console) | ![This image shows the Java logo](media/sample-v2-code/logo_java.png) | [Username/Password](msal-authentication-flows.md#usernamepassword) |[ms-identity-java-desktop](https://github.com/Azure-Samples/ms-identity-java-desktop/) | |
7475
| Desktop (Console) | ![This image shows the Python logo](media/sample-v2-code/logo_python.png) | [Username/Password](msal-authentication-flows.md#usernamepassword) |[ms-identity-python-desktop](https://github.com/Azure-Samples/ms-identity-python-desktop) | |

articles/active-directory/develop/scenario-web-api-call-api-acquire-token.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ms.tgt_pltfrm: na
1515
ms.workload: identity
1616
ms.date: 05/07/2019
1717
ms.author: jmprieur
18-
ms.custom: aaddev
18+
ms.custom: aaddev
1919
#Customer intent: As an application developer, I want to know how to write a web API that calls web APIs by using the Microsoft identity platform for developers.
2020
---
2121

@@ -25,6 +25,8 @@ After you've built a client application object, use it to acquire a token that y
2525

2626
## Code in the controller
2727

28+
# [ASP.NET Core](#tab/aspnetcore)
29+
2830
Here's an example of code that's called in the actions of the API controllers. It calls a downstream API named *todolist*.
2931

3032
```csharp
@@ -66,6 +68,33 @@ public static string GetMsalAccountId(this ClaimsPrincipal claimsPrincipal)
6668
}
6769
```
6870

71+
# [Java](#tab/java)
72+
Here's an example of code that's called in the actions of the API controllers. It calls the downstream API - Microsoft Graph.
73+
74+
```java
75+
@RestController
76+
public class ApiController {
77+
78+
@Autowired
79+
MsalAuthHelper msalAuthHelper;
80+
81+
@RequestMapping("/graphMeApi")
82+
public String graphMeApi() throws MalformedURLException {
83+
84+
String oboAccessToken = msalAuthHelper.getOboToken("https://graph.microsoft.com/.default");
85+
86+
return callMicrosoftGraphMeEndpoint(oboAccessToken);
87+
}
88+
89+
}
90+
```
91+
92+
# [Python](#tab/python)
93+
94+
A Python web API will need to use some middleware to validate the bearer token received from the client. The web API can then obtain the access token for downstream API using MSAL Python library by calling the [`acquire_token_on_behalf_of`](https://msal-python.readthedocs.io/en/latest/?badge=latest#msal.ConfidentialClientApplication.acquire_token_on_behalf_of) method. A sample demonstrating this flow with MSAL Python is not yet available.
95+
96+
---
97+
6998
## Next steps
7099

71100
> [!div class="nextstepaction"]

articles/active-directory/develop/scenario-web-api-call-api-app-configuration.md

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ms.tgt_pltfrm: na
1515
ms.workload: identity
1616
ms.date: 07/16/2019
1717
ms.author: jmprieur
18-
ms.custom: aaddev
18+
ms.custom: aaddev
1919
#Customer intent: As an application developer, I want to know how to write a web API that calls web APIs by using the Microsoft identity platform for developers.
2020
---
2121

@@ -25,6 +25,8 @@ After you've registered your web API, you can configure the code for the applica
2525

2626
The code that you use to configure your web API so that it calls downstream web APIs builds on top of the code that's used to protect a web API. For more information, see [Protected web API: App configuration](scenario-protected-web-api-app-configuration.md).
2727

28+
# [ASP.NET Core](#tab/aspnetcore)
29+
2830
## Code subscribed to OnTokenValidated
2931

3032
On top of the code configuration for any protected web APIs, you need to subscribe to the validation of the bearer token that you receive when your API is called:
@@ -44,15 +46,15 @@ public static IServiceCollection AddProtectedApiCallsWebApis(this IServiceCollec
4446
services.AddTokenAcquisition();
4547
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
4648
{
47-
// When an access token for our own web API is validated, we add it
49+
// When an access token for our own web API is validated, we add it
4850
// to the MSAL.NET cache so that it can be used from the controllers.
4951
options.Events = new JwtBearerEvents();
5052

5153
options.Events.OnTokenValidated = async context =>
5254
{
5355
context.Success();
5456

55-
// Adds the token to the cache and handles the incremental consent
57+
// Adds the token to the cache and handles the incremental consent
5658
// and claim challenges
5759
AddAccountToCacheFromJwt(context, scopes);
5860
await Task.FromResult(0);
@@ -139,6 +141,82 @@ private void AddAccountToCacheFromJwt(IEnumerable<string> scopes, JwtSecurityTok
139141
}
140142
}
141143
```
144+
# [Java](#tab/java)
145+
146+
The On-behalf-of (OBO) flow is used to obtain a token to call the downstream web API. In this flow, your web API receives a bearer token with user delegated permissions from the client application and then exchanges this token for another access token to call the downstream web API.
147+
148+
The code below uses Spring Security framework's `SecurityContextHolder` in the web API to get the validated bearer token. It then uses the MSAL Java library to obtain a token for downstream API using the `acquireToken` call with `OnBehalfOfParameters`. MSAL caches the token so that subsequent calls to the API can use `acquireTokenSilently` to get the cached token.
149+
150+
```Java
151+
@Component
152+
class MsalAuthHelper {
153+
154+
@Value("${security.oauth2.client.authority}")
155+
private String authority;
156+
157+
@Value("${security.oauth2.client.client-id}")
158+
private String clientId;
159+
160+
@Value("${security.oauth2.client.client-secret}")
161+
private String secret;
162+
163+
@Autowired
164+
CacheManager cacheManager;
165+
166+
private String getAuthToken(){
167+
String res = null;
168+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
169+
170+
if(authentication != null){
171+
res = ((OAuth2AuthenticationDetails) authentication.getDetails()).getTokenValue();
172+
}
173+
return res;
174+
}
175+
176+
String getOboToken(String scope) throws MalformedURLException {
177+
String authToken = getAuthToken();
178+
179+
ConfidentialClientApplication application =
180+
ConfidentialClientApplication.builder(clientId, ClientCredentialFactory.create(secret))
181+
.authority(authority).build();
182+
183+
String cacheKey = Hashing.sha256()
184+
.hashString(authToken, StandardCharsets.UTF_8).toString();
185+
186+
String cachedTokens = cacheManager.getCache("tokens").get(cacheKey, String.class);
187+
if(cachedTokens != null){
188+
application.tokenCache().deserialize(cachedTokens);
189+
}
190+
191+
IAuthenticationResult auth;
192+
SilentParameters silentParameters =
193+
SilentParameters.builder(Collections.singleton(scope))
194+
.build();
195+
auth = application.acquireTokenSilently(silentParameters).join();
196+
197+
if (auth == null){
198+
OnBehalfOfParameters parameters =
199+
OnBehalfOfParameters.builder(Collections.singleton(scope),
200+
new UserAssertion(authToken))
201+
.build();
202+
203+
auth = application.acquireToken(parameters).join();
204+
}
205+
206+
cacheManager.getCache("tokens").put(cacheKey, application.tokenCache().serialize());
207+
208+
return auth.accessToken();
209+
}
210+
}
211+
```
212+
213+
# [Python](#tab/python)
214+
215+
The On-behalf-of (OBO) flow is used to obtain a token to call the downstream web API. In this flow, your web API receives a bearer token with user delegated permissions from the client application and then exchanges this token for another access token to call the downstream web API.
216+
217+
A Python web API will need to use some middleware to validate the bearer token received from the client. The web API can then obtain the access token for downstream API using MSAL Python library by calling the [`acquire_token_on_behalf_of`](https://msal-python.readthedocs.io/en/latest/?badge=latest#msal.ConfidentialClientApplication.acquire_token_on_behalf_of) method. A sample demonstrating this flow with MSAL Python is not yet available.
218+
219+
---
142220

143221
You can also see an example of OBO flow implementation in [Node.js and Azure Functions](https://github.com/Azure-Samples/ms-identity-nodejs-webapi-onbehalfof-azurefunctions/blob/master/MiddleTierAPI/MyHttpTrigger/index.js#L61).
144222

0 commit comments

Comments
 (0)