Validierungstoken, die von AspNet.Security.OpenIdConnect.Server (ASP.NET vNext) ausgegeben werden

Ich verwende Visual Studio 2015 Enterprise und ASP.NET vNext Beta8, um einen Endpunkt zu erstellen, der JWT-Token ausgibt und verwendet. Ich näherte mich dem ursprünglich, indem ich die Token selbst generierte, wie beschriebenHie. Später eine hilfreicheArtike by @Pinpoint hat ergeben, dass AspNet.Security.OpenIdConnect.Server (a.k.a. OIDC) so konfiguriert werden kann, dass die Token für mich ausgegeben und verwendet werden.

So befolgte ich diese Anweisungen, stellte mich auf einen Endpunkt und schickte einen x-www-form-urlencoded Post vonPostbot Ich erhalte ein legitimes Token zurück:

{
  "token_type": "bearer",
  "access_token": "eyJ0eXAiO....",
  "expires_in": "3599"
}

Das ist aber auch toll, wo ich stecken bleibe. Wie kann ich nun eine Controller-Aktion mit Anmerkungen versehen, sodass sie dieses Inhaber-Token anfordert?

Ich dachte, ich müsste nur meine Controller-Methode mit [Authorize ("Bearer")] dekorieren und ein Authentifizierungsschema hinzufügen:

        services.AddAuthorization
        (
            options => 
            {
                options.AddPolicy
                (
                    JwtBearerDefaults.AuthenticationScheme, 
                    builder => 
                    {
                        builder.
                        AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
                        RequireAuthenticatedUser().
                        Build();
                    } 
                );
            }
        );

Und dann rufe meine Controller-Aktion mit der Überschrift "Authorization Bearer eyJ0eXAiO ...." auf, wie ich es in meinem vorherigen Beispiel getan hatte. Leider scheint dieser Ansatz nur eine Ausnahme zu generieren:

Bei der Verarbeitung der Anforderung ist eine nicht behandelte Ausnahme aufgetreten.

SocketException: Es konnte keine Verbindung hergestellt werden, da der Zielcomputer dies aktiv abgelehnt hat. 127.0.0.1:5000

WebException: Verbindung zum Remote-Server kann nicht hergestellt werden

HttpRequestException: Beim Senden der Anforderung ist ein Fehler aufgetreten.

IOException: IDX10804: Dokument kann nicht abgerufen werden von: 'http: // localhost: 50000 / .well-known / openid-configuration '. Microsoft.IdentityModel.Logging.LogHelper.Throw (Zeichenfolgenmeldung, Typ exceptionType, EventLevel logLevel, Ausnahme innerException)

InvalidOperationException: IDX10803: Konfiguration kann nicht abgerufen werden von: 'http: // localhost: 50000 / .well-known / openid-configuration '. Innere Ausnahme: 'IDX10804: Dokument kann nicht abgerufen werden von:'http: // localhost: 50000 / .well-known / openid-configuration '.'.


Betrachten Sie die folgenden Schritte zur Reproduktion (betrachten Sie diesen produktionswürdigen Code jedoch nicht):

enden Sie das ASP.NET Beta8-Tool wie beschrieben aHie

Öffnen Sie Visual Studio Enterprise 2015 und erstellen Sie ein neues Web-API-ASP.NET 5-Vorschau-Vorlagenprojekt.

Change project.json

{
"webroot": "wwwroot",
"version": "1.0.0 - *",

"Abhängigkeiten":
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-beta8",
"Microsoft.AspNet.Mvc": "6.0.0-beta8",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-beta8",
"Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-beta8",
"AspNet.Security.OpenIdConnect.Server": "1.0.0-beta3",
"Microsoft.AspNet.Authentication.OpenIdConnect": "1.0.0-beta8",
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4",
"Microsoft.AspNet.Diagnostics": "1.0.0-beta8"
},

"Befehle":
"web": "Microsoft.AspNet.Server.Kestrel"
},

"frameworks":
"dnx451": {}
},

"ausschließen":
"wwwroot",
"node_modules"
],
"publishExclude":
".Benutzer"
"
.vspscc "
]
}

Change Startup.cs wie folgt (mit freundlicher Genehmigung von @Pinpoints Originalartikel; ich habe Kommentare entfernt und den Snip "AddAuthorization" hinzugefügt):

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthorization
        (
            options => 
            {
                options.AddPolicy
                (
                    JwtBearerDefaults.AuthenticationScheme, 
                    builder => 
                    {
                        builder.
                        AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
                        RequireAuthenticatedUser().
                        Build();
                    } 
                );
            }
        );
        services.AddAuthentication();
        services.AddCaching();
        services.AddMvc();
        services.AddOptions();
    }

    // Configure is called after ConfigureServices is called.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<AppSettings> appSettings)
    {
        app.UseDeveloperExceptionPage();

        // Add a new middleware validating access tokens issued by the OIDC server.
        app.UseJwtBearerAuthentication(options => {
            options.AutomaticAuthentication = true;
            options.Audience = "http://localhost:50000/";
            options.Authority = "http://localhost:50000/";
            options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
            (
                metadataAddress : options.Authority + ".well-known/openid-configuration",
                configRetriever : new OpenIdConnectConfigurationRetriever(),
                docRetriever    : new HttpDocumentRetriever { RequireHttps = false }
            );
        });

        // Add a new middleware issuing tokens.
        app.UseOpenIdConnectServer
        (
            configuration => 
            {
                configuration.Options.TokenEndpointPath= "/authorization/v1";
                configuration.Options.AllowInsecureHttp = true;
                configuration.Provider = new OpenIdConnectServerProvider {

                    OnValidateClientAuthentication = context => 
                    {
                        context.Skipped();
                        return Task.FromResult<object>(null);
                    },

                    OnGrantResourceOwnerCredentials = context => 
                    {
                        var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
                        identity.AddClaim( new Claim(ClaimTypes.NameIdentifier, "todo")  );
                        identity.AddClaim( new Claim("urn:customclaim", "value", "token id_token"));
                        context.Validated(new ClaimsPrincipal(identity));
                        return Task.FromResult<object>(null);
                    }
                };
            }
        );

        app.UseMvc();
    }
}
Change wizarded ValuesController.cs an, um ein Authorize-Attribut anzugeben:
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET: api/values
    [Authorize("Bearer")] 
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

Führen Sie das Projekt aus und erwerben Sie ein Token mitPostbot. Um ein Token zu erwerben, verwenden Sie den x-www-form-urlencoded POST mit "grant_type" von "password", "username" von "anything", "password" von "anything" und "resource" der Adresse des API-Endpunkts. Meine spezielle URL ist zum Beispielhttp: // localhost: 37734 / authority / v1.

Kopieren Sie das Base64-codierte Token und rufen Sie mit dem Token den Controller für assistierte Werte mit @ auPostbot. Um das Token zu verwenden, erstellen Sie ein GET mit den Headern Content-Type application / json und Authorization bearer eyJ0eXAiO .... (Ihr Token). Meine bestimmte URL isthttp: // localhost: 37734 / api / values.

Beachten Sie die oben erwähnte Ausnahme.

Wenn der oben beschriebene [Authorize ("Bearer")] - Ansatz der falsche Weg ist, wäre ich sehr dankbar, wenn mir jemand helfen könnte, bewährte Methoden für die Aufnahme des JWT-Tokens mit OIDC zu verstehen.

Vielen Dank

Antworten auf die Frage(2)

Ihre Antwort auf die Frage