I am trying to unit test, with NUnit in C#, a custom Authorize Attribute. In particular that a particular http status code and message have been returned in the case of not being authorized.
My attribute is super simple - looks like this:
public class AuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (IsAuthorized(actionContext))
return;
HandleUnauthorizedRequest(actionContext);
}
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "You are not authorized to access this resource");
}
}
So to test this (and currently new in the field of testing) I have cobbled together the following code. In it, i am attaching a generic identity with a username and some role data.
public void Given_UserIsNotInAuthorizedRoles_When_Auhtorizing_ReturnsForbidden()
{
// Arrange
IPrincipal principal = new GenericPrincipal(new GenericIdentity("TestName"), new[] { "TestRole" });
HttpActionContext mockActionContext = new HttpActionContext()
{
ControllerContext = new HttpControllerContext()
{
Request = new HttpRequestMessage(),
RequestContext = new HttpRequestContext() { Principal = principal }
},
ActionArguments = { { "SomeArgument", "null" } }
};
mockActionContext.ControllerContext.Configuration = new HttpConfiguration();
mockActionContext.ControllerContext.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
// Act
AuthorizationAttribute authAttr = new AuthorizationAttribute();
authAttr.OnAuthorization(mockActionContext);
// Assert
Assert.IsTrue(mockActionContext.Response.StatusCode == System.Net.HttpStatusCode.Forbidden);
}
The mock controller looks like this:
[Authorization(Roles = "AdminRoleOnly", Users = "A user")]
internal class MockController : ApiController { }
When I'm debugging, i am finding that if (IsAuthorized(actionContext))
is returning true
- which i don't understand.
Can someone point me in the direction of why my authorize attribute is passing this identity as good?
For what it's worth, this code works in production. I'm back-filling some tests.
Somewhat related, are these ones
I've read through the question and answer on a similar question ASP.NET MVC unit testing custom AuthorizeAttribute though neither really either work nor relate, especially given they're for MVC controllers and not Api Controllers.
I've also read and tried to implement the code in the answer on this question too Mocking HttpActionContext.ActionArguments when testing Web.Api ActionFilter
The latter gets me somewhere near in that my authorization attribute is firing in a test and I am able to pass in the required context information.
You need to assign a Role
to the AuthorizationAttribute
. In your example you have a TestRole
assign to the principal. Assign any other role but that.
// Act
AuthorizationAttribute authAttr = new AuthorizationAttribute() {
Roles = "SomeOtherRole"
};
and the test should behave as expected when exercised.
If you review the source code for IAuthorized You will see logic that checks if there are roles assigned to the attribute. If there are none to compare it will default to true
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With