Fake权限验证小例子

fake · 浏览次数 : 0

小编点评

本文介绍了如何在本地测试环境中伪造权限验证,以便更方便地进行开发和调试。文章首先提到了一些关于如何实现这一目标的前置知识,接着详细阐述了如何在.NET框架中创建自定义的验证方案和认证处理器,并通过示例展示了如何使用这些自定义组件来伪造认证信息。 1. **前置知识**: - 介绍了在本地测试中,由于需要频繁填写token而导致的不便。 - 提供了两个参考链接,引导读者了解如何在不依赖本地环境的情况下进行测试。 2. **自定义验证方案**: - 讨论了如何在.NET框架中创建自定义的验证方案。 - 说明了如何通过继承`AuthenticationSchemeOptions`和`AuthenticationHandler`类来自定义验证逻辑。 - 详细描述了如何在自定义验证方案中添加用户信息和处理认证请求。 3. **伪造认证信息**: - 说明了如何通过伪造认证信息来通过验证,包括创建伪造的`ClaimsIdentity`和`AuthenticationTicket`对象。 - 描述了如何处理认证挑战和禁止访问,以便在本地测试环境中无需实际访问外部服务。 4. **认证中间件**: - 提供了一个示例,演示了如何将自定义的认证方案封装成一个中间件。 - 说明了如何在ASP.NET Core应用程序中使用这个中间件来处理身份验证。 总的来说,本文提供了一系列的技术步骤和示例代码,帮助开发者在不依赖外部环境的情况下进行本地开发和测试,同时也能轻松地模拟真实的认证过程。这对于提高开发效率和质量是非常有用的。

正文

前言

关于本地测试如何进行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根据自己的验证需要进行动态调整即可。

上面简述了如何去伪造认证信息,用于本地测试,预发或者线上通过环境变量或者配置关闭即可。

与Fake权限验证小例子相似的内容: