[解決済み] ASP.NET Coreのトークンベース認証
質問
ASP.NET Coreアプリケーションで作業しています。私はトークンベース認証を実装しようとしていますが、新しい セキュリティシステム を使用します。 私は 事例 クッキー認証や外部認証(GitHub、Microsoft、Twitter)を使っているようですが、あまり役に立ちませんでした。
私のシナリオは、angularjs アプリケーションが
/token
urlにユーザー名とパスワードを渡します。WebApiはユーザーを認証し
access_token
これは、次のリクエストでangularjsアプリによって使用されます。
現在のASP.NETのバージョンで私が必要とするものを正確に実装している素晴らしい記事を見つけました -。 ASP.NET Web API 2、Owin、およびIdentityを使用したトークン・ベース認証 . しかし、ASP.NET Coreで同じことを行う方法は私には明らかではありません。
私の質問は、ASP.NET Core WebApi アプリケーションがトークンベース認証で動作するように構成する方法ですか?
どのように解決するのですか?
.Net Core 3.1へのアップデートを行いました。
David Fowler (ASP .NET Core チームのアーキテクト) は、信じられないほどシンプルなタスクアプリケーションのセットをまとめました。 JWTのデモを行うシンプルなアプリケーション . この記事には、彼のアップデートとシンプルなスタイルを近々取り入れる予定です。
.Net Core 2に対応したアップデートを行いました。
この回答の以前のバージョンでは、RSA を使用していました。トークンを生成する同じコードがトークンの検証も行うのであれば、これは本当に必要ではありません。しかし、もしあなたが責任をもって配布しているのであれば、おそらくまだ
Microsoft.IdentityModel.Tokens.RsaSecurityKey
.
-
後で使用する定数をいくつか作成します。
const string TokenAudience = "Myself"; const string TokenIssuer = "MyProject";
-
Startup.csに以下を追加してください。
ConfigureServices
. これらの設定にアクセスするには、後で依存性注入を使用することになります。 私が想定しているのは、あなたのauthenticationConfiguration
はConfigurationSection
またはConfiguration
オブジェクトを作成し、デバッグ用と本番用で異なる設定をすることができます。鍵は安全に保管するようにしましょう! 任意の文字列を指定できます。var keySecret = authenticationConfiguration["JwtSigningKey"]; var symmetricKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keySecret)); services.AddTransient(_ => new JwtSignInHandler(symmetricKey)); services.AddAuthentication(options => { // This causes the default authentication scheme to be JWT. // Without this, the Authorization header is not checked and // you'll get no results. However, this also means that if // you're already using cookies in your app, they won't be // checked by default. options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters.ValidateIssuerSigningKey = true; options.TokenValidationParameters.IssuerSigningKey = symmetricKey; options.TokenValidationParameters.ValidAudience = JwtSignInHandler.TokenAudience; options.TokenValidationParameters.ValidIssuer = JwtSignInHandler.TokenIssuer; });
他の回答では、他の設定を変更しているのを見ましたが、例えば
ClockSkew
デフォルトは、時計が正確に同期していない分散環境でも動作するように設定されています。変更する必要があるのは、これらの設定だけです。 -
Authentication(認証)を設定します。を必要とするミドルウェアの前に、この行を記述する必要があります。
User
のような情報app.UseMvc()
.app.UseAuthentication();
この場合、トークンが
SignInManager
などがあります。あなたのJWTを出力するための独自のメカニズムを提供する必要があります - 下記を参照してください。 -
を指定したい場合があります。
AuthorizationPolicy
. これにより、Bearerトークンのみを認証として許可するコントローラやアクションを[Authorize("Bearer")]
.services.AddAuthorization(auth => { auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddAuthenticationTypes(JwtBearerDefaults.AuthenticationType) .RequireAuthenticatedUser().Build()); });
-
ここからが厄介なところです。トークンを構築するのです。
class JwtSignInHandler { public const string TokenAudience = "Myself"; public const string TokenIssuer = "MyProject"; private readonly SymmetricSecurityKey key; public JwtSignInHandler(SymmetricSecurityKey symmetricKey) { this.key = symmetricKey; } public string BuildJwt(ClaimsPrincipal principal) { var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: TokenIssuer, audience: TokenAudience, claims: principal.Claims, expires: DateTime.Now.AddMinutes(20), signingCredentials: creds ); return new JwtSecurityTokenHandler().WriteToken(token); } }
そして、トークンが必要なコントローラで、以下のようなものを作成します。
[HttpPost] public string AnonymousSignIn([FromServices] JwtSignInHandler tokenFactory) { var principal = new System.Security.Claims.ClaimsPrincipal(new[] { new System.Security.Claims.ClaimsIdentity(new[] { new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, "Demo User") }) }); return tokenFactory.BuildJwt(principal); }
ここでは、すでにプリンシパルを持っていることを想定しています。Identity を使用している場合は
IUserClaimsPrincipalFactory<>
を変換するためにUser
をClaimsPrincipal
. -
テストするために : トークンを取得し、以下のフォームに入力します。 jwt.io . 上で紹介した手順では、署名の検証に設定から得たsecretを使用することも可能です
-
.Net 4.5のベアラのみの認証と組み合わせてHTMLページの部分ビューでレンダリングしていた場合は
ViewComponent
を実行します。ほとんど上のController Actionのコードと同じです。
関連
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】C#で四捨五入する方法
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み] DateTime型の誕生日から年齢を計算するにはどうしたらいいですか?
-
[解決済み] JWT(JSONウェブトークン)の有効期限を自動的に延長する機能
-
[解決済み】ASP.NET Web APIのJWT認証について
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である