Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integration test on controller decorated with [Authorize] attribute

My application is an ASP.NET Core 1.0 Web API.

How do I test a controller which is decorated with the Authorize attribute?

For example, with this controller and test method:

[TestMethod]
public void GetSomeDataTest()
{
   var controller = new MyController();
   Assert.AreEqual(controller.GetSomeData(), "Test");
}

[Authorize]
public ActionResult GetSomeData()
{
   return this.Content("Test");
}

This is just an example code to make it possible for you guys to answer. I am actually invoking the Controller via a TestServer object.

This has already been asked but the accepted answer doesn't work anymore. Any suggestions how I could "fake" the users' authenticity?

like image 891
Moritz Schmidt Avatar asked Apr 03 '17 12:04

Moritz Schmidt


People also ask

What does Authorize attribute do?

The Authorize attribute is inheritable. This means that you can add it to a base controller class of yours and thereby ensure that any methods of any derived controllers are subject to authentication. NOTE: In general, any public method on a Controller class can be invoked via a valid URL.

When should we use Authorize attribute?

This attribute is useful when you want to use the Authorize attribute on a controller to protect all of the actions inside, but then there is this single action or one or two actions that you want to unprotect and allow anonymous users to reach that specific action.

What happens if you apply the AllowAnonymous attribute to a controller action that already uses the Authorize attribute?

If you combine [AllowAnonymous] and any [Authorize] attribute, the [Authorize] attributes are ignored. For example if you apply [AllowAnonymous] at the controller level, any [Authorize] attributes on the same controller (or on any action within it) is ignored.


1 Answers

You could set a claim principle to the current thread

[TestInitialize]
public void Initialize()
{
    var claims = new List<Claim>() 
    { 
        new Claim(ClaimTypes.Name, "UserName"),
        new Claim(ClaimTypes.Role, "Admin")
    };
    var identity = new ClaimsIdentity(claims, "TestAuth");
    var claimsPrincipal = new ClaimsPrincipal(identity);
    Thread.CurrentPrincipal = claimsPrincipal;
}

For .NET Core, you could set the user to the controller context

private MyController _ctrl;

[TestInitialize]
public void Initialize()
{
    var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
    {
         new Claim(ClaimTypes.Name, "UserName"),
         new Claim(ClaimTypes.Role, "Admin")
    }));

    _ctrl = new MyController();
    _ctrl.ControllerContext = new ControllerContext()
    {
        HttpContext = new DefaultHttpContext() { User = user }
    };
}

[TestMethod]
public void GetSomeDataTest()
{
    Assert.AreEqual(_ctrl.GetSomeData(), "Test");
}
like image 57
Marcus Höglund Avatar answered Oct 13 '22 09:10

Marcus Höglund