基本認証.NET 6.0 Web API

7217 ワード

概要


この記事では、私は共有します.基本認証をサポートするNET 6.0 Web APIサンプルコード.こちらthe sample code

TOC


  • Concept
  • Configuration
  • Custom attribute
  • Middleware
  • Allowanonymous attribute
  • Sample request
  • コンセプト


    構成

    The Web API validates an incoming request header based on the username and password configured in appsettings.json or Configuration at Azure App Service. The app exctracts the value through IConfiguration class.

    appsettings.json
    "BasicAuth": {
       "UserName": "",
       "Password": ""
    }
    

    カスタム属性

    A custom attribute BasicAuth is on the controller and allow only requests which attach the username and password on the request header.

    WeatherforecastController
    [HttpGet("RequireAuth")]
    [AllowAnonymous]
    [AuthorizeBasicAuth]
    public ActionResult<Weatherforecast> GetBasicAuth()
    {
        ...
    
    カスタム属性AuthorizeBasicAuthAttribute クラス継承AuthorizeAttribute and IAuthorizationFilter . アットOnAuthorization メソッドセットUnauthorizedResult() コンテキスト認証結果を返します.HttpContext.Items["BasicAuth"] が正しくない.
    AuthorizeBasicAuthAttribute
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (context.HttpContext.Items["BasicAuth"] is not true)
        {
            context.Result = new UnauthorizedResult();
            return;
        }
    }
    

    ミドルウェア

    In the custom middleware BasicAuthMiddleware , it validates the username and password attached to the request header and add true to HttpContext.Items['BasicAuth'] so it can pass the validation result to the later step of the authorization filter.

    BasicAuthMiddleware
    Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    string usernameAndPassword = encoding.GetString(Convert.FromBase64String(authHeaderVal.Parameter));
    string username = usernameAndPassword.Split(new char[] { ':' })[0];
    string password = usernameAndPassword.Split(new char[] { ':' })[1];
    if (username == this.configuration.GetValue<string>("BasicAuth:UserName") && password == this.configuration.GetValue<string>("BasicAuth:Password"))
    {
        httpContext.Items["BasicAuth"] = true;
    }
    
    検証プロセスはカスタムミドルウェア中ですBasicAuthMiddleware カスタム属性フィルタは、IConfiguration クラス.マイクロソフトドキュメンテーションによるとDependency Injection , フィルタ属性に依存関係のインジェクションコンストラクターを持つことはできません.
    属性として実装され、コントローラクラスまたはアクションメソッドに直接追加されたフィルターは、依存性注入(DI)によって提供されるコンストラクター依存関係を持つことはできません.属性がそれらが適用されるところで、彼らのコンストラクタパラメタを供給しなければならないので、建設者依存性はdiによって提供されません.

    アワード匿名属性

    I intentionally add [AllowAnonymous] to the controller because .NET built-in authentication is conducted in the middleware but the request header is supposed to have only a basic authentication information.

    • Without [AllowAnonymous] attribute in the controller, the controller does not give the request a permission to access.
    • Without app.UseAuthentication , the authorization process does not work. (401 Unauthorized)
    • Without app.UseAuthorization , the middleware that supports authorization cannot deal with the authorization metadata (500 internal server error.)

    Program.cs

    app.UseAuthentication();
    app.UseAuthorization();
    app.UseMiddleware<BasicAuthMiddleware>();
    

    リクエスト

    Powershell

    $basicAuthUsername = "{The user name configured in the Web API}"
    $basicAuthSecret = "{The password name configured in the Web API}"
    $bytes = [System.Text.Encoding]::ASCII.GetBytes($basicAuthUsername + ':' + $basicAuthSecret)
    $authHeader = [Convert]::ToBase64String($bytes)
    $Uri = "{App URL}/Weatherforecast/RequireAuth"
    $headers = @{
      "Authorization" = 'Basic ' + $authHeader
    }
    Invoke-RestMethod -Uri $Uri -Method Get -Headers $headers
    

    bash

    $basicAuthUsername = "{The user name configured in the Web API}"
    $basicAuthSecret = "{The password name configured in the Web API}"
    curl {App URL}/Weatherforecast/RequireAuth \
      -H "accept: application/json" \
      -H "Authorization:Basic $(echo -n $basicAuthUsername:$basicAuthSecret | openssl base64)"