2015-10-28 15 views
5

Ich verwende Visual Studio 2015 Enterprise und ASP.NET vNext Beta8, um einen Endpunkt zu erstellen, der JWT-Tokens sowohl ausgibt als auch verbraucht. Ich habe mich dem ursprünglich genähert, indem ich die Token selbst erzeugt habe, wie beschrieben here. Später ergab eine hilfreiche article von @Pinpoint, dass AspNet.Security.OpenIdConnect.Server (a.k.a.OIDC) konfiguriert werden kann, um die Token für mich ausgeben und konsumieren.Validierung von Token von AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)

Also folgte ich diese Anweisungen, stand einen Endpunkt auf, und durch eine x-www-form-urlencoded Post von postman Vorlage ich ein legit Token zurückerhalten:

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

Das ist großartig, aber auch, wo ich stecken bleiben. Nun, wie notiere ich eine Controller-Aktion, so dass sie dieses Bearer-Token verlangt?

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

Und dann rufen Sie mein Controller-Aktion mit dem ":

Ich dachte, alles, was ich hätte tun müssen, ist mein Controller-Methode mit dem [autorisieren („Bearer“)] dekorieren, ein Authentifizierungsschema hinzufügen Authorization Bearer eyJ0eXAiO .... "Header wie ich es in meinem vorherigen Beispiel getan habe. Traurigerweise scheint dieser Ansatz jedoch eine Ausnahme zu erzeugen:

Während der Verarbeitung der Anforderung ist eine nicht behandelte Ausnahme aufgetreten.

Socket: Es kann keine Verbindung hergestellt werden, weil die Zielmaschine aktiv es verweigerte 127.0.0.1:50000

WebException: kann keine Verbindung zum Remote-Server

HttpRequestException verbinden: Fehler beim Senden der Anforderung.

IOException: IDX10804: Dokument konnte nicht abgerufen werden von: 'http://localhost:50000/.well-known/openid-configuration'. Microsoft.IdentityModel.Logging.LogHelper.Throw (String Nachricht, Typ Exception, Eventlevel logLevel, Exception innerexception)

InvalidOperationException: IDX10803: Kann Konfiguration erhalten, aus: 'http://localhost:50000/.well-known/openid-configuration'. Innerer Ausnahmefehler: IDX10804: Dokument kann nicht abgerufen werden von: 'http://localhost:50000/.well-known/openid-configuration'. '.


die folgenden Schritte Betrachten zu reproduzieren (aber bitte diese Produktion würdig Code nicht berücksichtigen):

  • die ASP.NET Beta8 Tooling Nehmen wie here

  • öffnen Visual Studio Enterprise 2015 und erstellen Sie eine neue Web-API Vorschauvorlage für ASP.NET 5

  • Veränderung 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": [
    ".user",
    "
    .vs PSCC“
    ]
    }

  • ändern Startup.cs wie folgt (dies ist mit freundlicher Genehmigung von @ Pinpoint der Original-Artikel; Ich habe Kommentare entfernt und hinzugefügt, um die AddAuthorization Snip):

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(); 
    } 
} 
  • ändern wizarded ValuesController.cs ein Autorisieren Attribut angeben:
[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, und erwerben Sie ein Token mit postman. Um ein Token zu erhalten, verwenden Sie x-www-form-urlencoded POST mit "grant_type" von "password", "username" irgendetwas, "password" alles und "resource" die Adresse des API-Endpunkts. Meine bestimmte URL ist zum Beispiel http://localhost:37734/authorization/v1.

  • Kopieren Sie das Base64-codierte Token, und rufen Sie dann mit dem Token den Controller für verwaltete Werte unter Verwendung von postman auf. Um das Token zu verwenden, erstellen Sie einen GET mit den Kopfzeilen Content-Type application/json und Authorization Bearer eyJ0eXAiO .... (Ihr Token). Meine spezielle URL lautet http://localhost:37734/api/values.

  • Beachten Sie die oben erwähnte Ausnahme.

Wenn der [autorisiert („Bearer“)] Ansatz, den ich oben bin versucht, die falsche Art und Weise ich wäre zu gehen, ist sehr dankbar, wenn jemand könnte mir Best Practices helfen, zu verstehen, wie Sie die JWT Token aufnehmen mit OIDC.

Vielen Dank.

+0

Hinweis: Sie sollten in Erwägung ziehen, 'options.TokenValidationParameters.ValidateAudience' zu ​​entfernen und den' resource' -Parameter zu verwenden, wenn Sie Ihre Token-Anfrage machen, da dies in einer zukünftigen Version obligatorisch werden kann. Fügen Sie einfach '& resource = http% 3A% 2F% 2Flocalhost% 3A37734% 2F' in Ihre Formulardaten (JS-Seite) ein und es sollte funktionieren. Ich habe meinen ursprünglichen Beitrag aktualisiert, um das zu erwähnen. – Pinpoint

+0

@Pinpoint, ok danke. Ich habe die Ressourcenanforderung hinzugefügt, als ich meine Token-Anfrage gemacht habe, und ein Token wie folgt zurückerhalten: { "sub": "todo", "iss": "http: // localhost: 37734 /", "aud": " http: // localhost: 37734/", " exp ": 1446131180, " nbf ": 1446127580 } Aber wenn ich Optionen ausdenke.TokenValidationParameters.ValidateAudience = false und versuche, das Token zu verwenden, das ich erhalte" IDX10208: Unable to validate publikum. validationParameters.ValidAudience ist null oder whitespace und validationParameters.ValidAudiences ist null. " – 42vogons

+0

Vergessen Sie nicht, 'options.Audience =" http: // localhost: 37734/";' zu Ihren JWT-Bearer-Authentifizierungsoptionen hinzuzufügen;) – Pinpoint

Antwort

3

options.Authority entspricht der Absenderadresse (d. H. Der Adresse Ihres OIDC-Servers).

http://localhost:50000/ scheint nicht korrekt zu sein, da Sie http://localhost:37734/ später in Ihrer Frage verwenden. Versuchen Sie, die URL zu korrigieren und versuchen Sie es erneut.

+0

danke das wars! – 42vogons

Verwandte Themen