首页 > 解决方案 > c# User.IsInRole 在单元测试中失败

问题描述

我有这个方法:

[HttpPut]
[AuthorizeClaim("field:write")]
[ApiConventionMethod(typeof(AttemptApiConventions), nameof(AttemptApiConventions.AttemptPut))]
public override async Task<ActionResult<Field>> UpdateAsync(Field model)
{
    var getAttempt = await Mediator.Send(new GenericGet<Field>(model.Id));
    if (getAttempt.Failure) return Ok(getAttempt);
    
    var field = getAttempt.Result;
    
    if (!field.IsSpecification && !User.IsInRole("Administrator"))
        return Ok(new ForbiddenError(string.Format(Resources.PermissionError, "this field")).ToAttempt<Field>());

    if (!field.IsSpecification && model.Name != field.Name)
        return Ok(new ValidationError(string.Format(Resources.CannotBeChanged, nameof(Field.Name))).ToAttempt<Field>());

    return await base.UpdateAsync(model);
}

如您所见,我检查User.IsInRole在尝试更改字段时是否显示不同的错误消息。问题是,我有这个单元测试:

[Test]
public async Task ReturnBadRequestIfSpecificationFieldNameChanges()
{
    // Assemble
    var model = new Field {Id = 1, IsSpecification = false, Name = "Test"};
    var services = FieldsControllerContext.GivenServices();
    var controller = services.WhenCreateController("Administrator");

    services.Mediator.Send(Arg.Any<GenericGet<Field>>())
        .Returns(new Field {Id = 1, IsSpecification = false, Name = "Old"});

    // Act
    var actionResult = await controller.UpdateAsync(model);

    // Assert
    actionResult.ShouldBeBadRequest(string.Format(Sxp.Web.Properties.Resources.CannotBeChanged, nameof(Field.Name)));
}

看看线services.WhenCreateController("Administrator");。它正在传递我希望被模拟用户成为成员的角色。这是这样设置的:

public static class ControllerExtensions
{
    public static T WithUser<T>(this T controller, string roles = null) where T: ControllerBase
    {
        var id = Guid.NewGuid().ToString();
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, "example name"),
            new Claim(ClaimTypes.NameIdentifier, id),
            new Claim(JwtClaimTypes.Subject, id),
        };

        if (!string.IsNullOrEmpty(roles))
        {
            var r = roles.Split(",");

            claims.AddRange(r.Select(role => new Claim(JwtClaimTypes.Role, role)));
        }

        var user = new ClaimsPrincipal(new ClaimsIdentity(claims, "mock"));

        controller.ControllerContext = new ControllerContext
        {
            HttpContext = new DefaultHttpContext
            {
                User = user
            }
        };

        return controller;
    }
}

当我调试我的测试时,我可以看到:

在此处输入图像描述

谁能告诉我为什么?

标签: c#user-roles

解决方案


我找到了答案。这条线是罪魁祸首:

claims.AddRange(r.Select(role => new Claim(JwtClaimTypes.Role, role)));

不是JwtClaimTypes它检查,它实际上检查:

"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"

推荐阅读