Skip to content

Commit 7230a49

Browse files
Update for ASP.NET Core 2.0
Update the generator to produce providers for ASP.NET Core 2.0.
1 parent 961c626 commit 7230a49

12 files changed

+264
-207
lines changed

generators/app/index.js

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ var yosay = require('yosay');
66
module.exports = yeoman.generators.Base.extend({
77
initializing: function() {
88
this.templatedata = {};
9-
10-
this.log(yosay('Welcome to the classy ' + chalk.yellow('ASP.NET OAuth Provider') + ' generator!'));
9+
10+
this.log(yosay('Welcome to the classy ' + chalk.yellow('ASP.NET OAuth Provider') + ' generator!'));
1111
},
12-
12+
1313
prompting: function () {
1414
var done = this.async();
1515

@@ -18,7 +18,7 @@ module.exports = yeoman.generators.Base.extend({
1818
name: 'name',
1919
message: 'What is the name of the provider you want to create?',
2020
store: true
21-
},
21+
},
2222
{
2323
type: 'input',
2424
name: 'authorname',
@@ -50,22 +50,19 @@ module.exports = yeoman.generators.Base.extend({
5050
this.templatedata.authorizationendpoint = props.authorizationendpoint;
5151
this.templatedata.tokenendpoint = props.tokenendpoint;
5252
this.templatedata.userinformationendpoint = props.userinformationendpoint;
53-
53+
5454
this.name = props.name;
5555
this.applicationname = 'AspNet.Security.OAuth.' + props.name
56-
56+
5757
done();
5858
}.bind(this));
5959
},
6060

6161
writing: function() {
62-
this.fs.copyTpl(this.templatePath('project.json'), this.applicationname + '/project.json', this.templatedata)
63-
this.fs.copyTpl(this.templatePath('Project.xproj'), this.applicationname + '/' + this.applicationname + '.xproj', this.templatedata)
62+
this.fs.copyTpl(this.templatePath('Project.csproj'), this.applicationname + '/' + this.applicationname + '.csproj', this.templatedata)
6463
this.fs.copyTpl(this.templatePath('AuthenticationDefaults.cs'), this.applicationname + '/' + this.name + 'AuthenticationDefaults.cs', this.templatedata)
6564
this.fs.copyTpl(this.templatePath('AuthenticationExtensions.cs'), this.applicationname + '/' + this.name + 'AuthenticationExtensions.cs', this.templatedata)
6665
this.fs.copyTpl(this.templatePath('AuthenticationHandler.cs'), this.applicationname + '/' + this.name + 'AuthenticationHandler.cs', this.templatedata)
67-
this.fs.copyTpl(this.templatePath('AuthenticationHelper.cs'), this.applicationname + '/' + this.name + 'AuthenticationHelper.cs', this.templatedata)
68-
this.fs.copyTpl(this.templatePath('AuthenticationMiddleware.cs'), this.applicationname + '/' + this.name + 'AuthenticationMiddleware.cs', this.templatedata)
6966
this.fs.copyTpl(this.templatePath('AuthenticationOptions.cs'), this.applicationname + '/' + this.name + 'AuthenticationOptions.cs', this.templatedata)
7067
},
7168

generators/app/templates/AuthenticationDefaults.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,28 @@
44
* for more information concerning the license and the contributors participating to this project.
55
*/
66

7-
using Microsoft.AspNetCore.Builder;
7+
using Microsoft.AspNetCore.Authentication;
8+
using Microsoft.AspNetCore.Authentication.OAuth;
89

9-
namespace AspNet.Security.OAuth.<%= name %> {
10+
namespace AspNet.Security.OAuth.<%= name %>
11+
{
1012
/// <summary>
11-
/// Default values used by the <%= name %> authentication middleware.
13+
/// Default values used by the <%= name %> authentication provider.
1214
/// </summary>
13-
public static class <%= name %>AuthenticationDefaults {
15+
public static class <%= name %>AuthenticationDefaults
16+
{
1417
/// <summary>
15-
/// Default value for <see cref="AuthenticationOptions.AuthenticationScheme"/>.
18+
/// Default value for <see cref="AuthenticationScheme.Name"/>.
1619
/// </summary>
1720
public const string AuthenticationScheme = "<%= name %>";
1821

1922
/// <summary>
20-
/// Default value for <see cref="RemoteAuthenticationOptions.DisplayName"/>.
23+
/// Default value for <see cref="AuthenticationScheme.DisplayName"/>.
2124
/// </summary>
2225
public const string DisplayName = "<%= name %>";
2326

2427
/// <summary>
25-
/// Default value for <see cref="AuthenticationOptions.ClaimsIssuer"/>.
28+
/// Default value for <see cref="AuthenticationSchemeOptions.ClaimsIssuer"/>.
2629
/// </summary>
2730
public const string Issuer = "<%= name %>";
2831

generators/app/templates/AuthenticationExtensions.cs

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,70 @@
77
using System;
88
using AspNet.Security.OAuth.<%= name %>;
99
using JetBrains.Annotations;
10-
using Microsoft.Extensions.Options;
10+
using Microsoft.AspNetCore.Authentication;
1111

12-
namespace Microsoft.AspNetCore.Builder {
12+
namespace Microsoft.Extensions.DependencyInjection
13+
{
1314
/// <summary>
1415
/// Extension methods to add <%= name %> authentication capabilities to an HTTP application pipeline.
1516
/// </summary>
16-
public static class <%= name %>AuthenticationExtensions {
17+
public static class <%= name %>AuthenticationExtensions
18+
{
1719
/// <summary>
18-
/// Adds the <see cref="<%= name %>AuthenticationMiddleware"/> middleware to the specified
19-
/// <see cref="IApplicationBuilder"/>, which enables <%= name %> authentication capabilities.
20+
/// Adds <see cref="<%= name %>AuthenticationHandler"/> to the specified
21+
/// <see cref="AuthenticationBuilder"/>, which enables <%= name %> authentication capabilities.
2022
/// </summary>
21-
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
22-
/// <param name="options">A <see cref="<%= name %>AuthenticationOptions"/> that specifies options for the middleware.</param>
23-
/// <returns>A reference to this instance after the operation has completed.</returns>
24-
public static IApplicationBuilder Use<%= name %>Authentication(
25-
[NotNull] this IApplicationBuilder app,
26-
[NotNull] <%= name %>AuthenticationOptions options) {
27-
if (app == null) {
28-
throw new ArgumentNullException(nameof(app));
29-
}
30-
31-
if (options == null) {
32-
throw new ArgumentNullException(nameof(options));
33-
}
34-
35-
return app.UseMiddleware<<%= name %>AuthenticationMiddleware>(Options.Create(options));
23+
/// <param name="builder">The authentication builder.</param>
24+
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
25+
public static AuthenticationBuilder Add<%= name %>([NotNull] this AuthenticationBuilder builder)
26+
{
27+
return builder.Add<%= name %>(<%= name %>AuthenticationDefaults.AuthenticationScheme, options => { });
3628
}
3729

3830
/// <summary>
39-
/// Adds the <see cref="<%= name %>AuthenticationMiddleware"/> middleware to the specified
40-
/// <see cref="IApplicationBuilder"/>, which enables <%= name %> authentication capabilities.
31+
/// Adds <see cref="<%= name %>AuthenticationHandler"/> to the specified
32+
/// <see cref="AuthenticationBuilder"/>, which enables <%= name %> authentication capabilities.
4133
/// </summary>
42-
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
43-
/// <param name="configuration">An action delegate to configure the provided <see cref="<%= name %>AuthenticationOptions"/>.</param>
44-
/// <returns>A reference to this instance after the operation has completed.</returns>
45-
public static IApplicationBuilder Use<%= name %>Authentication(
46-
[NotNull] this IApplicationBuilder app,
47-
[NotNull] Action<<%= name %>AuthenticationOptions> configuration) {
48-
if (app == null) {
49-
throw new ArgumentNullException(nameof(app));
50-
}
51-
52-
if (configuration == null) {
53-
throw new ArgumentNullException(nameof(configuration));
54-
}
34+
/// <param name="builder">The authentication builder.</param>
35+
/// <param name="configuration">The delegate used to configure the <%= name %> options.</param>
36+
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
37+
public static AuthenticationBuilder Add<%= name %>(
38+
[NotNull] this AuthenticationBuilder builder,
39+
[NotNull] Action<<%= name %>AuthenticationOptions> configuration)
40+
{
41+
return builder.Add<%= name %>(<%= name %>AuthenticationDefaults.AuthenticationScheme, configuration);
42+
}
5543

56-
var options = new <%= name %>AuthenticationOptions();
57-
configuration(options);
44+
/// <summary>
45+
/// Adds <see cref="<%= name %>AuthenticationHandler"/> to the specified
46+
/// <see cref="AuthenticationBuilder"/>, which enables <%= name %> authentication capabilities.
47+
/// </summary>
48+
/// <param name="builder">The authentication builder.</param>
49+
/// <param name="scheme">The authentication scheme associated with this instance.</param>
50+
/// <param name="configuration">The delegate used to configure the <%= name %> options.</param>
51+
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
52+
public static AuthenticationBuilder Add<%= name %>(
53+
[NotNull] this AuthenticationBuilder builder, [NotNull] string scheme,
54+
[NotNull] Action<<%= name %>AuthenticationOptions> configuration)
55+
{
56+
return builder.Add<%= name %>(scheme, <%= name %>AuthenticationDefaults.DisplayName, configuration);
57+
}
5858

59-
return app.UseMiddleware<<%= name %>AuthenticationMiddleware>(Options.Create(options));
59+
/// <summary>
60+
/// Adds <see cref="<%= name %>AuthenticationHandler"/> to the specified
61+
/// <see cref="AuthenticationBuilder"/>, which enables <%= name %> authentication capabilities.
62+
/// </summary>
63+
/// <param name="builder">The authentication builder.</param>
64+
/// <param name="scheme">The authentication scheme associated with this instance.</param>
65+
/// <param name="caption">The optional display name associated with this instance.</param>
66+
/// <param name="configuration">The delegate used to configure the <%= name %> options.</param>
67+
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
68+
public static AuthenticationBuilder Add<%= name %>(
69+
[NotNull] this AuthenticationBuilder builder,
70+
[NotNull] string scheme, [CanBeNull] string caption,
71+
[NotNull] Action<<%= name %>AuthenticationOptions> configuration)
72+
{
73+
return builder.AddOAuth<<%= name %>AuthenticationOptions, <%= name %>AuthenticationHandler>(scheme, caption, configuration);
6074
}
6175
}
6276
}

generators/app/templates/AuthenticationHandler.cs

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,76 @@
77
using System.Net.Http;
88
using System.Net.Http.Headers;
99
using System.Security.Claims;
10+
using System.Text.Encodings.Web;
1011
using System.Threading.Tasks;
11-
using AspNet.Security.OAuth.Extensions;
1212
using JetBrains.Annotations;
1313
using Microsoft.AspNetCore.Authentication;
1414
using Microsoft.AspNetCore.Authentication.OAuth;
15-
using Microsoft.AspNetCore.Http.Authentication;
15+
using Microsoft.AspNetCore.WebUtilities;
1616
using Microsoft.Extensions.Logging;
17+
using Microsoft.Extensions.Options;
1718
using Newtonsoft.Json.Linq;
1819

19-
namespace AspNet.Security.OAuth.<%= name %> {
20-
public class <%= name %>AuthenticationHandler : OAuthHandler<<%= name %>AuthenticationOptions> {
21-
public <%= name %>AuthenticationHandler([NotNull] HttpClient client)
22-
: base(client) {
20+
namespace AspNet.Security.OAuth.<%= name %>
21+
{
22+
/// <summary>
23+
/// Defines a handler for authentication using <%= name %>.
24+
/// </summary>
25+
public class <%= name %>AuthenticationHandler : OAuthHandler<<%= name %>AuthenticationOptions>
26+
{
27+
/// <summary>
28+
/// Initializes a new instance of the <see cref="<%= name %>AuthenticationHandler"/> class.
29+
/// </summary>
30+
/// <param name="options">The authentication options.</param>
31+
/// <param name="logger">The logger to use.</param>
32+
/// <param name="encoder">The URL encoder to use.</param>
33+
/// <param name="clock">The system clock to use.</param>
34+
public <%= name %>AuthenticationHandler(
35+
[NotNull] IOptionsMonitor<<%= name %>AuthenticationOptions> options,
36+
[NotNull] ILoggerFactory logger,
37+
[NotNull] UrlEncoder encoder,
38+
[NotNull] ISystemClock clock)
39+
: base(options, logger, encoder, clock)
40+
{
2341
}
2442

25-
protected override async Task<AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity,
26-
[NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) {
27-
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
43+
/// <inheritdoc />
44+
protected override async Task<AuthenticationTicket> CreateTicketAsync(
45+
[NotNull] ClaimsIdentity identity,
46+
[NotNull] AuthenticationProperties properties,
47+
[NotNull] OAuthTokenResponse tokens)
48+
{
49+
var endpoint = Options.UserInformationEndpoint;
50+
51+
// TODO Append any additional query string parameters required
52+
//endpoint = QueryHelpers.AddQueryString(endpoint, "token", tokens.AccessToken);
53+
54+
var request = new HttpRequestMessage(HttpMethod.Get, endpoint);
2855
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
29-
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
3056

31-
var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
32-
response.EnsureSuccessStatusCode();
57+
// TODO Add any HTTP request headers required
58+
//request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
3359

34-
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
60+
var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
61+
if (!response.IsSuccessStatusCode)
62+
{
63+
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
64+
"returned a {Status} response with the following payload: {Headers} {Body}.",
65+
/* Status: */ response.StatusCode,
66+
/* Headers: */ response.Headers.ToString(),
67+
/* Body: */ await response.Content.ReadAsStringAsync());
3568

36-
identity.AddOptionalClaim(ClaimTypes.NameIdentifier, <%= name %>AuthenticationHelper.GetIdentifier(payload), Options.ClaimsIssuer);
69+
throw new HttpRequestException("An error occurred while retrieving the user profile from <%= name %>.");
70+
}
3771

38-
// TODO: Add any optional claims, eg
39-
// .AddOptionalClaim("urn:<%= name.toLowerCase() %>:name", <%= name %>AuthenticationHelper.GetName(payload), Options.ClaimsIssuer)
72+
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
4073

4174
var principal = new ClaimsPrincipal(identity);
42-
var ticket = new AuthenticationTicket(principal, properties, Options.AuthenticationScheme);
75+
var context = new OAuthCreatingTicketContext(principal, properties, Context, Scheme, Options, Backchannel, tokens, payload);
76+
context.RunClaimActions(payload);
4377

44-
var context = new OAuthCreatingTicketContext(ticket, Context, Options, Backchannel, tokens, payload);
4578
await Options.Events.CreatingTicket(context);
46-
47-
return context.Ticket;
79+
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
4880
}
4981
}
5082
}

generators/app/templates/AuthenticationHelper.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.

generators/app/templates/AuthenticationMiddleware.cs

Lines changed: 0 additions & 32 deletions
This file was deleted.

generators/app/templates/AuthenticationOptions.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,34 @@
44
* for more information concerning the license and the contributors participating to this project.
55
*/
66

7-
using Microsoft.AspNetCore.Builder;
8-
using Microsoft.AspNetCore.Http;
7+
using System.Security.Claims;
8+
using Microsoft.AspNetCore.Authentication;
9+
using Microsoft.AspNetCore.Authentication.OAuth;
910

10-
namespace AspNet.Security.OAuth.<%= name %> {
11+
namespace AspNet.Security.OAuth.<%= name %>
12+
{
1113
/// <summary>
1214
/// Defines a set of options used by <see cref="<%= name %>AuthenticationHandler"/>.
1315
/// </summary>
14-
public class <%= name %>AuthenticationOptions : OAuthOptions {
15-
public <%= name %>AuthenticationOptions() {
16-
AuthenticationScheme = <%= name %>AuthenticationDefaults.AuthenticationScheme;
17-
DisplayName = <%= name %>AuthenticationDefaults.DisplayName;
16+
public class <%= name %>AuthenticationOptions : OAuthOptions
17+
{
18+
/// <summary>
19+
/// Initializes a new instance of the <see cref="<%= name %>AuthenticationOptions"/> class.
20+
/// </summary>
21+
public <%= name %>AuthenticationOptions()
22+
{
1823
ClaimsIssuer = <%= name %>AuthenticationDefaults.Issuer;
19-
20-
CallbackPath = new PathString(<%= name %>AuthenticationDefaults.CallbackPath);
24+
CallbackPath = <%= name %>AuthenticationDefaults.CallbackPath;
2125

2226
AuthorizationEndpoint = <%= name %>AuthenticationDefaults.AuthorizationEndpoint;
2327
TokenEndpoint = <%= name %>AuthenticationDefaults.TokenEndpoint;
2428
UserInformationEndpoint = <%= name %>AuthenticationDefaults.UserInformationEndpoint;
29+
30+
// TODO Add any required scopes
31+
// Scope.Add("?");
32+
33+
// TODO Map any claims
34+
// ClaimActions.MapJsonKey(ClaimTypes.Email, "?");
2535
}
2636
}
2737
}

0 commit comments

Comments
 (0)