[解決済み] .NET Core 2.0上のJWT
質問
私は、DotNet core 2.0 (本日最終リリースに到達) で JWT を動作させるために、かなりの冒険をしてきました。 そこには トン のドキュメントがありますが、すべてのサンプルコードは非推奨のAPIを使用しているようで、Coreに新しく入ってきたため、正確にどのように実装することになっているのかを把握するのは、本当にめまいがするような状態です。Joseを使ってみましたが、app. UseJwtBearerAuthenticationは非推奨となっており、次に何をすべきかのドキュメントがありません。
誰か dotnet core 2.0 を使用するオープンソースプロジェクトで、認可ヘッダーから JWT を単純に解析し、HS256 エンコード JWT トークンのリクエストを認可することができるものはないでしょうか?
以下のクラスは例外をスローしませんが、どのリクエストも認証されず、何の表示も得られません。 なぜ の表示もありません。 レスポンスは空の 401 で、これは例外がないことを示しますが、シークレットがマッチしていないことを示します。
1つ奇妙なことは、私のトークンは HS256 アルゴリズムで暗号化されていますが、そのアルゴリズムを強制的に使用するように指示するインジケータがどこにも見当たりません。
私がこれまでに持っているクラスは以下のとおりです。
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json.Linq;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace Site.Authorization
{
public static class SiteAuthorizationExtensions
{
public static IServiceCollection AddSiteAuthorization(this IServiceCollection services)
{
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("SECRET_KEY"));
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
ValidateAudience = false,
ValidateIssuer = false,
IssuerSigningKeys = new List<SecurityKey>{ signingKey },
// Validate the token expiry
ValidateLifetime = true,
};
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.IncludeErrorDetails = true;
o.TokenValidationParameters = tokenValidationParameters;
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();
c.Response.StatusCode = 401;
c.Response.ContentType = "text/plain";
return c.Response.WriteAsync(c.Exception.ToString());
}
};
});
return services;
}
}
}
どのように解決するのですか?
ここでは、コントローラを使った完全動作の最小限のサンプルを示します。PostmanやJavaScriptの呼び出しで確認していただければと思います。
-
appsettings.json、appsettings.Development.json。セクションを追加します。なお、Keyはやや長め、Issuerはサービスのアドレスにします。
... ,"Tokens": { "Key": "Rather_very_long_key", "Issuer": "http://localhost:56268/" } ...
!!! 実際のプロジェクトでは、キーを appsettings.json ファイルに保存しないでください。環境変数に保存して、このように受け取ります。
Environment.GetEnvironmentVariable("JWT_KEY");
アップデイト : .net coreの設定がどのように動作するか見てみると、環境から正確に取得する必要はないようです。設定を使ってください。しかし、その代わりに、私たちはこの変数を環境変数に書き込むかもしれません、そして、私たちのコードは、設定の代わりに環境変数を好むでしょう。
-
AuthRequest.cs : ログインとパスワードを渡すための値を保持するDtoです。
public class AuthRequest { public string UserName { get; set; } public string Password { get; set; } }
-
Startup.cs の Configure() メソッドの BEFORE app.UseMvc() :
app.UseAuthentication();
-
Startup.csのConfigureServices()内:
services.AddAuthentication() .AddJwtBearer(cfg => { cfg.RequireHttpsMetadata = false; cfg.SaveToken = true; cfg.TokenValidationParameters = new TokenValidationParameters() { ValidIssuer = Configuration["Tokens:Issuer"], ValidAudience = Configuration["Tokens:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])) }; });
-
コントローラを追加します。
[Route("api/[controller]")] public class TokenController : Controller { private readonly IConfiguration _config; private readonly IUserManager _userManager; public TokenController(IConfiguration configuration, IUserManager userManager) { _config = configuration; _userManager = userManager; } [HttpPost("")] [AllowAnonymous] public IActionResult Login([FromBody] AuthRequest authUserRequest) { var user = _userManager.FindByEmail(model.UserName); if (user != null) { var checkPwd = _signInManager.CheckPasswordSignIn(user, model.authUserRequest); if (checkPwd) { var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, user.UserName), new Claim(JwtRegisteredClaimNames.Jti, user.Id.ToString()), }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken(_config["Tokens:Issuer"], _config["Tokens:Issuer"], claims, expires: DateTime.Now.AddMinutes(30), signingCredentials: creds); return Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) }); } } return BadRequest("Could not create token"); }}
以上です。乾杯!
UPDATEです。 現在のユーザーを取得する方法について質問されました。Todoです。
-
Startup.cs の ConfigureServices() に以下を追加します。
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
-
コントローラでコンストラクタに追加します。
private readonly int _currentUser; public MyController(IHttpContextAccessor httpContextAccessor) { _currentUser = httpContextAccessor.CurrentUser(); }
-
どこかに拡張機能を追加し、Controllerで使用します(...を使用します)。
public static class IHttpContextAccessorExtension { public static int CurrentUser(this IHttpContextAccessor httpContextAccessor) { var stringId = httpContextAccessor?.HttpContext?.User?.FindFirst(JwtRegisteredClaimNames.Jti)?.Value; int.TryParse(stringId ?? "0", out int userId); return userId; } }
関連
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み】Nullableオブジェクトは値を持たなければならない?
-
[解決済み] .NET Coreと.NET Standard Class Libraryのプロジェクトタイプの違いは何ですか?
-
[解決済み] JWT(JSONウェブトークン)の有効期限を自動的に延長する機能
-
[解決済み] JWTは解読できても、安全性はどうなのか?
-
[解決済み] EXEを出力する.NET Coreコンソールアプリケーションを構築する
-
[解決済み] .NET Core、.NET Framework、Xamarinの違いとは?
-
[解決済み】.NET Coreがインストールされているかどうかを判断する方法
-
[解決済み] .NET Core 2.0でConfigurationManager.AppSettingsは利用可能ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】URLから画像をダウンロードする方法
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する