Fake許可權驗證小例子

敖毛毛發表於2024-06-30

前言

關於本地測試如何進行Fake許可權驗證

正文

在我們使用swagger除錯本地介面的時候,我們常常因為每次需要填寫token而耽誤工作,不可能每次除錯的時候都去本地測試環境請求一個token進行驗證吧。

上圖可能是我們本地測試的時候需要填寫的一個token位置,本地測試不方便。

那麼怎麼偽造許可權驗證透過呢?

有兩個前置篇:

  1. https://www.cnblogs.com/aoximin/p/15582365.html
  2. https://www.cnblogs.com/aoximin/p/15613974.html

透過這兩個前置篇的閱讀,可能馬上就能知道下面表達所在了,但是及時不看也沒用過關係。

在.net 框架驗證的時候呢?

我們可以加入自己的驗證方案的。

  public virtual AuthenticationBuilder AddScheme<TOptions, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] THandler>(string authenticationScheme, string? displayName, Action<TOptions>? configureOptions)
      where TOptions : AuthenticationSchemeOptions, new()
      where THandler : AuthenticationHandler<TOptions>
      => AddSchemeHelper<TOptions, THandler>(authenticationScheme, displayName, configureOptions);

也就是說,我們可以自定義驗證方案,那麼我們加入我們的Fake 方案,即可透過。

public class FakeAuthenticationOptions : AuthenticationSchemeOptions
{
    public virtual ClaimsIdentity Identity { get; set; }
}

在Fake選項中加入了ClaimsIdentity,這個Identity 就是我們要偽造的使用者資訊。

那麼我們的handler就這樣寫:

public class FakeAuthenticationHandler: AuthenticationHandler<FakeAuthenticationOptions>
{
    public FakeAuthenticationHandler(
        IOptionsMonitor<FakeAuthenticationOptions> options, 
        ILoggerFactory logger, 
        UrlEncoder encoder, 
        ISystemClock clock) 
        : base(options, logger, encoder, clock)
    { }


    protected override Task HandleChallengeAsync(AuthenticationProperties properties)
    {
        return Task.CompletedTask;
    }

    protected override Task HandleForbiddenAsync(AuthenticationProperties properties)
    {
        return Task.CompletedTask;
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var principal = new ClaimsPrincipal(Options.Identity);
        var ticket = new AuthenticationTicket(principal, new AuthenticationProperties(), Scheme.Name);
        var result = AuthenticateResult.Success(ticket);

        return Task.FromResult(result);
    }
}

因為我們偽造資訊是為了透過驗證,那麼Challenge(401)和Forbidden(403)我們直接Task.CompletedTask,不會出現這種情況。

那麼我們認證的時候這樣寫HandleAuthenticateAsync:

  1. 將偽造的資訊生成ticket
  2. 將ticket注入到認證結果中去
  3. 返回認證結果

這個時候我們就偽造了認證的資訊。

注意:授權是透過認證的資訊進行授權的,那麼我們偽造了認證的資訊其實就是為了騙過授權。

然後我們將認證作為中介軟體進行封裝成中介軟體模樣:

public static class FakeAuthenticationExtensions
{
    public static AuthenticationBuilder AddFake(
        this AuthenticationBuilder builder, 
        string scheme,
        Action<FakeAuthenticationOptions> configureOptions)
        =>
            builder.AddScheme<FakeAuthenticationOptions, FakeAuthenticationHandler>(
                scheme, scheme, configureOptions);
}

那麼這個時候最好再加一個預設的方案名:

public class FakeScheme
{
    public const string Default = "Fake";
}

那麼我們注入scheme的時候就這樣即可:

builder.AddFake(FakeScheme.Default, u =>
{
	List<Claim> claims = new List<Claim>();
	var userId = configuration.GetValue<string>("AuthServer:FakeUser");
	claims.Add(new Claim(ClaimTypes.NameIdentifier, userId));
	u.Identity = new ClaimsIdentity(claims, "Role");
});

這樣就偽造了認證的資訊了,然後這個claims根據自己的驗證需要進行動態調整即可。

上面簡述瞭如何去偽造認證資訊,用於本地測試,預發或者線上透過環境變數或者配置關閉即可。

相關文章