12

What I want:

  1. A token generator use OAuthAuthorizationServer and token consumer use OAuthBearerAuthentication (authenticate the access token).
  2. Use OWIN pipeline to manage all stuff, token stuff and web api stuff.

What about the code:

public void Configuration(IAppBuilder app)
{
    app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    {
        AuthorizeEndpointPath = "/Authorize",
        AllowInsecureHttp = true,
        Provider = new OAuthAuthorizationServerProvider 
        {
            OnGrantCustomExtension = GrantCustomExtension,
            OnValidateClientRedirectUri = ValidateClientRedirectUri,
            OnValidateClientAuthentication = ValidateClientAuthentication,
        }
    });

    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
    {
        Provider = new OAuthBearerAuthenticationProvider 
        { 
            //Handles applying the authentication challenge to the response message.
            ApplyChallenge=MyApplyChallenge,

            //Handles processing OAuth bearer token.
            RequestToken=MyRequestToken,

            //Handles validating the identity produced from an OAuth bearer token.
            ValidateIdentity = MyValidateIdentity,
        }
    });

    app.UseWebApi(new WebApplication3.Config.MyWebApiConfiguration());
}

What's the question:

  1. The 3 properties of OAuthBearerAuthenticationProvider, ApplyChallenge, RequestToken and ValidateIdentity. How to implement the 3 methods?

  2. In the token authetication process, What I thought is to decrypt the access token, validate the token from the client, and if the token is validated, put the identities of the token to the HttpContext.Current.User.

    The OAuthBearerAuthenticationProvider's responsibility is to fulfill the previous steps. Am I right?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Albert Gao
  • 3,653
  • 6
  • 40
  • 69
  • Have you used the [walkthrough](http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server) on the ASP website? – Matthew Haugen Aug 02 '14 at 16:43
  • @MatthewHaugen Absolutely, but they didn't mention the 3 methods in OAuthBearerAuthenticationProvider – Albert Gao Aug 02 '14 at 17:03
  • May I ask why you want to implement them, then? I mean don't get me wrong, it's good to always know all your options. I'm just curious of why you'd want to override default behavior in your case, which doesn't sound like you need anything out of the ordinary. – Matthew Haugen Aug 02 '14 at 17:17
  • @MatthewHaugen The documents of official owin middleware is poor. :( Do you mean that the middleware has already do the decrypting, validating and put Principal for me @_@ ? – Albert Gao Aug 02 '14 at 17:33
  • If you follow that walkthrough, you will wind up with a working implementation. So yes. You might want to do other stuff after that, but I'd start off just getting what the walkthrough says working first. But yes, I certainly agree that the documentation leaves to be desired. – Matthew Haugen Aug 02 '14 at 17:34
  • @MatthewHaugen Finally, get to know all the magic by reading the source code of Katana on CodePlex.com @_@ The fault here is MS always encapsulates too much with a meaningless method name.... – Albert Gao Aug 03 '14 at 03:55

1 Answers1

7

As you know, UseOAuthAuthorizationServer has the job of authenticating the user. Then, UseOAuthBearerAuthentication has the job of ensuring that only authenticated users can access your application. Often, these two jobs are assigned to different web application. It looks like your application is doing both.

There are certainly some cases were you need to override the default OAuthBearerAuthenticationProvider. Maybe you do, or maybe you don't In my case, ApplicationCookie didn't quite fit the scenario. So, I'm storing a 3rd party JWT token in a cookie, rather than the header, and using it to indicate that the user is authenticated to a web application. I also needed to redirect to my own login page, rather than provide a 401.

Here's an implementation that does both:

public class CustomOAuthBearerProvider : IOAuthBearerAuthenticationProvider
{
    public Task ApplyChallenge(OAuthChallengeContext context)
    {
        context.Response.Redirect("/Account/Login");
        return Task.FromResult<object>(null);
    }

    public Task RequestToken(OAuthRequestTokenContext context)
    {
        string token = context.Request.Cookies[SessionKey];
        if (!string.IsNullOrEmpty(token))
        {
            context.Token = token;
        }
        return Task.FromResult<object>(null);
    }
    public Task ValidateIdentity(OAuthValidateIdentityContext context)
    {
        return Task.FromResult<object>(null);
    }
}

I didn't need to do anything special in ValidateIdentity, but I needed to satisfy the interface.

To wire this up, tell your app to use JwtBearerAuthentication with your provider:

// controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions
    {
        AllowedAudiences = audiences.ToArray(),
        IssuerSecurityTokenProviders = providers.ToArray(),
        Provider = new CookieOAuthBearerProvider()
    }
);
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
AJ Morris
  • 1,099
  • 2
  • 10
  • 19
  • 2
    If I have to add application specific claims which the server did not provide (external login like Azure AD), is it OK to add this claims in ValidateIdnetity? If the authenticated user although part of the organization does not have access to the application, where do I send him 401 status? – Hemant Jul 08 '15 at 16:14
  • @AJ Morris, how would you override the token validation using `OAuthBearerAuthenticationProvider` ? Is there way to do this? – gorillapower Feb 09 '17 at 07:39
  • I'm guessing that `Provider = new CookieOAuthBearerProvider()` should be `Provider = new CustomOAuthBearerProvider()`? – Philip Stratford Jul 19 '18 at 14:48
  • How can I do this in ASP.NET Core 2? I have posted a question about it: https://stackoverflow.com/questions/52184431/in-asp-net-core-read-jwt-token-from-cookie-instead-of-headers – Afshar Mohebi Sep 05 '18 at 11:50
  • oh my god, the requestToken method saved my life. been banging my head against the wall for days now, trying to get the token to work from cookies. thank you !! – Contra Mar 27 '19 at 12:36