In my previous installment, I focused mostly on sharing Cookies between an OWIN application and a .NET Core application. What happens if you want to utilize the Bearer tokens as well?
Out of the box, .NET Core supports JSON Web Tokens (JWT) for authentication/authorization on API endpoints. However, without modifying a ton of stuff in our OWIN OAuthserver, bearer tokens from OWIN are not JWT’s. This present a problem if you want to use the tokens for a .NET Core API endpoint.
Since we already got all of the IDataProtectionProvider stuff sorted out, it’s actually pretty easy to get this working with a custom Middleware. The basic premise is that the Middleware should intercept any requests and check for an Authorization token. If it’s detected, then the token should be decrypted in order to provide us with an AuthrnticationTicket. Using the AuthenticationTicket, we can instantiate a ClaimsIdentity and attach it to the context. This providers our validated user to the current request.
The Middleware looks like this:
public class AuthenticationMiddleware { private IDataProtectionProvider _protectionProvider; private readonly RequestDelegate _next; private List<string> _purpose = new List<string>() { "TokenMiddleware", "Access_Token", "v2" }; public AuthenticationMiddleware(RequestDelegate next, IDataProtectionProvider protectionProvider) { _next = next; _protectionProvider = protectionProvider; } public async Task Invoke(HttpContext context) { if (!context.User.Identity.IsAuthenticated) { try { var authorizeHeader = context.Request.Headers["Authorization"]; if (authorizeHeader != StringValues.Empty) { var authType = "bearer"; string token = authorizeHeader.FirstOrDefault(); if (token?.StartsWith(authType, StringComparison.OrdinalIgnoreCase) ?? false) { var regEx = new Regex(authType, RegexOptions.IgnoreCase); token = regEx.Replace(token, string.Empty).TrimStart(); var dataProtector = _protectionProvider.CreateProtector(_purpose); string decryptedToken = dataProtector.Unprotect(token); TicketSerializer serializer = new TicketSerializer(); AuthenticationTicket ticket = serializer.Deserialize(Encoding.UTF8.GetBytes(decryptedToken)); context.User = ticket.Principal; } } } catch (Exception ex) { Console.WriteLine(ex); } } await _next(context); } }
After defining the Middleware, we only need to tell IAppBuilder to use it. I put this as the first Middleware handler.
// Put our bearer token check first app.UseMiddleware<AuthenticationMiddleware>();
The only other change I had to make was to ensure that the same application name is used for all of the IDataProtectionProviders used across the various applications. Otherwise, the IDataProtector “unprotect” will fail.
In the future, of course, I will update things to utilize JWT’s and move to a secure token provider other than OWIN. For now, though, this is a very convenient stop-gap.
Hi. Do you have any sample project with this working? I am trying to put it to work but keep getting “Payload is invalid” in the core project
I do not have a fully working OWIN + .NET Core project showing this integration, but I can (and will) put a solution together pretty quickly for illustration.
In the meantime, if you are gettnig “Payload is invalid,” that indicates different encryption/decryption schemes between the two applications. Ensure that your “purposes” and application name are the same across the applications.
Yeah I almost missed your final comments on the article but I put the same name and purpose but still failing. Hoping when I look to your project I will get what I missed =/
Did you still need a sample? I didn’t have time to put together a working sample last week, but should have some time to put one together this week if you still need one.
Yes please! Still hiting my head on the wall to solve this haha
Just to mention. My problem is on the token flow. Didnt try to put cookie to work because I dont use cookie today.
Oh!
Well, that’s probably failing because .NET Core, by default, won’t interpret/intercept the bearer token and decrypt it accordingly. That is the purpose of the middleware described here.
Do you have it in your project with defined as the first middleware handler?
The other thing that comes to mind, if you look at Part 1 (https://long2know.com/2017/05/sharing-cookies-and-tokens-between-owin-and-net-core/) ..
Look at the lines where I have specifically set the DataProtector for the AccessToken:
That’s critical to ensure the “bearerProtector” with the expected purpose is used.
Hi, do you have a sample application with all of this working?
Sorry for the slow reply, but I can probably put together a working sample from some other templates that I have available.