2017-03-14 3 views
0

Ich habe das Szenario "Server-Anwendung, die auf ein Web-API zugreift".Die Verwendung des client_credentials-Flusses mit ADFS 4.0 gibt 401 zurück

Die Website verwendet OIDC und authentifiziert kein Problem.

Allerdings habe ich einen Anwendungsfall für den Zugriff auf einige der Web-API ohne Benutzerkontext und dafür verwende ich client_credentials.

Die Server-App hat eine Client-ID und den geheimen Schlüssel.

So übernimmt die Web-API-URL ist:

https://my-pc/WebService/api/my-api/

Der Web-API, um die RP-Kennung hat:

https://my-pc/WebService/api/my-api/

Zutrittskontrollpolitik ist:

Permit jeden

Ich habe eine Anspruchregel:

c: [] => issue (claim = c);

Client-Berechtigungen festgelegt ist:

"Alle Kunden" mit Rahmen von OpenID und user_impersonation.

Der Code ist:

AuthenticationContext ac = new AuthenticationContext("https://my-adfs/adfs/", false); 
// ClientCredential contains client_id and secret key 
AuthenticationResult result = await ac.AcquireTokenAsync("https://my-pc/WebService/api/my-api/", clientCredential); 

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://my-pc/WebService/api/my-api/"); 
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); 

HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("foo", "blah"), new KeyValuePair<string, string>("foo1", "blah1") }); 
request.Content = content; 
HttpResponseMessage response = await client.SendAsync(request); 

ADFS kehrt der Zugang kein Problem Token, aber wenn ich die Web-API-Aufruf, halte ich ein 401 bekommen - nicht authentifiziert.

Irgendwelche Ideen?

Antwort

0

Da Sie den Benutzerprinzipal nicht im Zugriffstoken erhalten, haben Sie keine Benutzersitzung an einen Principal angehängt. Wenn die Web-API im Cookie nach dem Prinzipal sucht (oder nach dem Autorisierungsheader, wenn Sie ein Zugriffstoken senden), wird der Prinzipal nicht gefunden, und Sie sind weiterhin ein anonymer Benutzer.

+0

Welcher Benutzerprinzipal? Es gibt keinen Benutzer. – nzpcmad

+0

Richtig! Aber aus Sicht der Web-API ist die Server-Anwendung der Benutzer, richtig? Wenn Sie ein Zugriffs-Token an die API senden, verwendet es einen Parser zum Dekodieren der JWT und liest den Principal. Da das Token kein Benutzerprinzipal hat, wird es einfach 401 zurückgeben. – krishna

+0

Ich denke, es hängt davon ab, wie Sie mit der Web-API kommunizieren. Wir verwenden zur Zeit auth_code flow in unserer Anwendung. In meinem Fall erhält der Client ein Zugriffstoken, nachdem der Benutzer authentifiziert wurde, wir analysieren ihn für Ansprüche und laden den Sicherheitskontext. Wir erstellen eine neue JWT (mit Principal) und übergeben sie an die Ressource, auf die der Benutzer zugreifen möchte. Diese Ressource dekodiert das JWT und erkennt den Benutzer.Jetzt versuchen wir, den client_credentials-Ablauf zu erreichen, da wir keinen Principal vom Zugriffstoken erhalten, die Ressource den Benutzer vom JWT nicht erkennt. – krishna

1

Endlich herausgefunden, und wrote it up.

Die beiden Teile des Codes:

using Microsoft.IdentityModel.Clients.ActiveDirectory; 

ClientCredential clientCredential = new ClientCredential(clientId, secretKey); 

AuthenticationContext ac = new AuthenticationContext("https://my-adfs/adfs/", false); 
AuthenticationResult result = await ac.AcquireTokenAsync("https://my-pc/WebService", 

clientCredential); 

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, 

"https://my-pc/WebService/api/my-api/"); 
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); 

HttpContent content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, 

string>("foo", "blah"), new KeyValuePair<string, string>("foo1", "blah1") }); 
request.Content = content; 
HttpResponseMessage response = await client.SendAsync(request); 

if (response.IsSuccessStatusCode) 
    // etc 

Und in Startup.Auth.cs

app.UseActiveDirectoryFederationServicesBearerAuthentication(
    new ActiveDirectoryFederationServicesBearerAuthenticationOptions 
    { 
     TokenValidationParameters = new TokenValidationParameters() 
     { 
      SaveSigninToken = true, 
      ValidAudience = "https://my-pc/WebService" 
     }, 

     MetadataEndpoint = "https://my-adfs/FederationMetadata/2007-06/FederationMetadata.xml" 
}); 

mir dauerte eine Weile!

Verwandte Themen