1

We've already asked and received a answer about how to do Resource Owner Password Credential flow. Configure the authorization server endpoint We're able to receive an access token from the Identity Server and to store it in the Relying Party's data store.

What we need now is to learn how to validate the access token at the Resource Server.

In the Startup of our Resource Server, we currently have this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication();
}

public void Configure(IApplicationBuilder app)
{
    // Add a new middleware validating access tokens issued by the server.
    app.UseOAuthBearerAuthentication(options =>
    {
        options.AutomaticAuthentication = true;
        options.Audience = "http://localhost:50000/";
        options.Authority = "http://localhost:50000/";
    });

    app.Run(async (context) =>
    {
        // this runs on each request not just per application startup
        await context.Response.WriteAsync(DateTime.Now.ToString() + 
            " Hello Resource Owner Password Flow...");
    });
}

What do we need to add within, say, a Controller/Action in the Resource Server, to check whether access token validation succeeded? E.g. in psuedo-code:

public string MyAction()
{
    if(AccessTokenIsValid())
    {
        return "one thing.";
    } 
    else
    {
        return "another.";
    }
}
Community
  • 1
  • 1
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467

1 Answers1

1

It should be super easy:

public string MyAction()
{
    if (User.Identity.IsAuthenticated)
    {
        return "one thing.";
    } 
    else
    {
        return "another.";
    }
}

You could also use the new approach ASP.NET 5 favors, which is basically the same snippet iterating over the different identities of the ClaimsPrincipal to determine if there's an authenticated one.

public string MyAction()
{
    if (User.Identities.Any(identity => identity.IsAuthenticated))
    {
        return "one thing.";
    } 
    else
    {
        return "another.";
    }
}
Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
  • 1
    Of course, if you simply need to block unauthenticated requests (instead of returning a different value), using `AuthorizeAttribute` will be far easier. – Kévin Chalet Jun 23 '15 at 23:34
  • 1
    Cool. We've also seen this: `context.User?.FindFirst("access_token")` which I'm assuming should just work too. Is that right? That's new syntax for me... for instance, putting the ? before the dot seems odd. Does that like, automatically check for `null` or something, and what is `FindFirst` searching? Is it the `User`, the request body, a query string parameter. I'll have to look into it some more. – Shaun Luttin Jun 23 '15 at 23:34
  • 1
    It won't work OTB because the bearer middleware doesn't store the token as a claim (you can do that using the `SecurityTokenValidated` notification) ; because in general, you don't need to retrieve the access token from the resource server (aka, your API). It's far more useful on the client application because you often need the access token to query your API (you can take a look at https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/vNext/samples/Mvc/Mvc.Client/Startup.cs#L104 for a sample) – Kévin Chalet Jun 23 '15 at 23:39
  • 1
    The new `?.` syntax is basically another way to return null when one of the members is itself null: `context.User == null ? null : context.User.FindFirst("access_token")`. – Kévin Chalet Jun 23 '15 at 23:41
  • 1
    On the resource server, won't we often want to inspect the claim to find out the user's role. If authorization is role based, that seems important, so I'm surprised to hear it's an uncommon use case. What's the more common approach to role based authorization on the resource server if not inspecting the token for its claims? In other words, on the resource server, how do we determine the role? Or does it just work using `IsInRole()`? – Shaun Luttin Jun 23 '15 at 23:47
  • 1
    My comment was probably not clear enough, sorry. Of course, retrieving user's claims is a totally common scenario, and can be easily done via User.FindFirst. My remark was just about extracting the "access_token" claim, which would simply return the raw JWT token and not the claims themselves. Sorry for the confusion. – Kévin Chalet Jun 23 '15 at 23:50
  • 1
    BTW, ASP.NET 5 offers a whole new authorization block that uses "authorization policies". It's a pretty cool thing: you define a policy in Startup.cs, you give it a name, and you can use it with AuthorizeAttribute: `[Authorize("yourpolicy")]` https://github.com/aspnet/MusicStore/blob/dev/src/MusicStore/Startup.cs#L118-L121 – Kévin Chalet Jun 23 '15 at 23:53
  • 1
    I appreciate that because it's hard to find documentation on the new ASP.NET 5 authorization - reading the source and samples seems to be the best approach for now. Once I understand it, I may find the time to contribute the parts of docs.asp.net that need someone to write it. E.g. http://docs.asp.net/en/latest/security/authorization/claims.html I'll probably start with a walkthru of the resource owner password flow that you've been explaining to me. – Shaun Luttin Jun 23 '15 at 23:56
  • 1
    Great! Writing a tutorial on how to migrate from the old OAuth2 authorization server middleware to the new OIDC middleware was also on my todo list. I asked Eilon from the ASP.NET and he told me it was a good idea. Don't hesitate if you want me to participate to your PR. – Kévin Chalet Jun 24 '15 at 00:07