11

Sto cercando di ottenere un semplice endpoint che risolva i problemi e consumi i token JWT utilizzando AspNew.Security.OpenIdConnect.Server per emettere il token e convalidare using Microsoft.AspNetCore.Authentication.JwtBearer.AspNetCore.Authentication.JwtBearer non riesce con Nessun SecurityTokenValidator disponibile per il token con .net core RC2

posso generare l'un'ammenda simbolica ma cercando di autenticare il token non riesce con l'errore Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token: {token}

A questo punto ho spogliato tutto e hanno la seguente:

project.json

{ 
    "dependencies": { 
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final", 
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final", 
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final", 
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final", 
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0-rc2-final", 
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final", 
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final", 
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final", 
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final", 
    "AspNet.Security.OAuth.Validation": "1.0.0-alpha1-final", 
    "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta5-final", 
    "Microsoft.AspNetCore.Authentication": "1.0.0-rc2-final", 
    "Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0-rc2-final" 
    }, 

    "tools": { 
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": { 
     "version": "1.0.0-preview1-final", 
     "imports": "portable-net45+win8+dnxcore50" 
    } 
    }, 

    "frameworks": { 
    "net461": { } 
    }, 

    "buildOptions": { 
    "emitEntryPoint": true, 
    "preserveCompilationContext": true 
    }, 

    "publishOptions": { 
    "include": [ 
     "wwwroot", 
     "Views", 
     "appsettings.json", 
     "web.config" 
    ] 
    }, 

    "scripts": { 
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] 
    } 
} 

metodi Startup.cs:

// This method gets called by the runtime. Use this method to add services to the container. 
     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddAuthorization(options => 
       { 
        options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, 
         builder => 
         { 
          builder. 
          AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme). 
          RequireAuthenticatedUser(). 
          Build(); 
         } 
        ); 
       } 
      ); 

      services.AddAuthentication(); 
      services.AddDistributedMemoryCache(); 
      services.AddMvc(); 
      services.AddOptions(); 
     } 

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
      loggerFactory.AddDebug(); 

      var jwtOptions = new JwtBearerOptions() 
      { 
       AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme, 
       AutomaticAuthenticate = true, 
       Authority = "http://localhost:5000/", 
       Audience = "http://localhost:5000/", 
       RequireHttpsMetadata = false 
      }; 

      jwtOptions.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration> 
       (
        metadataAddress: jwtOptions.Authority + ".well-known/openid-configuration", 
        configRetriever: new OpenIdConnectConfigurationRetriever(), 
        docRetriever: new HttpDocumentRetriever { RequireHttps = false } 
       ); 


      app.UseJwtBearerAuthentication(jwtOptions); 

      app.UseOpenIdConnectServer(options => 
      { 
       options.AllowInsecureHttp = true; 
       options.AuthorizationEndpointPath = Microsoft.AspNetCore.Http.PathString.Empty; 
       options.Provider = new OpenIdConnectServerProvider 
       { 
        OnValidateTokenRequest = context => 
        { 
         context.Skip(); 
         return Task.FromResult(0); 
        }, 

        OnGrantResourceOwnerCredentials = context => 
        { 
         var identity = new ClaimsIdentity(context.Options.AuthenticationScheme); 
         identity.AddClaim(ClaimTypes.NameIdentifier, "[unique id]"); 

         identity.AddClaim("urn:customclaim", "value", OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); 

         var ticket = new AuthenticationTicket(
          new ClaimsPrincipal(identity), 
          new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties(), 
          context.Options.AuthenticationScheme); 

         ticket.SetScopes("profile", "offline_access"); 

         context.Validate(ticket); 

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

      app.UseMvc(); 
     } 

invio POST x-url-codificato a http://localhost:5000 con grant_type = password, username = foo, password = bar genera il token di accesso previsto.

Ho aggiunto l'attributo [Authorize("Bearer")] al ValuesController e questo funziona come previsto nel JwtBearerMiddlewear è invocato ma non riesco a ottenere il token da convalidare.

Qualcuno ha funzionato con .net core RC2? Ho avuto la stessa cosa lavorando su RC1 ma non sono riuscito a farlo funzionare.

Grazie.

risposta

8

A partire da beta5 (per ASP.NET Core RC2), the OpenID Connect server middleware no longer uses JWT as the default format for access tokens. Al contrario, utilizza token opachi, crittografati dallo stack solido di ASP.NET Core Data Protection (esattamente come i cookie di autenticazione).

avete 3 opzioni per correggere l'errore che state vedendo:

  • Utilizzare le new OAuth2 validation middleware sviluppati per supportare i token opache (l'opzione consigliata, se il vostro API e il vostro server di autorizzazione sono parte dello stesso app). Per questo, mantieni il riferimento AspNet.Security.OAuth.Validation in project.json e sostituisci . Puoi anche rimuovere Microsoft.AspNetCore.Authentication.JwtBearer da project.json.

  • Forza il middleware server OpenID Connect per usare i token JWT chiamando options.AccessTokenHandler = new JwtSecurityTokenHandler(); nelle opzioni. Nota che dovrai anche chiamare ticket.SetResources(...) per collegare il pubblico appropriato con i token JWT (vedi questo altro SO post per ulteriori informazioni).

  • Utilizzare la new introspection middleware. Questa opzione è più complessa e richiede l'implementazione dell'evento ValidateIntrospectionRequest per convalidare le credenziali del client. Usalo solo se sai cosa stai facendo.
+0

Se si decide di utilizzare l'introspezione, il pacchetto desiderato è [qui] (https://www.nuget.org/packages/AspNet.Security.OAuth.Introspection/). Non "AspNet.Security.OAuth.Extensions" – paulio