Setting up basic OAuth with OWIN is very simple using username/password flow.
Install nuget
Microsoft.Owin.Security.OAuth
Once you install it, you will need to do two things
- First, write a class which implement authentication logic
- Second, integrate that class with OWIN.
Implementing provider
Lets define a class which implements `OAuthAuthorizationServerProvider`
[sourcecode language=”csharp”]
public class SimpleAuthorizationProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
await Task.Run(() => context.Validated());
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
if (context.Password != context.UserName)
{
context.SetError("invalid_password", "The user name or password is incorrect.");
return;
}
await Task.Run(() => context.Validated(new ClaimsIdentity(context.Options.AuthenticationType)));
}
}
[/sourcecode]
Integrate Provided
Now we need to configure OWIN to use OAUTH. so change the existing OwinConfiguration class to look like below
[sourcecode language=”csharp”]
public class OwinConfiguration
{
public void Configuration(IAppBuilder app)
{
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
Provider = new SimpleAuthorizationProvider()
});
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
Provider = new OAuthBearerAuthenticationProvider()
});
}
}
[/sourcecode]
Setting the authentication mode to active will help us in having `IPrincipal` set for web-api’s.
Testing
Owin provides its own testing framework as well. Please install nuget:
Microsoft.Owin.Testing
Once installed please add below tests and make sure that they passes.
[sourcecode language=”csharp”]
[TestFixture]
public class OwinTests
{
[Test]
public async Task Should_Authenticate_User()
{
using (var server = TestServer.Create<OwinConfiguration>())
{
var response = await server.CreateRequest("/token")
.And(x => x.Content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "admin"),
new KeyValuePair<string, string>("password", "admin"),
new KeyValuePair<string, string>("grant_type", "password")
})).PostAsync();
response.IsSuccessStatusCode.Should().BeTrue();
response.StatusCode.Should().Be(HttpStatusCode.OK);
}
}
[Test]
public async Task Should_Fail_Authentication()
{
using (var server = TestServer.Create<OwinConfiguration>())
{
var response = await server.CreateRequest("/token")
.And(x => x.Content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "admin"),
new KeyValuePair<string, string>("password", "wrong-password"),
new KeyValuePair<string, string>("grant_type", "password")
})).PostAsync();
response.IsSuccessStatusCode.Should().BeFalse();
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}
}
}
[/sourcecode]