是否可以编写可以测试AuthorizationPolicy对象的测试?

时间:2017-10-09 16:36:46

标签: c# asp.net-core authorization .net-core

我有一个我想在C#中测试的政策

public class WorkflowCreatePolicy
{
    public AuthorizationPolicy AuthorizationPolicy =>
        new AuthorizationPolicyBuilder()
            .RequireClaim("scope", "WorkflowAdmin")
            .Build();
}

有没有人知道如何测试AuthorizationPolicy以确认范围" WorkflowAdmin"是成功的,所有其他人都不是吗?

这是我在检查对象时看到的内容:

enter image description here

我设法找到了这个网站:Authorization Handler Unit Tests但它讨论的是测试处理程序,并且代码标志着auth尝试成功。

我不确定这是否正在接近。它目前还没有通过

[Test]
public void GivenPolicyName_WhenICallPolicyChecks_ThenItPasses()
{
    ClaimsPrincipal user = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim(CustomClaims.Scope, "WorkflowAdmin") }));

    WorkflowCreatePolicy workflowCreatePolicy = new WorkflowCreatePolicy();

    AuthorizationHandlerContext authorizationHandlerContext = new AuthorizationHandlerContext(workflowCreatePolicy.AuthorizationPolicy.Requirements, user, null);

    Assert.That(authorizationHandlerContext.HasSucceeded, Is.EqualTo(true));
}

4 个答案:

答案 0 :(得分:2)

引擎盖下AuthorizationPolicy只是授权处理程序的集合。像RequireClaim这样的方法将Microsoft构建的处理程序添加到集合中。在这种情况下,ClaimsAuthorizationRequirement继承自AuthorizationHandler

要验证用户是否通过了AuthorizationPolicy,您需要AuthorizationService来调用所有政策。在第一个处理程序未能对用户进行身份验证后,DefaultAuthorizationService将停止。如果你没有注册另一个AuthorizationService,那么将使用这个。

因此,您可以自己构建AuthorizationService并在其上调用AuthorizeAsync方法。请注意,如果您想对其进行测试,则需要注册自定义AuthorizationHandler

private static async Task<bool> CanAuthorizeUserWithPolicyAsync(ClaimsPrincipal user, AuthorizationPolicy policy)
{
    var handlers = policy.Requirements.Select(x => x as IAuthorizationHandler).ToArray();
    // add your custom authorization handlers here to the `handlers` collection

    var authorizationOptions = Options.Create(new AuthorizationOptions());

    authorizationOptions.Value.AddPolicy(nameof(policy), policy);

    var policyProvider = new DefaultAuthorizationPolicyProvider(authorizationOptions);
    var handlerProvider = new DefaultAuthorizationHandlerProvider(handlers);
    var contextFactory = new DefaultAuthorizationHandlerContextFactory();

    var authorizationService = new DefaultAuthorizationService(
        policyProvider, 
        handlerProvider, 
        new NullLogger<DefaultAuthorizationService>(), 
        contextFactory, 
        new DefaultAuthorizationEvaluator(), 
        authorizationOptions);

    var result = await authorizationService.AuthorizeAsync(user, policy);
    return result.Succeeded;
}

您可以像以下一样使用此方法。

var user = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim("scope", "WorkflowAdmin") }));

var policy = new AuthorizationPolicyBuilder()
    .RequireClaim("scope", "WorkflowAdmin")
    .Build();

Assert.That(await CanAuthorizeUserWithPolicyAsync(user, policy), Is.EqualTo(true));

答案 1 :(得分:1)

请参阅ASP.NET核心安全单元测试中的this test。我从中采用了这种模式并将其应用于您的政策。

[Fact]
public async Task ShouldAllowIfScopeClaimWorkflowAdminIsPresent()
{
    // Arrange
    var authorizationService = BuildAuthorizationService(services =>
    {
        services.AddAuthorization(options =>
        {
            options.AddPolicy("SomePolicyName", new WorkflowCreatePolicy().AuthorizationPolicy
        });
    });
    var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[] { new Claim("scope", "WorkflowAdmin") }));

    // Act
    var allowed = await authorizationService.AuthorizeAsync(user, "SomePolicyName");

    // Assert
    Assert.True(allowed.Succeeded);
}
private IAuthorizationService BuildAuthorizationService(Action<IServiceCollection> setupServices = null)
{
    var services = new ServiceCollection();
    services.AddAuthorization();
    services.AddLogging();
    services.AddOptions();
    setupServices?.Invoke(services);
    return services.BuildServiceProvider().GetRequiredService<IAuthorizationService>();
}

答案 2 :(得分:0)

找到它:)

[TestFixture]
public class WorkflowCreatePolicyTests
{
    [Test]
    public void GivenAuthorizationPolicy_WhenICheckTheClaimScopes_ThenItHasUserAdmin()
    {
        AuthorizationPolicy authorizationPolicy = new WorkflowCreatePolicy().AuthorizationPolicy;
        ClaimsAuthorizationRequirement claimsAuthorizationRequirement = authorizationPolicy.Requirements
            .FirstOrDefault(x => (x as ClaimsAuthorizationRequirement)?.ClaimType == "scope")
            as ClaimsAuthorizationRequirement;

        Assert.That(claimsAuthorizationRequirement?.AllowedValues, Contains.Item("WorkflowAdmin"));
    }
}

答案 3 :(得分:-1)

恕我直言,您希望使用integration tests进行测试。

Unit testing it is covered by the ASP.NET Core并且在一天结束时,您希望确保对您的终点的访问权限得到保护。

您可以使用TestServer

应用程序的组成应在此时进行测试:确保在没有所需声明的情况下调用终点将导致403。