2015-06-13 38 views
7

Bir HTTP başlığı olarak (Azure Mobil Hizmetler tarafından verilmiş) Bu JWT'yi geçmek deneyin/Yetkilendirme/Hamiline jetonu: yapılandırılmış benim ASP.NET WEB API içineNeden SecurityTokenSignatureKeyNotFoundException alıyorum?

Header: 
{ 
    "alg": "HS256", 
    "typ": "JWT", 
    "kid": "0" 
} 
Claims: 
{ 
    "ver": 2, 
    "aud": "Facebook", 
    "iss": "urn:microsoft:windows-azure:zumo", 
    "urn:microsoft:credentials": "pYK8b5...", 
    "exp": 1436730730, 
    "uid": "Facebook:10000xxxxxxxxxx" 
} 

:

const string issuer = "urn:microsoft:windows-azure:zumo"; 
byte[] mobileServicesSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:SecretKey"]); 

app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions 
    { 
     AuthenticationMode = AuthenticationMode.Active, 
     AllowedAudiences = new[] { "Facebook" }, 
     IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
       { 
        new SymmetricKeyIssuerSecurityTokenProvider(issuer, mobileServicesSecret) 
       } 
    }); 

ben olsun:

tip 'System.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException' ilk şansını istisna Sist oluştu em.IdentityModel.Tokens.Jwt.dll

Bunun nedeni "çocuk" özelliğinin varlığı olduğundan şüpheleniyorum.

DÜZENLEME: Bu https://github.com/Magenic/JWTvalidator/tree/master/JwtValidator/JwtValidator'u kullanarak, JWT'yi doğrulamak mümkündür, bu yüzden yanlış bir şey yoktur. Ama gerçekten OWIN/Katana'yı kullanmak istiyorum.

+0

Bu sorunun üstesinden gelebilir misiniz? Bununla takılıyorum. Kodu verebilir misiniz? –

+0

@KunalB. hayır, üzgünüm Owin/Katana'yı kullanmak için bir çözüm bulamadım. Bağlantıdaki JwtValidator sınıfını kullanmalı ve doğrulamak için özel bir Kimlik Doğrulama özelliğini kullanmalıyım. Microsoft en iyi yaptıkları şeyi yapar; Bir ekip (Azure Mobiles Services ekibi) çitin bir tarafında oturuyor, diğer (ASP.NET ekibi) diğer tarafta oturuyor ve muhtemelen birbirleriyle hiç konuşmamışlar ... :( –

+0

2 gün sonra Ben - http://markwalsh.io/development/2014/12/02/ASP.Net%20Web%20API%20with%20JWT/ Bu benim için çalıştı.Hata ayıklama sırasında hala bazı garip mesaj alıyorum. –

cevap

0

Google şu anlaşılacağı - Calling the tokeninfo endpoint

yerine bu doğrulama adımlarını gerçekleştirmek için kendi kod yazma, biz şiddetle platformu için Google API istemci kitaplığı kullanarak veya bizim tokeninfo doğrulama uç noktasını çağırarak tavsiye .

tokeninfo bitiş noktasını kullanarak bir ID belirtecini doğrulamak için, uç noktaya bir HTTPS POST veya GET isteği yapın ve kimlik kodunuzu id_token parametresine iletin. Örneğin, belirteç "XYZ123", aşağıdaki GET isteğinde bulunması doğrulamak için:

CustomJwtHandler.cs

using System; 
using System.Collections.Generic; 
using System.IdentityModel.Tokens; 
using System.Linq; 
using System.Net.Http; 
using System.Web; 
using System.Web.Configuration; 
using Newtonsoft.Json; 
using System.Net; 
using System.Threading.Tasks; 
using System.Threading; 
using Services.Models; 
using System.Security.Claims; 

namespace Services 
{ 
    /// <summary> 
    /// This is an implementation of Google JWT verification that 
    /// demonstrates: 
    /// - JWT validation 
    /// </summary> 
    /// @author [email protected] (Kunal Bajpai) 


    public class CustomJwtHandler : DelegatingHandler 
    { 
     private const string URL_GOOGLE_TOKEN_INFO = "https://www.googleapis.com/oauth2/v3/tokeninfo"; 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="request"></param> 
     /// <param name="cancellationToken"></param> 
     /// <returns></returns> 
     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
     { 
      HttpStatusCode statusCode; 
      string token; 

      var authHeader = request.Headers.Authorization; 
      if (authHeader == null) 
      { 
       // Missing authorization header 
       return base.SendAsync(request, cancellationToken); 
      } 

      if (!TryRetrieveToken(request, out token)) 
      { 
       return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.Unauthorized)); 
      } 

      try 
      { 
       ValidateToken(token); 
       return base.SendAsync(request, cancellationToken); 
      } 
      catch (SecurityTokenInvalidAudienceException) 
      { 
       statusCode = HttpStatusCode.Unauthorized; 
      } 
      catch (SecurityTokenValidationException) 
      { 
       statusCode = HttpStatusCode.Unauthorized; 
      } 
      catch (Exception) 
      { 
       statusCode = HttpStatusCode.InternalServerError; 
      } 

      return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode)); 
     } 
     /// <summary> 
     /// Validates JWT Token 
     /// </summary> 
     /// <param name="JwtToken"></param> 
     private void ValidateToken(string JwtToken) 
     { 
      try 
      { 
       using (WebClient wc = new WebClient()) 
       { 
        TokenInfo tokenInfo = JsonConvert.DeserializeObject<TokenInfo>(wc.DownloadString(URL_GOOGLE_TOKEN_INFO + "?id_token=" + JwtToken)); 

        ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(ExtractClaims(tokenInfo), tokenInfo.Issuer)); 

        Thread.CurrentPrincipal = claimsPrincipal; 
        HttpContext.Current.User = claimsPrincipal; 
       } 
      } 
      catch (WebException e) 
      { 
       HttpStatusCode statusCode = ((HttpWebResponse)e.Response).StatusCode; 
       if (statusCode == HttpStatusCode.BadRequest) 
       { 
        throw new SecurityTokenValidationException(); 
       } 
       else 
       { 
        throw new Exception(); 
       } 
      } 
     } 

     /// <summary> 
     /// Tries to retrieve Token 
     /// </summary> 
     /// <param name="request"></param> 
     /// <param name="token"></param> 
     /// <returns></returns> 
     private static bool TryRetrieveToken(HttpRequestMessage request, out string token) 
     { 
      token = null; 
      IEnumerable<string> authorizationHeaders; 

      if (!request.Headers.TryGetValues("Authorization", out authorizationHeaders) || 
      authorizationHeaders.Count() > 1) 
      { 
       return false; 
      } 

      var bearerToken = authorizationHeaders.ElementAt(0); 
      token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken; 
      return true; 
     } 

     private List<Claim> ExtractClaims(TokenInfo tokenInfo) 
     { 
      List<Claim> claims = new List<Claim> { 
       new Claim(ClaimTypes.Name, tokenInfo.Name), 
       new Claim(ClaimTypes.Email, tokenInfo.Email), 
       new Claim(ClaimTypes.GivenName, tokenInfo.GivenName), 
       new Claim(ClaimTypes.Surname, tokenInfo.FamilyName), 
       new Claim(ApplicationUser.CLAIM_TYPE_LOCALE, tokenInfo.Locale), 
       new Claim(ClaimTypes.NameIdentifier, tokenInfo.ProviderKey, ClaimValueTypes.String, tokenInfo.Issuer), 
       new Claim(ApplicationUser.CLAIM_TYPE_EMAIL_CONFIRMED, tokenInfo.IsEmailVerifed.ToString(), ClaimValueTypes.Boolean) 
      }; 

      return claims; 
     } 
    } 
} 

TokenInfo.cs

using Microsoft.AspNet.Identity.EntityFramework; 
using Newtonsoft.Json; 

namespace Services.Models 
{ 
    public class TokenInfo 
    { 
     [JsonProperty("iss")] 
     public string Issuer { get; set; } 

     [JsonProperty("aud")] 
     public string AudienceClientId { get; set; } 

     [JsonProperty("sub")] 
     public string ProviderKey { get; set; } 

     [JsonProperty("email_verified")] 
     public bool IsEmailVerifed { get; set; } 

     [JsonProperty("azp")] 
     public string AndroidClientId { get; set; } 

     [JsonProperty("email")] 
     public string Email { get; set; } 

     [JsonProperty("iat")] 
     public long IssuedAt { get; set; } 

     [JsonProperty("exp")] 
     public long ExpiresAt { get; set; } 

     [JsonProperty("name")] 
     public string Name { get; set; } 

     [JsonProperty("picture")] 
     public string Picture { get; set; } 

     [JsonProperty("given_name")] 
     public string GivenName { get; set; } 

     [JsonProperty("family_name")] 
     public string FamilyName { get; set; } 

     [JsonProperty("locale")] 
     public string Locale { get; set; } 

     [JsonProperty("alg")] 
     public string Algorithm { get; set; } 

     [JsonProperty("kid")] 
     public string kid { get; set; } 

     public override bool Equals(object obj) 
     { 
      if (obj.GetType() != typeof(ApplicationUser)) 
      { 
       return false; 
      } 

      ApplicationUser user = (ApplicationUser)obj; 
      bool hasLogin = false; 

      foreach (IdentityUserLogin login in user.Logins) 
      { 
       if (login.ProviderKey == ProviderKey) 
       { 
        hasLogin = true; 
        break; 
       } 
      } 
      if (!hasLogin) { return false; } 

      if (user.FirstName != GivenName) { return false; } 
      if (user.LastName != FamilyName) { return false; } 
      if (user.Locale != Locale) { return false; } 

      return base.Equals(obj); 
     } 
    } 
} 

WebApiConfig. cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net.Http; 
using System.Web.Http; 
using Microsoft.Owin.Security.OAuth; 
using Newtonsoft.Json.Serialization; 

namespace Services 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      // Web API configuration and services 
      // Configure Web API to use only bearer token authentication. 
      config.SuppressDefaultHostAuthentication(); 
      config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 

      // Web API routes 
      config.MapHttpAttributeRoutes(); 

      config.Routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "api/{controller}/{id}", 
       defaults: new { id = RouteParameter.Optional } 
      ); 
      config.MessageHandlers.Add(new CustomJwtHandler()); 
     } 
    } 
} 
+0

Ne düşünüyorsun Google Hizmetini belirten jetonu sık sık çağırırsak – Redplane

+0

Hiçbir şey olmaz. Muhtemelen kotayı tükürürsünüz. –

+0

Bu yüzden neden kullandığım sunucuda Google Token'i doğrulamayı düşünüyorum. – Redplane

İlgili konular