2016-02-07 49 views
6

Używam rozdzielonych zasobów i serwerów uwierzytelniania. Po pomyślnym uzyskaniu Tokenu JSON, sprawdzam go za pomocą jwt.io i wszystko jest ok z formatem tokena i jest tajne.Token sieciowy ASP.NET JSON "401 Nieautoryzowane"

Zapytanie jest z nagłówka Authorization:

Authorization: Bearer TOKEN_HERE 

odpowiedź jest zawsze "401.":

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

Oto moja Startup.cs z serwerem zasobów

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) 
        } 
       }); 

     } 
    } 
} 

Oto przykład odszyfrowanego tokenu:

{ 
    "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 
} 

Sprawdziłem Sekret i jest taki sam po obu stronach (serwery autoryzacji i zasobów). Mecze publiczności, emitent również. Próbowano już przejść na wersję System.IdentityModel.Tokens.Jwt do wersji 3.0.2, ale bez powodzenia

Domyślam się, że jest jakiś problem w konfiguracji konfiguracji, ale nic nie pomogło.

Wszelkie pomysły?

Odpowiedz

5

TL; DR: czy próbowałeś usunąć GlobalConfiguration.Configuration.SuppressDefaultHostAuthentication()?

Podczas korzystania z tej metody interfejs Web API usuwa nazwę użytkownika utworzoną i dodaną do kontekstu OWIN przez hosta lub przez oprogramowanie pośredniczące zarejestrowane przed Web API (w twoim przypadku przez oprogramowanie pośredniczące JWT).

Ta metoda jest przeznaczona do stosowania z HostAuthenticationFilter lub HostAuthenticationAttribute, która bezpośrednio wywołuje oprogramowanie pośredniczące uwierzytelniania odpowiadające określonemu typowi uwierzytelniania i utrzymuje wynikową nazwę użytkownika w kontekście OWIN.

Ponieważ używasz SuppressDefaultHostAuthentication bez HostAuthenticationAttribute, Web API zawsze widzi nieuwierzytelnione żądania, i dlatego są one odrzucane przez AuthorizeAttribute.

+1

To pomogło, wielkie dzięki! Myślałem, że SuppressDefaultHostAuthentication() pozwala wcześniejszej obsługi innej procedury uwierzytelniania. Zgadzam się, brakowało odpowiedniego HostAuthenticationFilter – Begunini