Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9749

ASP.NET Core の API の認証をカスタマイズする方法

$
0
0

Azure AD とか Azure AD B2C とか IdentityService4 とかを使うといい感じにはできます。
でも、例えば API Key での認証にしたいとか、なんらかの独自の認証の仕組みがあって、それに依存しないといけないとかいろんな事情が世の中にはあると思います。

やってみよう

ASP.NET Core の API のプロジェクトを作成します。認証などはとりあえず無しで。

普段は Visual Studio 2019 を使うのですがファンが壊れていて発火したら怖いので VS Code on Macbook Pro でやりたいと思います

ということで dotnetコマンドで作成して Visual Studio Code で開きましょう。

$ dotnet new api -o MyApi
$ code MyApi

そうすると以下のようなものが作成されます。

image.png

VS Code に C# 拡張機能を入れていたら .vscode のフォルダーを生成するか?と聞いてくるので便利です。

では、早速 Startup.cs を編集して認証認可を有効にしましょう。

publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){if(env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseHttpsRedirection();app.UseRouting();app.UseAuthorization();// addapp.UseAuthorization();app.UseEndpoints(endpoints=>{endpoints.MapControllers();});}

そして、独自認証の処理を実装します。AuthenticationHandlerを継承して作ります。サクッといきましょう。

継承してクイックフィックス(Ctrl + . か電球マークをクリック)で、コンストラクターと中小メソッドのインプリメントができるので以下のようなコードまでは、ほぼ打たなくても生成できます。

classMyAuthHandler:AuthenticationHandler<AuthenticationSchemeOptions>{publicMyAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions>options,ILoggerFactorylogger,UrlEncoderencoder,ISystemClockclock):base(options,logger,encoder,clock){}protectedoverrideTask<AuthenticateResult>HandleAuthenticateAsync(){thrownewNotImplementedException();}}

HandleAuthenticateAsync を実装します。とりあえず今回は HTTP ヘッダーに API_KEY という名前で A か B が入ってたら OK というざるロジックでいきます。API_KEY をちゃんと実装するなら何処かに発行した API_KEY を保存しておきましょうね。

protectedoverrideTask<AuthenticateResult>HandleAuthenticateAsync(){if(Context.Request.Headers.TryGetValue("API_KEY",outvarapiKey)&&!string.IsNullOrWhiteSpace(apiKey)){var(ok,name)=apiKey.ToString()switch{"A"=>(true,"a さん"),"B"=>(true,"b さん"),_=>(false,""),};if(!ok){returnTask.FromResult(AuthenticateResult.Fail("Invalid API Key"));}varp=newClaimsPrincipal(newClaimsIdentity(new[]{newClaim(ClaimTypes.Name,name),},"MyAuthType"));returnTask.FromResult(AuthenticateResult.Success(newAuthenticationTicket(p,"Api")));}else{returnTask.FromResult(AuthenticateResult.Fail("Invalid API Key"));}}

そして、ConfigureServices で、このハンドラーを設定します。
デフォルトのスキーマの名前を Api にして、Api というスキーマで MyAuthHandler を使うようにしています。

publicvoidConfigureServices(IServiceCollectionservices){services.AddControllers();services.AddAuthentication("Api").AddScheme<AuthenticationSchemeOptions,MyAuthHandler>("Api",options=>{});}

そして、デフォルトで生成される WeatherForecastController.cs に Authorize 属性を追加して認証必須にして、返すデーターに認証されたユーザーの名前も入れるようにしました。

[ApiController][Route("[controller]")][Authorize]// addpublicclassWeatherForecastController:ControllerBase{// コンストラクタやフォールドなどは省略[HttpGet]publicIEnumerable<WeatherForecast>Get(){varrng=newRandom();returnEnumerable.Range(1,5).Select(index=>newWeatherForecast{Date=DateTime.Now.AddDays(index),TemperatureC=rng.Next(-20,55),Summary=$"{Summaries[rng.Next(Summaries.Length)]} for {HttpContext.User.Identity.Name}",// 名前も返すようにした}).ToArray();}}

ここまでできたら dotnet runコマンドで実行しましょう

Visual Studio Code の REST API 拡張機能を使って叩いてみましょう。
まずは、ヘッダー無しの状態

image.png

401 ですね。いい感じ。

API_KEY に A を設定して呼んでみましょう。

image.png

ちゃんと 200 で、名前も a さんになってますね。B でやっても OK

image.png

C にすると、401 にちゃんと戻ります。

image.png

まとめ

ということで認証の動きをカスタマイズしてみました。
意外と簡単に API Key での認証ができました。今回は HTTP ヘッダーでやりましたが同じ要領でクエリーパラメーターや、クッキーでもできます。

もし、認証をカスタマイズしたい!という人は参考にしてみてください。

あ、ちなみに Azure 使う場合は API Management 使うとプログラムに実装しなくてもいいので、そっちが使えるならそっち使いましょう。


Viewing all articles
Browse latest Browse all 9749

Trending Articles