2015-04-07 2 views
1

Я следил за учебниками до this point в серии. Я использую один проект в решении, который действует как как орган выдачи маркера, так и сервер ресурсов.Web Api с Owin с JWT всегда не разрешает запрос

JWT генерируется с использованием конечной точки, указанной в классе запуска, и я также проверил ее на jwt.io. Однако, когда я прохожу этот JWT с помощью почтальона на Chrome до конца API ресурс точки обеспеченных с атрибутом Authorize, я всегда нахожу это возвращение

{ «сообщение»: «Разрешение было отказано в этой просьбе» }

Другой метод api, как и в классе контроллера api ниже, работает при вызове через почтмана в Chrome.

Я использовал самые последние версии всех библиотек DLL, требуемых от консоли NuGet

код в классе запуска

public void Configuration(IAppBuilder app) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 
     ConfigureOAuthTokenGeneration(app); 
     ConfigureOAuthTokenConsumption(app); 
     WebApiConfig.Register(config); 
     app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
     app.UseWebApi(config); 
    } 


    private void ConfigureOAuthTokenGeneration(IAppBuilder app) 
    { 
     OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() 
     { 
      //For Dev enviroment only (on production should be AllowInsecureHttp = false) 
      AllowInsecureHttp = true, 
      TokenEndpointPath = new PathString("/oauth/token"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
      Provider = new CustomOAuthProvider(), 
      AccessTokenFormat = new CustomJwtFormat(ConfigurationManager.AppSettings["Issuer"]), 
     }; 

     // OAuth 2.0 Bearer Access Token Generation 
     app.UseOAuthAuthorizationServer(OAuthServerOptions); 
    } 

    private void ConfigureOAuthTokenConsumption(IAppBuilder app) 
    { 
     string issuer = ConfigurationManager.AppSettings["Issuer"]; 
     string audienceId = ConfigurationManager.AppSettings["AudienceId"]; 
     byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["AudienceSecret"]); 

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

код в пользовательских OAuthProvider

public class CustomOAuthProvider : OAuthAuthorizationServerProvider 
    { 
     public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
     { 
      context.Validated(); 
      return Task.FromResult<object>(null); 
     } 

     public override Task MatchEndpoint(OAuthMatchEndpointContext context) 
     { 
      //avoid pre-flight calls 
      if (context.OwinContext.Request.Method == "OPTIONS" && context.IsTokenEndpoint) 
      { 
       context.OwinContext.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "POST" }); 
       context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "accept", "authorization", "content-type" }); 
       context.OwinContext.Response.StatusCode = 200; 
       context.RequestCompleted(); 

       return Task.FromResult<object>(null); 
      } 

      return base.MatchEndpoint(context);  
     } 

     public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
     { 
      context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

      //setting up claims in the constructor of class UserDetails 
      UserDetails user = new UserDetails(); 
      user.UserName = context.UserName; 
      user.FirstName = "Dummy First"; 
      user.LastName = "Dummy Last"; 

      ClaimsIdentity identity = new ClaimsIdentity("JWT-BearerAuth-Test"); 
      identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); 
      foreach (string claim in user.Claims) 
      { 
       identity.AddClaim(new Claim(ClaimTypes.Role, claim));  
      } 
      var ticket = new AuthenticationTicket(identity, null); 

      context.Validated(ticket); 

     } 
    } 

Пользовательский класс JWT

public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket> 
    { 
     private readonly string _issuer = string.Empty; 

     public CustomJwtFormat(string issuer) 
     { 
      _issuer = issuer; 
     } 

     public string Protect(AuthenticationTicket data) 
     { 
      if (data == null) 
      { 
       throw new ArgumentNullException("data"); 
      } 

      string audienceId = ConfigurationManager.AppSettings["AudienceId"]; 

      string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["AudienceSecret"]; 

      var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64); 

      var signingKey = new HmacSigningCredentials(keyByteArray); 
      var issued = data.Properties.IssuedUtc; 
      var expires = data.Properties.ExpiresUtc; 
      var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey); 
      var handler = new JwtSecurityTokenHandler(); 
      var jwt = handler.WriteToken(token); 
      return jwt; 
     } 

    } 

Api контроллер Сервер ресурса в

public class AdminController : ApiController 
    { 
     //This call works 
     public IHttpActionResult ReadData(string id) 
     { 
      return Ok("ID sent in:" + id); 
     } 

     //[Authorize(Roles="EditRecord")] //doesnt work 
     [Authorize] //doesnt work either 
     public IHttpActionResult EditData(string id) 
     { 
      return Ok("Edited ID:" + id); 
     } 
    } 

Моя среда VS2013 с Framework 4.5 с использованием oauth2 с Web Api 2. Пожалуйста, извините за длинный пост.

+0

Привет, вы могли заставить эту работу работать? Я столкнулся с той же проблемой. Поиск, но не удалось найти какие-либо решения. –

ответ

0

Вы должны убедиться, что значения для эмитента, аудитории и аудиторииSecret, используемые в методе «ConfigureOAuthTokenConsumption», - это те же значения, которые использовались при создании токена JWT, позаботились о концевых косых чертах «/».

Это единственное, что приходит мне на ум прямо сейчас.

+0

Это то же самое, что и значения в файле web.config и вытащил оттуда сам. Существует только проект для создания и потребления токенов, поэтому нет никакой вероятности того, что значения будут отличаться даже по ошибке – user20358

Смежные вопросы