C# Intregration tests on Webapi Controller ignores Authentication Attribute

Viewed 37

In my solution which is based on .NET Framework 4.8 I have a simple controller which uses JWT for Authentication. As an example I have this simple API function:

[HttpGet]
[JwtAuthentication]
public async Task<IHttpActionResult> GetISOCodes()
{
    var languageCodes = await dBReader.GetISOLanguageCodes();

    return Ok(languageCodes);
}

The attribute implements IAuthenticationFilter and looks like this:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class JwtAuthenticationAttribute : Attribute, IAuthenticationFilter
{
    public string Realm { get; set; }
    public bool AllowMultiple => false;

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        var request = context.Request;
        var authorization = request.Headers.Authorization;

        var token = authorization.Parameter;
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        return Task.FromResult(0);
    }
}

I want to cover my controller with integration tests that also include the token handling so I intend to write as follows:

[TestMethod]
[ExpectedException(typeof(JwtAuthenticationException))]
public async Task GetISOCodes_NoHeader_ThrowException()
{
    // Act
    await languagecontroller.GetISOCodes();
}

[TestMethod]
[ExpectedException(typeof(JwtAuthenticationException))]
public async Task GetISOCodes_WithHeader_ThrowException()
{
    // Arrange
    var token = string.Empty;

    var controllerContext = new HttpControllerContext() { RequestContext = new HttpRequestContext() };
    var request = new HttpRequestMessage();
    request.Headers.Add("Authorization", "Bearer " + token);

    controllerContext.Request = request;
    languagecontroller.ControllerContext = controllerContext;

    // Act
    await languagecontroller.GetISOCodes();
}

For some reason the AuthenticateAsync function or lets better say the entire attribute is skipped. Does anybody know, what I am missing to make this work?

1 Answers

I would not recommend this.

Instead do this .... call the actual endpoints to do stuff just like a normal client would.

So, you issue a call to your token endpoint and then use that token to call whatever other endpoint you want to test.

Instantiating and calling controller methods tells me there isn't enough SOC and then it's not an integration test to begin with.

Don't fake things with integration tests, call endpoints instead.

Related