Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

Commit

Permalink
Use opaque tokens by default and update the MVC sample to use the new…
Browse files Browse the repository at this point in the history
… validation middleware
  • Loading branch information
kevinchalet committed Dec 12, 2015
1 parent 2a60743 commit 939067d
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 36 deletions.
1 change: 1 addition & 0 deletions NuGet.config
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="aspnet-contrib" value="https://www.myget.org/F/aspnet-contrib/api/v2" />
<add key="AspNetVNext" value="https://www.myget.org/F/aspnetvnext/api/v2" />
<add key="WebStack Nightly" value="http://www.myget.org/f/aspnetwebstacknightly/" />
<add key="AzureAd Nightly" value="http://www.myget.org/F/azureadwebstacknightly/" />
Expand Down
4 changes: 0 additions & 4 deletions samples/Mvc/Mvc.Client/Startup.cs
Expand Up @@ -54,10 +54,6 @@ public class Startup {
// retrieve the identity provider's configuration and spare you from setting
// the different endpoints URIs or the token validation parameters explicitly.
options.Authority = "http://localhost:54540/";
// Note: the resource property represents the different endpoints the
// access token should be issued for (values must be space-delimited).
options.Resource = "http://localhost:54540/";
});

app.UseStaticFiles();
Expand Down
10 changes: 3 additions & 7 deletions samples/Mvc/Mvc.Server/Controllers/AuthorizationController.cs
Expand Up @@ -129,19 +129,15 @@ public class AuthorizationController : Controller {

var properties = new AuthenticationProperties();

// Note: you can change the list of scopes granted
// to the client application using SetScopes:
// Set the list of scopes granted to the client application.
properties.SetScopes(new[] {
/* openid: */ OpenIdConnectConstants.Scopes.OpenId,
/* email: */ OpenIdConnectConstants.Scopes.Email,
/* profile: */ OpenIdConnectConstants.Scopes.Profile
});

// You can also limit the resources endpoints
// the access token should be issued for:
properties.SetResources(new[] {
"http://localhost:54540/"
});
// Set the resources servers the access token should be issued for.
properties.SetResources(new[] { "resource_server" });

// This call will instruct AspNet.Security.OpenIdConnect.Server to serialize
// the specified identity to build appropriate tokens (id_token and token).
Expand Down
11 changes: 2 additions & 9 deletions samples/Mvc/Mvc.Server/Controllers/ResourceController.cs
@@ -1,5 +1,4 @@
using System.Globalization;
using System.Security.Claims;
using System.Security.Claims;
using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Mvc;

Expand All @@ -13,13 +12,7 @@ public class ResourceController : Controller {
return HttpBadRequest();
}

// Note: identity is the ClaimsIdentity representing the resource owner
// and identity.Actor is the identity corresponding to the client
// application the access token has been issued to (delegation).
return Content(string.Format(
CultureInfo.InvariantCulture,
"{0} has been successfully authenticated via {1}",
identity.Name, identity.Actor.Name));
return Content($"{identity.Name} has been successfully authenticated.");
}
}
}
29 changes: 24 additions & 5 deletions samples/Mvc/Mvc.Server/Startup.cs
Expand Up @@ -39,14 +39,23 @@ public class Startup {

// Create a new branch where the registered middleware will be executed only for API calls.
app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch => {
branch.UseJwtBearerAuthentication(options => {
branch.UseOAuthValidation(options => {
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
options.RequireHttpsMetadata = false;
options.Audience = "http://localhost:54540/";
options.Authority = "http://localhost:54540/";
});
// Alternatively, you can also use the introspection middleware.
// Using it is recommended if your resource server is in a
// different application/separated from the authorization server.
//
// branch.UseOAuthIntrospection(options => {
// options.AutomaticAuthenticate = true;
// options.AutomaticChallenge = true;
// options.Authority = "http://localhost:54540/";
// options.Audience = "resource_server";
// options.ClientId = "resource_server";
// options.ClientSecret = "875sqd4s5d748z78z7ds1ff8zz8814ff88ed8ea4z4zzd";
// });
});

// Create a new branch where the registered middleware will be executed only for non API calls.
Expand Down Expand Up @@ -106,6 +115,7 @@ public class Startup {
// Note: by default, tokens are signed using dynamically-generated
// RSA keys but you can also use your own certificate:
//
// options.SigningCredentials.AddCertificate(certificate);
});

Expand All @@ -116,6 +126,15 @@ public class Startup {
app.UseWelcomePage();

using (var database = app.ApplicationServices.GetService<ApplicationContext>()) {
// Note: when using the introspection middleware, your resource server
// MUST be registered as an OAuth2 client and have valid credentials.
//
// database.Applications.Add(new Application {
// ApplicationID = "resource_server",
// DisplayName = "Main resource server",
// Secret = "875sqd4s5d748z78z7ds1ff8zz8814ff88ed8ea4z4zzd"
// });

database.Applications.Add(new Application {
ApplicationID = "myClient",
DisplayName = "My client application",
Expand Down
1 change: 0 additions & 1 deletion samples/Mvc/Mvc.Server/Views/Shared/Authorize.cshtml
Expand Up @@ -8,7 +8,6 @@
<h1>Authorization</h1>

<p class="lead text-left">Do you wanna grant <strong>@Model.Item2.DisplayName</strong> an access to your resources? (scopes requested: @Model.Item1.Scope)</p>
<p class="lead text-left"><strong>@Model.Item2.DisplayName</strong> will be able to access the following endpoints: @string.Join(" ; ", Model.Item1.GetResources())</p>

<form enctype="application/x-www-form-urlencoded" method="post">
@Html.AntiForgeryToken()
Expand Down
3 changes: 2 additions & 1 deletion samples/Mvc/Mvc.Server/project.json
Expand Up @@ -11,7 +11,6 @@
"Microsoft.AspNet.Mvc": "6.0.0-*",
"Microsoft.AspNet.Authentication.Cookies": "1.0.0-*",
"Microsoft.AspNet.Authentication.Google": "1.0.0-*",
"Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-*",
"Microsoft.AspNet.Authentication.Twitter": "1.0.0-*",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
Expand All @@ -20,6 +19,8 @@
"Microsoft.Extensions.Logging.Console": "1.0.0-*",
"Microsoft.Extensions.Logging.Debug": "1.0.0-*",

"AspNet.Security.OAuth.Introspection": "1.0.0-*",
"AspNet.Security.OAuth.Validation": "1.0.0-*",
"AspNet.Security.OpenIdConnect.Server": "1.0.0-*"
},

Expand Down
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
Expand Down Expand Up @@ -341,14 +342,12 @@ public static class OpenIdConnectServerExtensions {
}

/// <summary>
/// Configures the OpenID Connect server to issue opaque access tokens produced by the data protection block.
/// Opaque tokens cannot be read by client applications or resource servers if they don't share identical keys.
/// Note: you can use the validation endpoint to validate opaque tokens directly on the authorization server.
/// Configures the OpenID Connect server to issue JWT access tokens.
/// </summary>
/// <param name="options">The options used to configure the OpenID Connect server.</param>
/// <returns>The options used to configure the OpenID Connect server.</returns>
public static OpenIdConnectServerOptions UseOpaqueTokens([NotNull] this OpenIdConnectServerOptions options) {
options.AccessTokenHandler = null;
public static OpenIdConnectServerOptions UseJwtTokens([NotNull] this OpenIdConnectServerOptions options) {
options.AccessTokenHandler = new JwtSecurityTokenHandler();

return options;
}
Expand Down
Expand Up @@ -140,6 +140,11 @@ internal partial class OpenIdConnectServerHandler : AuthenticationHandler<OpenId
ticket = notification.AuthenticationTicket;
ticket.Properties.CopyTo(properties);

// Add the intented audiences in the authentication ticket.
if (notification.Audiences.Count != 0) {
ticket.SetAudiences(notification.Audiences);
}

if (notification.SecurityTokenHandler == null) {
return notification.DataFormat?.Protect(ticket);
}
Expand Down
Expand Up @@ -129,11 +129,10 @@ public class OpenIdConnectServerOptions : AuthenticationOptions {

/// <summary>
/// The <see cref="SecurityTokenHandler"/> instance used to forge access tokens.
/// You can set it to null to produce opaque tokens serialized by the data protector subsytem.
/// This property is only used when <see cref="IOpenIdConnectServerProvider.SerializeAccessToken"/> doesn't call
/// <see cref="BaseControlContext.HandleResponse"/>.
/// Note: this property is only used when <see cref="IOpenIdConnectServerProvider.SerializeAccessToken"/>
/// doesn't call <see cref="BaseControlContext.HandleResponse"/>.
/// </summary>
public SecurityTokenHandler AccessTokenHandler { get; set; } = new JwtSecurityTokenHandler();
public SecurityTokenHandler AccessTokenHandler { get; set; }

/// <summary>
/// The <see cref="JwtSecurityTokenHandler"/> instance used to forge identity tokens.
Expand Down

0 comments on commit 939067d

Please sign in to comment.