wake-up-neo.com

ASP.NET-Web-API und OpenID Connect: Informationen zum Zugriffstoken aus dem Berechtigungscode

Ich versuche, OpenID Connect zum Laufen zu bringen ... Ein Benutzer meiner Web-API konnte einen Autorisierungscode eines OpenID Connect-Providers abrufen. Wie soll ich diesen Code an meine ASP.NET-Web-API übergeben? Wie muss ich OWIN Middleware so konfigurieren, dass ich mithilfe des Autorisierungscodes ein Zugriffstoken erhalten kann?

UPDATE: Ein SPA verwendet AJAX für die Kommunikation mit meinem Webservice (ASP.NET-Web-API). Verwenden Sie in meinem Webservice OWIN Middleware. Ich habe OpenIDConnect als Authentifizierungsmechanismus festgelegt. Wenn der Web-Service zum ersten Mal aufgerufen wird, wurde der Benutzer erfolgreich auf die Anmeldeseite des OpenID Connect-Providers weitergeleitet. Der Benutzer konnte sich anmelden und erhielt einen Berechtigungscode. AFAIK kann dieser Code (von meinem Webservice) nun für ein Access Token verwendet werden. Ich weiß jedoch nicht, wie ich diesen Code an meinen Webservice zurückbekomme (erfolgt dies mit einem Header?) Und was dann konfiguriert werden muss, um das Zugriffstoken zu erhalten. Ich denke, ich könnte den Token-Endpunkt manuell aufrufen, aber ich möchte stattdessen die OWIN-Komponente nutzen.

13
Dunken

BenV hat die Frage bereits beantwortet, aber es gibt noch mehr zu beachten.

class partial Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        // ...

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
          {
            ClientId = clientId,
            Authority = authority,
            Notifications = new OpenIdConnectAuthenticationNotifications() {
                AuthorizationCodeReceived = (context) => {
                   string authorizationCode = context.Code;
                   // (tricky) the authorizationCode is available here to use, but...
                   return Task.FromResult(0);
                }
            }
          }
    }
}

Zwei Probleme:

  • Zuerst wird authorizationCode schnell abgelaufen. Es hat keinen Sinn, es aufzubewahren.
  • Das zweite Problem ist, dass das AuthorizationCodeReceived -Ereignis nicht für das Neuladen der Seite ausgelöst wird, solange Autorisierungscode nicht abgelaufen ist und in der Sitzung gespeichert wird.

Was Sie tun müssen ist, AcquireTokenByAuthorizationCodeAsync aufzurufen, die es zwischenspeichert und ordnungsgemäß in TokenCache.DefaultShare behandelt:

AuthorizationCodeReceived = (context) => {
    string authorizationCode = context.Code;
    AuthenticationResult tokenResult = await context.AcquireTokenByAuthorizationCodeAsync(authorizationCode, new Uri(redirectUri), credential);
    return Task.FromResult(0);
}

Rufen Sie vor every an die Ressource jetzt AcquireTokenSilentAsync auf, um das accessToken abzurufen (es wird TokenCache oder automatisch refreshToken verwendet). Wenn das Token abgelaufen ist, wird eine AdalSilentTokenAcquisitionException-Ausnahme ausgelöst (Prozedur zur Erneuerung des Zugriffscodes aufgerufen).

// currentUser for ClaimsPrincipal.Current.FindFirst("http://schemas.Microsoft.com/identity/claims/objectidentifier")
AuthenticationResult authResult = await context.AcquireTokenSilentAsync(resourceUri, credential, currentUser);

Der Aufruf von AcquireTokenSilentAsync ist sehr schnell, wenn das Token zwischengespeichert wird.

11
andrew.fox

Der empfohlene Ansatz besteht darin, das Ereignis AuthorizationCodeReceived zu verwenden, um den Auth-Code für ein Zugriffstoken auszutauschen. Vittorio hat einen Blogeintrag der den Gesamtfluss umreißt.

Hier ist ein Beispiel aus dieser Beispiel-App auf GitHub des Startup.Auth.cs-Codes, um dies einzurichten:

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
        ClientId = clientId,
        Authority = Authority,
        Notifications = new OpenIdConnectAuthenticationNotifications()
        {
            AuthorizationCodeReceived = (context) =>
           {
               var code = context.Code;
               ClientCredential credential = new ClientCredential(clientId, appKey);
               string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.Microsoft.com/identity/claims/tenantid").Value;
               string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
               AuthenticationContext authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantID), new EFADALTokenCache(signedInUserID));
               AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                           code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceID);

               return Task.FromResult(0);
            },
            ...
    }

Hinweis: Das Ereignis AuthorizationCodeReceived wird nur einmal aufgerufen, wenn die Autorisierung wirklich stattfindet. Wenn der Authentifizierungscode bereits generiert und gespeichert ist, wird dieses Ereignis nicht aufgerufen. Sie müssen sich ausloggen oder Cookies löschen, um die Durchführung dieses Ereignisses zu erzwingen.

10
BenV

Sie müssen die standardmäßige Gültigkeitsprüfung von owin umgehen, um eine benutzerdefinierte Autorisierung durchzuführen:

           new OpenIdConnectAuthenticationOptions
            {
                ...,
                TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = false
                },
1
James