2

I am having a lot of trouble getting my asp.net 5 web app to be able to accept JWT tokens. I have the code already fully functional using mvc5 and just want some help converting this code to be identical but work with mvc6. The way it is set up is my client (web-site) is a trusted app and uses an IssuerSigningToken to validate the trusted app status, and after that I can just pass JWT tokens and get user and claims details back from auth server.

old code:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration httpConfig = new HttpConfiguration();
    app.UseJwtBearerAuthentication(new MyJwtOptions());
    app.UseWebApi(httpConfig);
    ConfigureWebApi(httpConfig);
    app.UseWebApi(httpConfig);
}

public class MyJwtOptions : JwtBearerAuthenticationOptions
{
    public MyJwtOptions()
    {
        var issuer = "https://tv.domain.com/trust/domain";
        var audience = "https://www.domain.com/";
        var key = Convert.FromBase64String("dW8E7DDKW34DDW33jg=");
        AllowedAudiences = new[] {audience};
        IssuerSecurityTokenProviders = new[] {new SymmetricKeyIssuerSecurityTokenProvider(issuer, key)};
    }
}

The best example I can find that comes close is here - JwtBearerSample

        app.UseJwtBearerAuthentication(options =>
        {
            options.AutomaticAuthenticate = true;
            options.AutomaticChallenge = true;
            // You also need to update /wwwroot/app/scripts/app.js
            options.Authority = Configuration["jwt:authority"];
            options.Audience = Configuration["jwt:audience"];
        });

I can not figure out if I am close or not, my main problem is how to I add the IssuerSignerToken ? I am using Thinktecture , and it doesn't seem like they have any new up-to-date example up yet. Has anyone accomplished what I am trying to do? I know there are several other similar questions , but the responses to those use X.509 Certificates , I would prefer if possible to use the same string key for IssuerSignerToken

UPDATE

my problem is the options I used to use inherited from Microsoft.Owin.Security.JwtBearerAuthenticationOptions the new code expects Microsoft.AspNet.Authentication.JwtBearer.JwtBearerOptions

Scott Selby
  • 9,420
  • 12
  • 57
  • 96
  • I think you're looking for JwtBearerOptions.TokenValidationParameters.IssuerSigningToken. Otherwise explore TokenValidationParameters as that's where most of this configuration lives. – Tratcher Dec 18 '15 at 05:38
  • @Tratcher - thanks , I had another question trying to figure out how to set that parameter. It looks like that accepts type SecurityKey , and I am having trouble finding an example that uses an actual key instead of certificate – Scott Selby Dec 18 '15 at 06:31
  • Ask here: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet – Tratcher Dec 19 '15 at 07:49

3 Answers3

1

To use a symmetric key, you'll need to migrate to the RC2 nightly builds (it won't work natively with RC1).

Here's how you can specify the issuer key needed to validate JWT tokens (you don't need to subclass JwtBearerOptions or JwtBearerAuthenticationOptions for that):

var key = Convert.FromBase64String("dW8E7DDKW34DDW33jg=");

app.UseJwtBearerAuthentication(options => {
    options.AutomaticAuthenticate = true;
    options.AutomaticChallenge = true;

    options.Authority = Configuration["jwt:authority"];
    options.Audience = Configuration["jwt:audience"];

    options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(key);
});
Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
  • I'm going to try this out, do you any resources that you got this info from? This sounds absolutely perfect and I really hope it works. I am just curious how you knew that . I have been spending almost all day researching this for days now – Scott Selby Dec 20 '15 at 00:57
  • Haha, no particular resource, [except this commit](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/commit/ee7c72e61039718465a8ad60936f90a642e9e32f) (I'm just a long-time IdentityModel user, and [I use it massively in the projects I work on](https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server)). To migrate to RC2, add the `https://www.myget.org/F/aspnetvnext/` feed in your NuGet settings, run `dnvm upgrade -u` to use the latest DNX runtime and replace `rc1-final` by `*` in your project.json. – Kévin Chalet Dec 20 '15 at 01:15
  • I still don't understand if it was a bug that this support was left out of rc-1 or if it was intentional , got it all working now after 2 days of frustration , thanks – Scott Selby Dec 21 '15 at 19:47
  • since you were my savior on this , can you please assist with trying to set the RedirectUrl for this ? check ou http://stackoverflow.com/questions/34629768/redirect-to-url-instead-of-401-for-unauthenticated – Scott Selby Jan 06 '16 at 09:39
  • @ScottSelby answered ;) – Kévin Chalet Jan 06 '16 at 11:35
  • @Pinpoint, do you know of any tutorials for RC1 for authenticating username/password/token for WebAPIs. I haven't found anything that is current. I was hoping that I could build on the latest and greatest for this new project but it's looking more and more likely that I will have to go back to ASP.NET 4 w/ WebAPI. – Jon49 Jan 15 '16 at 20:18
  • Here's a tutorial about OpenIddict, but you'll need to migrate to RC2: http://capesean.co.za/blog/asp-net-5-jwt-tokens/. Alternatively, if you don't want to migrate to RC2 or don't want to use OpenIddict, you can also give ASOS a try. You'll have to manually implement the resource owner password grant, but it's really easy: http://stackoverflow.com/a/30857524/542757. – Kévin Chalet Jan 15 '16 at 20:28
0

Pinpoint's answer is exactly right, I though thought I could add on that and prevent hours of frustrating problems while getting this to work.

do not set anything to the property Authority

// even if everything else is properly set you will get 500
// some demos tell you to put CLientId here , that is wrong
options.Authority = "";

you can't set the configurations directly , you have to make a new Configurations object like so:

 options.Configuration = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration()
 {
     Issuer = "https://tv.domain.com/trust/domain"
 };

in MVC5 you would use System.Security.Claims in your controller to get current User like so:

var user = ClaimsPrincipal.Current;

that will no longer work, now you will add this in the controller:

var user = User.Identity;
Scott Selby
  • 9,420
  • 12
  • 57
  • 96
  • do you know of any tutorials for RC1 for authenticating username/password/token for WebAPIs. I haven't found anything that is current. I was hoping that I could build on the latest and greatest for this new project but it's looking more and more likely that I will have to go back to ASP.NET 4 w/ WebAPI. – Jon49 Jan 15 '16 at 16:59
  • @pinpoint is literally the expert to go to about that if you can get ahold of him – Scott Selby Jan 15 '16 at 19:27
  • @ScottSelby haha, thanks! I posted my answer as a comment under the previous post ;) – Kévin Chalet Jan 15 '16 at 20:29
0

You can use it like this :

 app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = clientIds,
                IssuerSecurityKeyProviders = new IIssuerSecurityKeyProvider[]
                {
                    new SymmetricKeyIssuerSecurityKeyProvider(issuer, key)
                }
            });
Gal Koren
  • 73
  • 1
  • 10