2017-12-23 37 views
1

apiアプリケーションでJSON Webトークンベースの認証を適用しようとしています。問題は、トークンをテストするたびに不正なトークンシグネチャを取得していることです。さらに、私のコントローラで私の要求を承認することができず、後者を生成することと関係があると思います。asp.net core2でJWTを正しく設定する方法は?

すべての関連コードを投稿してくれて、誰かが私を助けることができたら非常に感謝しています。 ソースコードはgithubのASPNETCore2JwtAuthentication

appsettings.json

"BearerTokens": { 
    "Key": "iNivDmHLpUA223sqsfhqGbMRdRj1PVkH", 
    "Issuer": "http://localhost/", 
    "Audience": "http://localhost/", 
    "AccessTokenExpirationMinutes": 2, 
    "RefreshTokenExpirationMinutes": 60 
}, 

Startup.csから/ConfigureServices

  services.AddAuthorization(options => 
        { 
         options.AddPolicy(CustomRoles.Admin, policy => policy.RequireRole(CustomRoles.Admin)); 
         options.AddPolicy(CustomRoles.User, policy => policy.RequireRole(CustomRoles.User)); 
         options.AddPolicy(CustomRoles.Editor, policy => policy.RequireRole(CustomRoles.Editor)); 
        }); 


      services.AddAuthentication(options => 
       { 
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 
        options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme; 
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 
       }) 
       .AddCookie(cfg => 
       { 
        cfg.SlidingExpiration = true; 
       }) 
       .AddJwtBearer(cfg => 
       { 
        cfg.RequireHttpsMetadata = false; 
        cfg.SaveToken = true; 
        cfg.TokenValidationParameters = new TokenValidationParameters 
        { 
         ValidIssuer = Configuration["BearerTokens:Issuer"], 
         ValidAudience = Configuration["BearerTokens:Audience"], 
         IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["BearerTokens:Key"])), 
         ValidateIssuerSigningKey = true, 
         ValidateLifetime = true, 
         ClockSkew = TimeSpan.Zero 
        }; 
        cfg.Events = new JwtBearerEvents 
        { 
         OnAuthenticationFailed = context => 
         { 
          var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents)); 
          logger.LogError("Authentication failed.", context.Exception); 
          return Task.CompletedTask; 
         }, 
         OnTokenValidated = context => 
         { 
          var tokenValidatorService = context.HttpContext.RequestServices.GetRequiredService<ITokenValidatorService>(); 
          return tokenValidatorService.ValidateAsync(context); 
         }, 
         OnMessageReceived = context => 
         { 
          return Task.CompletedTask; 
         }, 
         OnChallenge = context => 
         { 
          var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents)); 
          logger.LogError("OnChallenge error", context.Error, context.ErrorDescription); 
          return Task.CompletedTask; 
         } 
        }; 
       }); 


      services.AddCors(options => 
      { 
       options.AddPolicy("CorsPolicy", 
        builder => builder 
         .WithOrigins("http://localhost:4200") //Note: The URL must be specified without a trailing slash (/). 
         .AllowAnyMethod() 
         .AllowAnyHeader() 
         .AllowCredentials()); 
      }); 
      services.AddMvc(); 



**Startup.cs**/Configure 


app.UseAuthentication(); 
app.UseMvc(); 

TokenStoreService.cs

を導出します生成されたトークン

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkODFhNTQ4ZS0xOWFlLTRhNDQtODZhMS0zY2ZiNWU0MmE4ZDkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0LyIsImlhdCI6MTUxNDAwODYwOCwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiIwYjk0NWZkZC00ZjViLTRhMmEtODNiZi0yNTA1YjBkNjJiODUiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiSlNPTiIsIkRpc3BsYXlOYW1lIjoiQWJ1IE1haXphciIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvc2VyaWFsbnVtYmVyIjoiNTU0Zjg5ZjMtZjRiMi00ODY0LThiMzctZWNmMGY2OGNlOWM0IiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy91c2VyZGF0YSI6IjBiOTQ1Zmの10

public async Task<(string accessToken, string refreshToken)> CreateJwtTokens(ApplicationUser user) 
{ 
    var now = DateTimeOffset.UtcNow; 
    var accessTokenExpiresDateTime = now.AddMinutes(_configuration.Value.AccessTokenExpirationMinutes); 
    var refreshTokenExpiresDateTime = now.AddMinutes(_configuration.Value.RefreshTokenExpirationMinutes); 
    var accessToken = await createAccessTokenAsync(user, accessTokenExpiresDateTime.UtcDateTime).ConfigureAwait(false); 
    var refreshToken = Guid.NewGuid().ToString().Replace("-", ""); 

    await AddUserTokenAsync(user, refreshToken, accessToken, refreshTokenExpiresDateTime, accessTokenExpiresDateTime).ConfigureAwait(false); // this method is only to store the generated token in the database, irrelevent to the issue. 
    await this.context.SaveChangesAsync(); 


    return (accessToken, refreshToken); 
} 

private async Task<string> createAccessTokenAsync(ApplicationUser user, DateTime expires) 
     { 
      var claims = new List<Claim> 
      { 
       // Unique Id for all Jwt tokes 
       new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), 
       // Issuer 
       new Claim(JwtRegisteredClaimNames.Iss, _configuration.Value.Issuer), 
       // Issued at 
       new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToUnixEpochDate().ToString(), ClaimValueTypes.Integer64), 
       new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), 
       new Claim(ClaimTypes.Name, user.UserName), 
       new Claim("DisplayName", user.LastName), 
       // to invalidate the cookie 
       new Claim(ClaimTypes.SerialNumber, user.SecurityStamp), 
       // custom data 
       new Claim(ClaimTypes.UserData, user.Id.ToString()) 
      }; 

      // add roles 
      var roles = await _rolesService.FindUserRolesAsync(user.Id).ConfigureAwait(false); 
      foreach (var role in roles) 
      { 
       claims.Add(new Claim(ClaimTypes.Role, role.RoleId)); 
      } 

      var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.Value.Key)); 
      var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 
      var token = new JwtSecurityToken(
       issuer: _configuration.Value.Issuer, 
       audience: _configuration.Value.Audience, 
       claims: claims, 
       notBefore: DateTime.UtcNow, 
       expires: expires, 
       signingCredentials: creds); 

      return new JwtSecurityTokenHandler().WriteToken(token); 
     } 

サンプルRkLTRmNWItNGEyYS04M2JmLTI1MDViMGQ2MmI4NSIsIm5iZiI6MTUxNDAwODYwNywiZXhwIjoxNTE0MDA4NzI3LCJhdWQiOiJodHRwOi8vbG9jYWxob3N0LyJ9.q-IphSwiOhzDT9upOO4XOvGQVp_NxymcuW4WWuERe2U

validation link

+0

私はステップバイステップのブログ記事を書いています。あなたに役立つかもしれません。https://mostafizz.wordpress.com/2017/09/30/jwt-token-with-cookie-authentication-in-asp-net-core -2-0/ – Mostafiz

+0

同じ問題で、あなたのコードはクッキーのために起動されましたが、JWTは起動しませんでした。 – JSON

+0

JWTを検証しようとしたときにキーを提供していただければ幸いです。私はJWTのような問題は何も見ません。あなたが提供したJWT検証リンクは、JWTを生成するために使用した鍵を提供するまで、無効な署名を表示します –

答えて

0

ので、私の問題は、独自のトークンを検証するあなたのカスタマイズされた方法である私のITokenValidatorServiceのバグでした。設定は、上記示した

OnTokenValidated = context => 
         { 
          var tokenValidatorService = context.HttpContext.RequestServices.GetRequiredService<ITokenValidatorService>(); 
          return tokenValidatorService.ValidateAsync(context); 
         }, 

だけで正常に動作しかし、私はまだJWT validatorは、いずれかのように無効なトークン提出帰国し続ける理由だろ!

関連する問題