2016-02-07 38 views
6

Utilizzo server di autenticazione e risorse disaccoppiati. Quando ottengo con successo il token Web JSON, lo controllo con jwt.io e tutto è a posto con il formato token ed è segreto.Token Web ASP.NET JSON "401 Non autorizzato"

richiesta è con intestazione autorizzazione:

Authorization: Bearer TOKEN_HERE 

risposta è sempre "401 Unauthorized":

{ 
    "message": "Authorization has been denied for this request." 
} 

Ecco il mio Startup.cs dai server risorsa

using Microsoft.Owin; 
using Microsoft.Owin.Cors; 
using Microsoft.Owin.Security; 
using Microsoft.Owin.Security.Jwt; 
using Newtonsoft.Json.Serialization; 
using Owin; 
using System.Web.Http; 
using Test.Database; 
using Test.Infrastructure; 
using Microsoft.WindowsAzure.ServiceRuntime; 

[assembly: OwinStartup(typeof(Test.API.Startup))] 
namespace Custodesk.API 
{ 
    public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      app.CreatePerOwinContext(() => 
       ApplicationDbContext.Create(RoleEnvironment.GetConfigurationSettingValue("SqlConnectionString"))); 
      app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

      GlobalConfiguration.Configuration.SuppressDefaultHostAuthentication(); 

      ConfigureOAuthTokenConsumption(app); 

      GlobalConfiguration.Configure(config => 
      { 
       //global filters 
       config.Filters.Add(new AuthorizeAttribute()); 

       // Web API routes 
       config.MapHttpAttributeRoutes(); 
       config.Routes.MapHttpRoute(
        name: "DefaultApi", 
        routeTemplate: "{controller}/{action}/{id}", 
        defaults: new { id = RouteParameter.Optional } 
       ); 

       config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
      }); 

      app.UseCors(CorsOptions.AllowAll); 

      app.UseWebApi(GlobalConfiguration.Configuration); 
     } 

     private void ConfigureOAuthTokenConsumption(IAppBuilder app) 
     { 
      var issuer = "http://localhost"; 
      var audience = "Universal_application"; 
      var secret = Helper.GetHash("helper_class_to_get_the_same_hash_as_authentication_server"); 

      // Api controllers with an [Authorize] attribute will be validated with JWT 
      app.UseJwtBearerAuthentication(
       new JwtBearerAuthenticationOptions 
       { 
        AuthenticationMode = AuthenticationMode.Active, 
        AllowedAudiences = new[] { audience }, 
        IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
        { 
         new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) 
        } 
       }); 

     } 
    } 
} 

Ecco un esempio di token decrittografato:

{ 
    "typ": "JWT", 
    "alg": "HS256" 
} 
{ 
    "nameid": "b22a825e-60ce-45ed-b2cb-b2ee46a47936", 
    "unique_name": "begunini", 
    "role": [ 
    "Owner", 
    "Admin", 
    "ManagerViewer" 
    ], 
    "iss": "http://localhost", 
    "aud": "Universal_application", 
    "exp": 1454876502, 
    "nbf": 1454876202 
} 

Ho controllato il segreto ed è lo stesso su entrambi i lati (server di autenticazione e risorse). Partite di pubblico, anche l'emittente. Già provato a eseguire il downgrade di System.IdentityModel.Tokens.Jwt alla versione 3.0.2 ma senza fortuna

Suppongo che ci sia qualche problema nell'ordine di configurazione, ma nulla è servito.

Qualche idea?

risposta

5

TL; DR: hai provato a rimuovere GlobalConfiguration.Configuration.SuppressDefaultHostAuthentication()?

Quando si utilizza questo metodo, Web API rimuove l'utente principale creato e aggiunto al contesto OWIN dall'host o dal middleware registrato prima dell'API Web (nel caso specifico dal middleware del portatore JWT).

Questo metodo deve essere utilizzato con HostAuthenticationFilter o HostAuthenticationAttribute, che richiama direttamente il middleware di autenticazione corrispondente al tipo di autenticazione specificato e persiste l'utente principale risultante nel contesto OWIN.

Poiché si utilizza SuppressDefaultHostAuthentication senza HostAuthenticationAttribute, l'API Web vede sempre le richieste non autenticate ed è per questo che vengono rifiutate da AuthorizeAttribute.

+1

Questo ha aiutato, grazie mille! Ho pensato che SuppressDefaultHostAuthentication() consenta a un altro gestore di autenticazione di essere precedente. D'accordo, mancava l'appropriato HostAuthenticationFilter – Begunini