iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
Cloud Native

The Journey of ASP.NET and Beyond系列 第 9

ASP.NET Core Web API: Identity Recognition

  • 分享至 

  • xImage
  •  

The guild also needs authorization to recognize the adventurers, such as seals, signatures, or coats of arms.

  冒險者四處犯險,又可各處征戰,其身份可謂處處皆暢通無阻,而諸如公會、門衛者又何以辨其身份?非核心區或以自白、印章、簽名、家徽、紋身等辨認。然而若核心區亦循其法,則可能造成混淆,人員之出入無以確認,冒充身分者不勝枚舉,故可見辨其身分之重。冒險者公會,乃情報之中心,掌管各種任務,並知曉冒險者之情況,而由此況可知,冒險者公會不能不奠定良好之身分辨認,而其所用乃權杖

訪問權杖 Bearer Token


  訪問權杖乃開放授權2.0(OAuth 2.0)中主要使用之存取權杖類型。其為不透明之字串,且冒險者若使用之,其對冒險者無任何目的。有些公會會給予十六進位字元之短字串所組成之權杖,他者則可能使用結構化權杖,如JWT。此次以JWT為例。

  首先,至管理NuGet套件安裝Microsoft.AspNetCore.Authentication.JwtBearer之套件。並至appsettings.json中新增JwtSettings,並於其中增加三者Issuer、Audience、Key,分別為頒布者、接收者、密鑰。
https://ithelp.ithome.com.tw/upload/images/20231005/20151244w365ma4KRt.png

  其次,於Program.cs中之builder.Services.AddSwaggerGen()中新增以下內容,此乃於swagger中新增Bearer Token認證之功能:

builder.Services.AddSwaggerGen(entity =>
{
   entity.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
   {
       Name = "Identify Recognition",
       Description = "Guild Identity Recognition",
       Type = SecuritySchemeType.Http, // 使用之方案類型
       Scheme = "Bearer",
       BearerFormat = "JWT"
   });
   entity.AddSecurityRequirement(new OpenApiSecurityRequirement
   {
       {
           new OpenApiSecurityScheme
           {
               Reference = new OpenApiReference
               {
                   Type = ReferenceType.SecurityScheme,
                   Id = "Bearer"
               }
           },
           new string[] {}
       }
   });
});

  再新增builder.Services.AddAuthentication().AddJwtBearer(),於AddSwaggerGen()之下,此步乃為確保使用JWT Bearer Token進行身份驗證時,頒布者、接收者、有效期和簽名金鑰等方面都符合預期之設置。

builder.Services.AddAuthentication().AddJwtBearer(option =>
{
    option.IncludeErrorDetails = true;
    option.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true, // 是否驗證頒布者
        ValidateAudience = true, // 是否驗證接收者
        ValidateLifetime = true, // 是否驗證 JWT 的有效期
        ValidateIssuerSigningKey = true, // 是否驗證簽名金鑰

        ValidIssuer = builder.Configuration.GetValue<string>("JwtSettings:Issuer"),
        ValidAudience = builder.Configuration.GetValue<string>("JwtSettings:Audience"),
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration.GetValue<string>("JwtSettings:Key")))
    };
});

  最後在加上builder.Services.AddAuthorization();便完成program.cs中之設置。此時可在Controller中加上[Authorize][ApiController][HttpMethod]上,便可辨認冒險者授權否。若無則如下圖。
https://ithelp.ithome.com.tw/upload/images/20231005/20151244SfncbcVl5a.png

授權 Authorize


  於授權前,必先由冒險者提出其證明,以證其分,故公會提供「印記」以辨身分,冒險者以印記、名字以產生權杖,權杖又賦予冒險者操作各公會之事務。是故首先撰寫生成權杖之法,首先創建Helper之資料夾,並創建JwtHelper.cs:

namespace WebApplication1.Helper
{
    public class JwtHelper
    {
        private readonly string issuer;
        private readonly string key;
        private readonly string audience;

        public JwtHelper(IConfiguration configuration)
        {
            issuer = configuration.GetValue<string>("JwtSettings:Issuer");
            audience = configuration.GetValue<string>("JwtSettings:Audience");
            key = configuration.GetValue<string>("JwtSettings:Key");
        }

        public string GenerateGuildToken(string sigil, string name)
        {
            List<Claim> claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Jti, sigil),
                new Claim(JwtRegisteredClaimNames.Sub, name),
                new Claim(ClaimTypes.Role, "Adventurer")
            };

            var SecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));

            var jwtSecurityToken = new JwtSecurityToken
            (
                issuer: issuer,
                audience: audience,
                claims: claims,
                expires: DateTime.Now.AddHours(1),
                signingCredentials: new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256)
            );
            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);

            return token;
        }
    }
}

  謹記:JwtHelper完成後需於Program.cs中註冊builder.Services.AddSingleton<JwtHelper>();

  完成權杖產生之法後,便可於公會之禮賓部進行身分之認證,做法如下,冒險者給出公會賦予之「印記」,依據印記可得出冒險者之身分,其後以其二者產生權杖,並交付於冒險者手中,冒險者便可行各事務。

    [AllowAnonymous]
    [ApiController]
    [Route("[controller]")]
    public class RecognitionController : ControllerBase
    {
        private readonly JwtHelper _jwtHelper;
        private readonly GuildContext _Context;
        public RecognitionController(JwtHelper jwtHelper, GuildContext guild)
        {
            _jwtHelper = jwtHelper;
            _Context = guild;
        }

        [HttpPost]
        public async Task<IActionResult> Recognition(string sigil)
        {
            var Adventurer = _Context.AdventurersProfile.SingleOrDefault(e => e.Sigil.Equals(sigil));
            if (Adventurer == null) return Ok("not found");
            var token = _jwtHelper.GenerateGuildToken(sigil, Adventurer.Name);
            return Ok(token);
        }
    }

  取得之權杖進行授權後,原本應無法操作之事務得行之。
https://ithelp.ithome.com.tw/upload/images/20231006/20151244xXTjXBoSNc.png


上一篇
ASP.NET Core Web API: CRUD Adventurer's Guild
下一篇
ASP.NET Core Web API: Dispatching a Missive
系列文
The Journey of ASP.NET and Beyond30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言