The guild also needs authorization to recognize the adventurers, such as seals, signatures, or coats of arms.
冒險者四處犯險,又可各處征戰,其身份可謂處處皆暢通無阻,而諸如公會、門衛者又何以辨其身份?非核心區或以自白、印章、簽名、家徽、紋身等辨認。然而若核心區亦循其法,則可能造成混淆,人員之出入無以確認,冒充身分者不勝枚舉,故可見辨其身分之重。冒險者公會,乃情報之中心,掌管各種任務,並知曉冒險者之情況,而由此況可知,冒險者公會不能不奠定良好之身分辨認,而其所用乃權杖。
訪問權杖乃開放授權2.0(OAuth 2.0)中主要使用之存取權杖類型。其為不透明之字串,且冒險者若使用之,其對冒險者無任何目的。有些公會會給予十六進位字元之短字串所組成之權杖,他者則可能使用結構化權杖,如JWT。此次以JWT為例。
首先,至管理NuGet套件安裝Microsoft.AspNetCore.Authentication.JwtBearer之套件。並至appsettings.json中新增JwtSettings,並於其中增加三者Issuer、Audience、Key,分別為頒布者、接收者、密鑰。
其次,於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]
上,便可辨認冒險者授權否。若無則如下圖。
於授權前,必先由冒險者提出其證明,以證其分,故公會提供「印記」以辨身分,冒險者以印記、名字以產生權杖,權杖又賦予冒險者操作各公會之事務。是故首先撰寫生成權杖之法,首先創建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;
}
}
}
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);
}
}
取得之權杖進行授權後,原本應無法操作之事務得行之。