10

I am implementing an OAuth2 provider for OWIN and Azure Active Director. FWIW, at this time the OpenId Connect option doesn't fit the requirements for this work.

I get an auth code, and returned to my reply url with the auth_code, state, and make the request for a token to "scheme://login.windows.net/{myguid}/oauth2/token.

 // Build up the body for the token request
 var body = new List<KeyValuePair<string, string>>();
 body.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
 body.Add(new KeyValuePair<string, string>("code", code));
 body.Add(new KeyValuePair<string, string>("redirect_uri", redirectUri));
 body.Add(new KeyValuePair<string, string>("client_id", Options.ClientId));
 body.Add(new KeyValuePair<string, string>("client_secret", Options.ClientSecret));

 // Request the token
 HttpResponseMessage tokenResponse =
     await httpClient.PostAsync(TokenEndpoint, new FormUrlEncodedContent(body));
 string text = await tokenResponse.Content.ReadAsStringAsync();
 tokenResponse.EnsureSuccessStatusCode();

I get this error:

{"error":"invalid_resource","error_description":"AADSTS50001: Resource identifier is not provided.
Trace ID: 227f2af8-0837-4f22-ac0f-a09b3f9a6d50
Correlation ID: 3d783f11-44d0-4efa-8831-3dd581d653ed
Timestamp: 2014-08-08 21:59:49Z","error_codes":[50001],"timestamp":"2014-08-08 21:59:49Z","trace_id":"227f2af8-0837-4f22-ac0f-a09b3f9a6d50","correlation_id":"3d783f11-44d0-4efa-8831-3dd581d653ed"}

OK, I add the resource option:

 // Build up the body for the token request
 var body = new List<KeyValuePair<string, string>>();
 body.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
 body.Add(new KeyValuePair<string, string>("code", code));
 body.Add(new KeyValuePair<string, string>("redirect_uri", redirectUri));
 body.Add(new KeyValuePair<string, string>("client_id", Options.ClientId));
 body.Add(new KeyValuePair<string, string>("client_secret", Options.ClientSecret));
 body.Add(new KeyValuePair<string, string>("resource", "https://myappid"));

{"error":"invalid_request","error_description":"AADSTS90027: The client 'xxxxx' and resource 'https://myappid' identify the same application.
Trace ID: 6c77f123-d75f-43a9-8117-b3f372891ee4
Correlation ID: d9081f8b-b690-4478-bf15-55325a9736ec
Timestamp: 2014-08-08 21:48:34Z","error_codes":[90027],"timestamp":"2014-08-08 21:48:34Z","trace_id":"6c77f123-d75f-43a9-8117-b3f372891ee4","correlation_id":"d9081f8b-b690-4478-bf15-55325a9736ec"}

so I must have the correct app id associated with my client id. hrrmph! I am clearly doing something wrong but just can't seem to see it. Any suggestions?

Philip Nelson
  • 985
  • 6
  • 20
  • [Had the same question](http://stackoverflow.com/questions/28415234/whats-wrong-with-this-authorization-exchange), with some extra complications -- I wish I had found this before. :) – Lars Kemmann Feb 11 '15 at 00:31

3 Answers3

22

I had the same problem, i just wanted to implement a user-login.

After trying 1000 things (with this post amongst others) i found out that i can use the Microsoft.Azure.ActiveDirectory-id as resource paramter. On this way i don't have to create an second app.

http://blogs.msdn.com/b/besidethepoint/archive/2012/10/23/getting-started-with-azure-active-directory.aspx

nameValuePairs.add(new BasicNameValuePair("resource", "00000002-0000-0000-c000-000000000000"));

and got the token

UPDATE:

the azure support suggested me to use https://graph.windows.net/ :

nameValuePairs.add(new BasicNameValuePair("resource", "https://graph.windows.net/"));
wutzebaer
  • 14,365
  • 19
  • 99
  • 170
  • I've used `resource=https://graph.windows.net/` to solve this problem too and it works a treat. But what does this actually mean? – dvdsmpsn Aug 30 '16 at 22:02
  • "resource" says which resource i want to access with the token i just requested – wutzebaer Aug 31 '16 at 07:31
9

Using the "openid" scope in the authorization request should trigger an OpenID Connect flow that would return an id_token and does not require a resource.

gye
  • 1,374
  • 3
  • 16
  • 27
  • Trying to integrate with KeyCloak and Azure Active Directory. Filling nothing in default resource makes the integration success. – Brian Ng Jan 08 '19 at 08:20
6

OAuth deals with 4 parties: 1) resource owner aka user 2) resource app: usually a Web API that protects access to resources owner by the user 3) client app: a web app or mobile app or even another Web API that wants to access the resource on-behalf of the user 4) the authority: the secure token service that authenticates the user and/or the client app and issues a delegated access token to the client to access the resource.

Your code is using the same identifier for the client app as well as the resource - essentially it is trying to request for an access token to access itself. It can be argued that this scenario should be allowed - but it isn't today by Azure AD.

Please do the following: register a resource application in Azure AD. In its manifest add a new an appPermission (follow this post). Then, go to the client application configuration page and scroll to the bottom - in the 'Permissions to other applications' section, add the resource permission to the client applications list of "delegated permissions".

Now, use the resource application's AppIDURI or ClientID in your OAuth request and stuff should work.

Hope this helps.

dvdsmpsn
  • 2,839
  • 1
  • 26
  • 40
Dushyant Gill
  • 3,966
  • 18
  • 14
  • Thanks, seems there are a few gaps for me to pick up in my understanding. I will check this out tomorrow night. – Philip Nelson Aug 09 '14 at 17:22
  • I marked it as the answer though I haven't completed working. My next surprise was that after adding the app permission, it is only available in *other* applications. Seems very odd to me, I add an application for my external api, but to use it I have to add another application, a resource as you put it, and then give it permissions. In other providers, say Google, i just add the application and give it permissions. What distinguishes and application from a resource? – Philip Nelson Aug 11 '14 at 04:27
  • Hi Phillip, can you briefly explain your scenario: e.g. "I am trying to secure access to a web API, which mobile apps will access on behalf of an Azure AD user" – Dushyant Gill Aug 11 '14 at 05:41
  • We are building some prepatory code to use to evaluate some external identity providers, including an on premise ADFS and two external providers that will do Oauth2 or WSFed. These providers will be used to to authenticate users of a web site which in turn uses an internal api we also hope to have delegated access to so we can log/audit actual users. We settled on aspnet.identity as it seemed to cover a broader range of options. – Philip Nelson Aug 11 '14 at 12:06
  • By adding a second application, a unique claim via the manifest, and a permission in my original application I was able to get a token. The last step is using to retrieve the user info from the graph api "me" link I think. Still not fully grokking this model. The authority, #4 in the answer is in my mind the directory, but in this model, it is another application of the directory protecting a resource identified by another application. – Philip Nelson Aug 11 '14 at 13:17
  • Oh so your web app was able to get a token for the web API? I am glad. If your web app also wants to call the Graph API, it can get an access token for it too, by just redeeming the refresh token that it got in the first call for an access token for graph. Do this: Read through our topic here http://msdn.microsoft.com/en-us/library/azure/dn499820.aspx, and if you still have questions - I will be happy to answer. You can reach me at http://www.dushyantgill.com/blog/contact – Dushyant Gill Aug 12 '14 at 06:02