2

I use token auth for my WebApi application.

I have the following ConfigureAuth method in Startup class:

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);

and ApplicationOAuthProvider:

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
    private readonly string _publicClientId;

    public ApplicationOAuthProvider(string publicClientId)
    {
        if (publicClientId == null)
        {
            throw new ArgumentNullException("publicClientId");
        }

        _publicClientId = publicClientId;
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

        var user = await userManager.FindAsync(context.UserName, context.Password);
        //ApplicationUser user = new ApplicationUser() { UserName ="a" };

        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }

        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
            CookieAuthenticationDefaults.AuthenticationType);

        AuthenticationProperties properties = CreateProperties(user.UserName);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

so, I should call /Token and pass credentials to get token. It works, but I want to create Unit Test for it. Is it possible?

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159

2 Answers2

5

The only way to do that is by make an integration test, which asserts the full pipeline testing - from request to response. Before the actual test on the server, you can call the token endpoint to get it, and then use it in the actual unit test by attaching it to the response. I have a sample, which uses MyTested.WebApi here:

Sample

You can do the same without the testing library, this is just how to do it.

0

I like the idea of pluggable configuration. For Unit Test project, I want to use specific identity and get predictable data fro LDAP. So, i use the following line in my unit test method when setting http configuration:

config.Filters.Add(new WebApiSetIdentityFilter(config, identityName));

where the filter just "hacks" the identity, replacing the fields I need:

public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
    //This principal flows throughout the request.
    context.Principal = new GenericPrincipal(new GenericIdentity(this.IdentityName, "LdapAuthentication"), new string[0]);
}
Alexander
  • 1,152
  • 1
  • 16
  • 18