Reputation:
I've created a backend WebApi to create JWT tokens and they're working fine when I use PostMan to access restricted resources by adding the token to the header, e.g. [Authorise(Roles="SuperAdmin")].
I want to use this infrastructure with my MVC app, but don't quite know how to tie it together.
I'm guessing that when the user creates an account and I generate a JWT for them (Via the WebApi), I need to stick the token in a cookie, but how do this and also extract the JWT from the cookie on future requests, so that it will work with the normal [Authorize] attribute that I decorate the ActionResults with?
Do I need to put something in the Owin pipeline? Or do I need to create a custom [Authorize] attribute?
My Startup.cs file currently looks like this:
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
ConfigureOAuthTokenGeneration(app);
ConfigureOAuthTokenConsumption(app);
ConfigureWebApi(httpConfig);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(httpConfig);
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//TODO: enforce https in live
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat("https://localhost:443")
};
// Plugin the OAuth bearer JSON Web Token tokens generation and Consumption will be here
// OAuth 2.0 Bearer Access Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
private void ConfigureOAuthTokenConsumption(IAppBuilder app)
{
var issuer = "https://localhost:443";
string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]);
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] { audienceId },
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{
new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
}
});
}
private void ConfigureWebApi(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
If it helps, I was following this guide: http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/
Upvotes: 2
Views: 4698
Reputation: 7394
The infrastructure your referred to is really designed to handle direct web API calls. A classic redirect based web app would fall back on more traditional patterns, where the app receives one token, validates it and uses it to initiate an authenticated session (by saving the results of the token validation in some session artifact, like a token). Although you can implement this patters starting form any token based system, including your custom one, usually it's more convenient (and secure) to leverage existing protocols (like OpenId Connect) and existing products (like Azure AD or Identity Server). See this for a simple example based on Azure AD - the middleware remains the same no matter what OpenId Provider you pick.
Upvotes: 2