2017-02-20 8 views
9

Я пытаюсь создать авторизацию маркера Jwt. Для этого у меня есть выпускающая часть с кодом вроде этого:Авторизация Jwt-токенов не работает

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
{ 
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"}); 
    Users user; 
    using (var db = new UserStore()) 
    { 
     user = Task.Run(()=> db.FindUser(context.UserName, context.Password, context.ClientId)).Result; 
    } 
    if (user == null) 
    { 
     context.SetError("invalid_grant", "The user name or password is incorrect"); 
     return Task.FromResult<object>(null); 
    } 
    var identity = new ClaimsIdentity("JWT"); 
    identity.AddClaim(new Claim(ClaimTypes.Name, user.Email)); 
    identity.AddClaim(new Claim("sub", context.UserName)); 
    identity.AddClaim(new Claim(ClaimTypes.Role, user.Roles.Name)); 

    var props = new AuthenticationProperties(new Dictionary<string, string> 
    { 
     { 
      "audience", context.ClientId ?? string.Empty 
     } 
    }); 
    var ticket = new AuthenticationTicket(identity, props); 
    context.Validated(ticket); 
    return Task.FromResult<object>(null); 
} 

И «ресурс» часть, которая должна принять однонаправленную фишку:

public void ConfigureOAuth(IAppBuilder app) 
{ 
    var issuer = SiteGlobal.Issuer; 
    var audience = SiteGlobal.Audience; 
    var secret = TextEncodings.Base64Url.Decode(SiteGlobal.Secret); 
    app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions 
    { 
     AuthenticationMode = AuthenticationMode.Active, 
     AllowedAudiences = new[] { audience }, 
     IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[] 
     { 
      new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret) 
     } 
    }); 
} 

Насколько я могу видеть выданный маркер действителен (I сделал валидацию на jwt.io), поэтому проблема - это еще что-то. Когда я отправляю токен в Postman с вызовом контроллера, защищенным атрибутом [Authorize], он всегда возвращает код 401. Не могли бы вы посоветовать, как это исправить?

P.S. Вот как я реализую пользовательские Jwt fortmat:

public string Protect(AuthenticationTicket data) 
{ 
    if (data == null) 
    { 
     throw new ArgumentNullException("data"); 
    } 
    string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null; 
    if (string.IsNullOrWhiteSpace(audienceId)) throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience"); 
    Audience audience; 
    using (var store = new AudienceStore()) 
    { 
     audience = Task.Run(()=> store.FindAudience(audienceId)).Result; 
    } 
    var symmetricKeyAsBase64 = audience.Base64Secret; 
    var signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(symmetricKeyAsBase64)); 
    var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest); 
    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, signingCredentials); 
    var handler = new JwtSecurityTokenHandler(); 
    var jwt = handler.WriteToken(token); 
    return jwt; 
} 

P.S. Ребята, мне очень жаль, но я забыл объяснить, что «эмитент» является частью кода, который является автономным приложением, между тем «аудитория» защищена web api. Это два разных приложения, выполняемых независимо.

+0

Не помогло бы вам http://security.stackexchange.com/a/128882/131820? – Tatranskymedved

+0

Я не уверен в этом. Есть ли проблемы с заголовками, я получу что-то вроде плохого запроса, но не уныло. –

+0

У меня нет опыта с 'jwt', только с запросами' REST' через URL, где нужен заголовок запроса 'Authorization: Basic ' и если что-то не так (pass/name/syntax) он бросил мне 401. – Tatranskymedved

ответ

2

В Почтальон убедитесь, что вы отправляете заголовок авторизации, используя следующий формат:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

Postman Authorization Header

Убедитесь, что вы покидаете вкладку авторизации установлен на Type: No Auth.

Если у вас по-прежнему возникают проблемы, установите контрольную точку в GrantResourceOwnerCredentials и посмотрите, доходит ли она до этой точки. Также рассмотрите переопределение метода ValidateClientAuthenticationOAuthAuthorizationServerProvider, который должен быть вызван до GrantResourceOwnerCredentials, если вы хотите отлаживать ранее в цепочке событий.

+0

Код Tha от почтмана: Авторизация: Носитель eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImFuZHJleS5zaGVka29AZ21haWwuY29tIiwic3ViIjoiYW5kcmV5LnNoZWRrb0BnbWFpbC5jb20iLCJyb2xlIjoiQWRtaW4iLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUyNzk5IiwiYXVkIjoiMDk5MTUzYzI2MjUxNDliYzhlY2IzZTg1ZTAzZjAwMjIiLCJleHAiOjE0ODc3NzIxOTEsIm5iZiI6MTQ4Nzc3MDM5MX0.5GFpvU08CjaS5LTH0vRVFIGuilenkEgVu_aJLma4lPo –

+0

Это вопрос - в «resorce» апи не установили Asp.Net идентичность, как сказано в этом руководстве - http://bitoftech.net/2014/10/27/json-web-token-asp- нетто-веб-апи-2-JWT-Owin-авторизации-сервер/комментарий-страница-3/# комментарий-97300. Метод GrantResourceOwnerCredentials У меня есть только часть «эмитента». –

+0

@ andrey.shedko вы не опубликовали то, что пытались запустить через почтальона, но 401 предполагает, что что-то не проходит через ваше разрешение. Установка точек останова должна позволять вам проверять и находить конкретную точку отказа. Это работает, если вы удаляете атрибут Authorized и запускаете запрос через почтальона? – cchamberlain

2

Я только что попытался запустить demo project, упомянутый в SON Web Token in ASP.NET Web API 2 using Owin, и все работало, как ожидалось.

Я заметил, что ваша реализация метода Protect отличается совсем немного. Я бы предложил вам сравнить вашу реализацию с примером, приведенным в статье. Сначала попробуйте сделать эту работу.

Также убедитесь, что эмитент, аудитория и секрет одинаковы на обоих серверах.

Если вы предоставляете полный исходный код, я могу попытаться расследовать больше.

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