diff --git a/samples/Mvc.Server/Startup.cs b/samples/Mvc.Server/Startup.cs
index 11d8d895..0daa3a5f 100644
--- a/samples/Mvc.Server/Startup.cs
+++ b/samples/Mvc.Server/Startup.cs
@@ -76,9 +76,7 @@ namespace Mvc.Server {
// Note: OpenIddict must be added after
// ASP.NET Identity and the external providers.
- app.UseOpenIddict(options => {
- options.AllowInsecureHttp = true;
- });
+ app.UseOpenIddict();
app.UseMvcWithDefaultRoute();
diff --git a/src/OpenIddict.Core/OpenIddictBuilder.cs b/src/OpenIddict.Core/OpenIddictBuilder.cs
index 0db22be7..9213149a 100644
--- a/src/OpenIddict.Core/OpenIddictBuilder.cs
+++ b/src/OpenIddict.Core/OpenIddictBuilder.cs
@@ -1,36 +1,21 @@
-/*
- * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
- * See https://github.com/openiddict/core for more information concerning
- * the license and the contributors participating to this project.
- */
+using OpenIddict;
-using System;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace OpenIddict {
- public class OpenIddictBuilder {
- internal OpenIddictBuilder(IServiceCollection services) {
- Services = services;
+namespace Microsoft.AspNet.Builder {
+ ///
+ /// Holds various properties allowing to configure OpenIddct.
+ ///
+ public class OpenIddictBuilder : OpenIdConnectServerBuilder {
+ public OpenIddictBuilder(IApplicationBuilder builder)
+ : base(builder) {
+ Options = new OpenIddictOptions();
}
///
- /// Gets or sets the type corresponding to the Application entity.
- ///
- public Type ApplicationType { get; set; }
-
- ///
- /// Gets or sets the type corresponding to the Role entity.
+ /// Gets or sets the options used by OpenIddict.
///
- public Type RoleType { get; set; }
-
- ///
- /// Gets or sets the type corresponding to the User entity.
- ///
- public Type UserType { get; set; }
-
- ///
- /// Gets the services used by OpenIddict.
- ///
- public IServiceCollection Services { get; }
+ public new OpenIddictOptions Options {
+ get { return base.Options as OpenIddictOptions; }
+ set { base.Options = value; }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/OpenIddict.Core/OpenIddictController.cs b/src/OpenIddict.Core/OpenIddictController.cs
index a5131a30..7c4ad440 100644
--- a/src/OpenIddict.Core/OpenIddictController.cs
+++ b/src/OpenIddict.Core/OpenIddictController.cs
@@ -10,8 +10,8 @@ using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using AspNet.Security.OpenIdConnect.Extensions;
-using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNet.Authorization;
+using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Mvc;
using Microsoft.Extensions.Internal;
@@ -20,8 +20,11 @@ using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace OpenIddict {
// Note: this controller is generic and doesn't need to be marked as internal to prevent MVC from discovering it.
public class OpenIddictController : Controller where TUser : class where TApplication : class {
- public OpenIddictController([NotNull] OpenIddictManager manager) {
+ public OpenIddictController(
+ [NotNull] OpenIddictManager manager,
+ [NotNull] OpenIddictOptions options) {
Manager = manager;
+ Options = options;
}
///
@@ -32,7 +35,7 @@ namespace OpenIddict {
///
/// Gets the OpenIddict options used by the server.
///
- protected virtual OpenIddictOptions Options => (OpenIddictOptions) HttpContext.Items[typeof(OpenIddictOptions)];
+ protected virtual OpenIddictOptions Options { get; }
[HttpGet, HttpPost]
public async Task Authorize() {
diff --git a/src/OpenIddict.Core/OpenIddictExtensions.cs b/src/OpenIddict.Core/OpenIddictExtensions.cs
index 3f825a7b..927b4161 100644
--- a/src/OpenIddict.Core/OpenIddictExtensions.cs
+++ b/src/OpenIddict.Core/OpenIddictExtensions.cs
@@ -9,6 +9,7 @@ using System.Diagnostics;
using System.Reflection;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNet.FileProviders;
+using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.StaticFiles;
@@ -22,8 +23,8 @@ using NWebsec.Owin;
namespace Microsoft.AspNet.Builder {
public static class OpenIddictExtensions {
- public static OpenIddictBuilder AddOpenIddictCore(
- [NotNull] this IdentityBuilder builder) where TApplication : class {
+ public static OpenIddictServices AddOpenIddictCore([NotNull] this IdentityBuilder builder)
+ where TApplication : class {
builder.Services.AddAuthentication();
builder.Services.AddCaching();
@@ -36,7 +37,7 @@ namespace Microsoft.AspNet.Builder {
typeof(OpenIddictManager<,>).MakeGenericType(
builder.UserType, typeof(TApplication)));
- var services = new OpenIddictBuilder(builder.Services) {
+ var services = new OpenIddictServices(builder.Services) {
ApplicationType = typeof(TApplication),
RoleType = builder.RoleType,
UserType = builder.UserType
@@ -47,19 +48,22 @@ namespace Microsoft.AspNet.Builder {
return services;
}
+ public static IApplicationBuilder UseOpenIddict([NotNull] this IApplicationBuilder app) {
+ return app.UseOpenIddict(options => { });
+ }
+
public static IApplicationBuilder UseOpenIddict(
[NotNull] this IApplicationBuilder app,
- [NotNull] Action configuration) {
- var instance = new OpenIddictOptions();
+ [NotNull] Action configuration) {
+ var builder = new OpenIddictBuilder(app);
- // Turn ApplicationCanDisplayErrors on to ensure ASP.NET MVC 6
- // handles errored requests and returns an appropriate error page.
- instance.ApplicationCanDisplayErrors = true;
+ // By default, enable AllowInsecureHttp in development/testing environments.
+ var environment = app.ApplicationServices.GetRequiredService();
+ builder.Options.AllowInsecureHttp = environment.IsDevelopment() || environment.IsEnvironment("Testing");
- // Call the configuration delegate defined by the user.
- configuration(instance);
+ configuration(builder);
- if (!instance.UseCustomViews) {
+ if (!builder.Options.UseCustomViews) {
app.UseStaticFiles(new StaticFileOptions {
FileProvider = new EmbeddedFileProvider(
assembly: Assembly.Load(new AssemblyName("OpenIddict.Assets")),
@@ -76,24 +80,8 @@ namespace Microsoft.AspNet.Builder {
// Add OpenIdConnectServerMiddleware to the ASP.NET 5 pipeline.
app.UseOpenIdConnectServer(options => {
- // Resolve the OpenIddict provider from the global services container.
+ options.Options = builder.Options;
options.Provider = app.ApplicationServices.GetRequiredService();
-
- // Copy the OpenIddict options to the ASOS configuration.
- options.Options.AuthenticationScheme = instance.AuthenticationScheme;
-
- options.Options.Issuer = instance.Issuer;
-
- options.Options.AuthorizationEndpointPath = instance.AuthorizationEndpointPath;
- options.Options.LogoutEndpointPath = instance.LogoutEndpointPath;
-
- options.Options.AccessTokenLifetime = instance.AccessTokenLifetime;
- options.Options.AuthorizationCodeLifetime = instance.AuthorizationCodeLifetime;
- options.Options.IdentityTokenLifetime = instance.IdentityTokenLifetime;
- options.Options.RefreshTokenLifetime = instance.RefreshTokenLifetime;
-
- options.Options.ApplicationCanDisplayErrors = instance.ApplicationCanDisplayErrors;
- options.Options.AllowInsecureHttp = instance.AllowInsecureHttp;
});
#if DNX451
@@ -120,57 +108,45 @@ namespace Microsoft.AspNet.Builder {
#endif
// Run the rest of the pipeline in an isolated environment.
- return app.Isolate(builder => {
- // Add the options to the ASP.NET context
- // before executing the rest of the pipeline.
- builder.Use(next => context => {
- context.Items[typeof(OpenIddictOptions)] = instance;
+ return app.Isolate(container => container.UseMvc(routes => {
+ // Register the actions corresponding to the authorization endpoint.
+ if (builder.Options.AuthorizationEndpointPath.HasValue) {
+ routes.MapRoute("{D97891B4}", builder.Options.AuthorizationEndpointPath.Value.Substring(1), new {
+ controller = typeof(OpenIddictController<,>).Name,
+ action = nameof(OpenIddictController.Authorize)
+ });
- return next(context);
- });
+ routes.MapRoute("{7148DB83}", builder.Options.AuthorizationEndpointPath.Value.Substring(1) + "/accept", new {
+ controller = typeof(OpenIddictController<,>).Name,
+ action = nameof(OpenIddictController.Accept)
+ });
- // Register ASP.NET MVC 6 and the actions
- // associated to the OpenIddict controller.
- builder.UseMvc(routes => {
- // Register the actions corresponding to the authorization endpoint.
- if (instance.AuthorizationEndpointPath.HasValue) {
- routes.MapRoute("{D97891B4}", instance.AuthorizationEndpointPath.Value.Substring(1), new {
- controller = typeof(OpenIddictController<,>).Name,
- action = nameof(OpenIddictController.Authorize)
- });
-
- routes.MapRoute("{7148DB83}", instance.AuthorizationEndpointPath.Value.Substring(1) + "/accept", new {
- controller = typeof(OpenIddictController<,>).Name,
- action = nameof(OpenIddictController.Accept)
- });
-
- routes.MapRoute("{23438BCC}", instance.AuthorizationEndpointPath.Value.Substring(1) + "/deny", new {
- controller = typeof(OpenIddictController<,>).Name,
- action = nameof(OpenIddictController.Deny)
- });
- }
-
- // Register the action corresponding to the logout endpoint.
- if (instance.LogoutEndpointPath.HasValue) {
- routes.MapRoute("{C7DB102A}", instance.LogoutEndpointPath.Value.Substring(1), new {
- controller = typeof(OpenIddictController<,>).Name,
- action = nameof(OpenIddictController.Logout)
- });
- }
- });
- }, services => {
- var builder = app.ApplicationServices.GetRequiredService();
+ routes.MapRoute("{23438BCC}", builder.Options.AuthorizationEndpointPath.Value.Substring(1) + "/deny", new {
+ controller = typeof(OpenIddictController<,>).Name,
+ action = nameof(OpenIddictController.Deny)
+ });
+ }
+
+ // Register the action corresponding to the logout endpoint.
+ if (builder.Options.LogoutEndpointPath.HasValue) {
+ routes.MapRoute("{C7DB102A}", builder.Options.LogoutEndpointPath.Value.Substring(1), new {
+ controller = typeof(OpenIddictController<,>).Name,
+ action = nameof(OpenIddictController.Logout)
+ });
+ }
+ }), services => {
+ var instance = app.ApplicationServices.GetRequiredService();
services.AddMvc()
// Register the OpenIddict controller.
.AddControllersAsServices(new[] {
- typeof(OpenIddictController<,>).MakeGenericType(builder.UserType, builder.ApplicationType)
+ typeof(OpenIddictController<,>).MakeGenericType(instance.UserType, instance.ApplicationType)
})
// Update the Razor options to use an embedded provider
// extracting its views from the current assembly.
.AddRazorOptions(options => {
- if (!instance.UseCustomViews) {
+ if (!builder.Options.UseCustomViews) {
options.FileProvider = new EmbeddedFileProvider(
assembly: typeof(OpenIddictOptions).GetTypeInfo().Assembly,
baseNamespace: "OpenIddict.Core");
@@ -178,24 +154,26 @@ namespace Microsoft.AspNet.Builder {
});
// Register the sign-in manager in the isolated container.
- services.AddScoped(typeof(SignInManager<>).MakeGenericType(builder.UserType), provider => {
+ services.AddScoped(typeof(SignInManager<>).MakeGenericType(instance.UserType), provider => {
var accessor = provider.GetRequiredService();
var container = (IServiceProvider) accessor.HttpContext.Items[typeof(IServiceProvider)];
Debug.Assert(container != null);
// Resolve the sign-in manager from the parent container.
- return container.GetRequiredService(typeof(SignInManager<>).MakeGenericType(builder.UserType));
+ return container.GetRequiredService(typeof(SignInManager<>).MakeGenericType(instance.UserType));
});
// Register the user manager in the isolated container.
- services.AddScoped(typeof(OpenIddictManager<,>).MakeGenericType(builder.UserType, builder.ApplicationType), provider => {
+ services.AddScoped(typeof(OpenIddictManager<,>).MakeGenericType(instance.UserType, instance.ApplicationType), provider => {
var accessor = provider.GetRequiredService();
var container = (IServiceProvider) accessor.HttpContext.Items[typeof(IServiceProvider)];
Debug.Assert(container != null);
// Resolve the user manager from the parent container.
- return container.GetRequiredService(typeof(OpenIddictManager<,>).MakeGenericType(builder.UserType, builder.ApplicationType));
+ return container.GetRequiredService(typeof(OpenIddictManager<,>).MakeGenericType(instance.UserType, instance.ApplicationType));
});
+
+ services.AddScoped(provider => builder.Options);
});
}
}
diff --git a/src/OpenIddict.Core/OpenIddictOptions.cs b/src/OpenIddict.Core/OpenIddictOptions.cs
index a43da165..abafec80 100644
--- a/src/OpenIddict.Core/OpenIddictOptions.cs
+++ b/src/OpenIddict.Core/OpenIddictOptions.cs
@@ -4,81 +4,14 @@
* the license and the contributors participating to this project.
*/
-using System;
using AspNet.Security.OpenIdConnect.Server;
-using Microsoft.AspNet.Http;
namespace OpenIddict {
- public class OpenIddictOptions {
- public string AuthenticationScheme { get; set; } = OpenIddictDefaults.AuthenticationScheme;
-
- ///
- /// The base address used to uniquely identify the authorization server.
- /// The URI must be absolute and may contain a path, but no query string or fragment part.
- /// Unless AllowInsecureHttp has been set to true, an HTTPS address must be provided.
- ///
- public Uri Issuer { get; set; }
-
- ///
- /// The request path where client applications will redirect the user-agent in order to
- /// obtain user consent to issue a token. Must begin with a leading slash, like "/connect/authorize".
- /// This setting can be set to to disable the authorization endpoint.
- ///
- public PathString AuthorizationEndpointPath { get; set; } = new PathString(OpenIdConnectServerDefaults.AuthorizationEndpointPath);
-
- ///
- /// The request path client applications communicate with to log out.
- /// Must begin with a leading slash, like "/connect/logout".
- /// You can set it to to disable the logout endpoint.
- ///
- public PathString LogoutEndpointPath { get; set; } = new PathString(OpenIdConnectServerDefaults.LogoutEndpointPath);
-
- ///
- /// The period of time the authorization code remains valid after being issued. The default is 5 minutes.
- /// This time span must also take into account clock synchronization between servers in a web farm, so a very
- /// brief value could result in unexpectedly expired tokens.
- ///
- public TimeSpan AuthorizationCodeLifetime { get; set; } = TimeSpan.FromMinutes(5);
-
- ///
- /// The period of time the access token remains valid after being issued. The default is 1 hour.
- /// The client application is expected to refresh or acquire a new access token after the token has expired.
- ///
- public TimeSpan AccessTokenLifetime { get; set; } = TimeSpan.FromHours(1);
-
- ///
- /// The period of time the identity token remains valid after being issued. The default is 20 minutes.
- /// The client application is expected to refresh or acquire a new identity token after the token has expired.
- ///
- public TimeSpan IdentityTokenLifetime { get; set; } = TimeSpan.FromMinutes(20);
-
- ///
- /// The period of time the refresh token remains valid after being issued. The default is 6 hours.
- /// The client application is expected to start a whole new authentication flow after the refresh token has expired.
- ///
- public TimeSpan RefreshTokenLifetime { get; set; } = TimeSpan.FromHours(6);
-
- ///
- /// Determines whether refresh tokens issued during a grant_type=refresh_token request should be generated
- /// with a new expiration date or should re-use the same expiration date as the original refresh token.
- /// Set this property to true to assign a new expiration date each time a refresh token is issued,
- /// false to use the expiration date of the original refresh token. When set to false,
- /// access and identity tokens' lifetime cannot exceed the expiration date of the refresh token.
- ///
- public bool UseSlidingExpiration { get; set; } = true;
-
- ///
- /// Set to true if the web application is able to render error messages on the authorization endpoint. This is only needed for cases where
- /// the browser is not redirected back to the client application, for example, when the client_id or redirect_uri are incorrect. The
- /// authorization endpoint should expect to see the OpenID Connect response added to the ASP.NET 5 environment.
- ///
- public bool ApplicationCanDisplayErrors { get; set; }
-
- ///
- /// True to allow incoming requests to arrive on HTTP and to allow redirect_uri parameters to have HTTP URI addresses.
- /// Setting this option to false in production is strongly encouraged to mitigate man-in-the-middle attacks.
- ///
- public bool AllowInsecureHttp { get; set; }
+ public class OpenIddictOptions : OpenIdConnectServerOptions {
+ public OpenIddictOptions() {
+ AuthenticationScheme = OpenIddictDefaults.AuthenticationScheme;
+ ApplicationCanDisplayErrors = true;
+ }
///
/// Set to true to allow you to use your own views/styles/scripts in your server.
diff --git a/src/OpenIddict.Core/OpenIddictServices.cs b/src/OpenIddict.Core/OpenIddictServices.cs
new file mode 100644
index 00000000..35bfa3e6
--- /dev/null
+++ b/src/OpenIddict.Core/OpenIddictServices.cs
@@ -0,0 +1,36 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/openiddict/core for more information concerning
+ * the license and the contributors participating to this project.
+ */
+
+using System;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace OpenIddict {
+ public class OpenIddictServices {
+ public OpenIddictServices(IServiceCollection services) {
+ Services = services;
+ }
+
+ ///
+ /// Gets or sets the type corresponding to the Application entity.
+ ///
+ public Type ApplicationType { get; set; }
+
+ ///
+ /// Gets or sets the type corresponding to the Role entity.
+ ///
+ public Type RoleType { get; set; }
+
+ ///
+ /// Gets or sets the type corresponding to the User entity.
+ ///
+ public Type UserType { get; set; }
+
+ ///
+ /// Gets the services used by OpenIddict.
+ ///
+ public IServiceCollection Services { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenIddict.EF/OpenIddictExtensions.cs b/src/OpenIddict.EF/OpenIddictExtensions.cs
index e136dd63..9a826e61 100644
--- a/src/OpenIddict.EF/OpenIddictExtensions.cs
+++ b/src/OpenIddict.EF/OpenIddictExtensions.cs
@@ -16,21 +16,21 @@ using OpenIddict;
namespace Microsoft.AspNet.Builder {
public static class OpenIddictExtensions {
- public static OpenIddictBuilder AddEntityFrameworkStore([NotNull] this OpenIddictBuilder builder) {
- builder.Services.AddScoped(
- typeof(IOpenIddictStore<,>).MakeGenericType(builder.UserType, builder.ApplicationType),
+ public static OpenIddictServices AddEntityFrameworkStore([NotNull] this OpenIddictServices services) {
+ services.Services.AddScoped(
+ typeof(IOpenIddictStore<,>).MakeGenericType(services.UserType, services.ApplicationType),
typeof(OpenIddictStore<,,,,>).MakeGenericType(
- /* TUser: */ builder.UserType,
- /* TApplication: */ builder.ApplicationType,
- /* TRole: */ builder.RoleType,
- /* TContext: */ ResolveContextType(builder),
- /* TKey: */ ResolveKeyType(builder)));
+ /* TUser: */ services.UserType,
+ /* TApplication: */ services.ApplicationType,
+ /* TRole: */ services.RoleType,
+ /* TContext: */ ResolveContextType(services),
+ /* TKey: */ ResolveKeyType(services)));
- return builder;
+ return services;
}
- private static Type ResolveContextType([NotNull] OpenIddictBuilder builder) {
- var service = (from registration in builder.Services
+ private static Type ResolveContextType([NotNull] OpenIddictServices services) {
+ var service = (from registration in services.Services
where registration.ServiceType.IsConstructedGenericType
let definition = registration.ServiceType.GetGenericTypeDefinition()
where definition == typeof(IUserStore<>)
@@ -65,9 +65,9 @@ namespace Microsoft.AspNet.Builder {
throw new InvalidOperationException("The type of the database context cannot be automatically inferred.");
}
- private static Type ResolveKeyType([NotNull] OpenIddictBuilder builder) {
+ private static Type ResolveKeyType([NotNull] OpenIddictServices services) {
TypeInfo type;
- for (type = builder.UserType.GetTypeInfo(); type != null; type = type.BaseType?.GetTypeInfo()) {
+ for (type = services.UserType.GetTypeInfo(); type != null; type = type.BaseType?.GetTypeInfo()) {
if (!type.IsGenericType) {
continue;
}
@@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Builder {
throw new InvalidOperationException(
"The type of the key identifier used by the user " +
- $"entity '{builder.UserType}' cannot be automatically inferred.");
+ $"entity '{services.UserType}' cannot be automatically inferred.");
}
}
}
\ No newline at end of file
diff --git a/src/OpenIddict/OpenIddictExtensions.cs b/src/OpenIddict/OpenIddictExtensions.cs
index 7ac05a37..2fd23d82 100644
--- a/src/OpenIddict/OpenIddictExtensions.cs
+++ b/src/OpenIddict/OpenIddictExtensions.cs
@@ -4,6 +4,7 @@
* the license and the contributors participating to this project.
*/
+using System;
using Microsoft.AspNet.Identity;
using Microsoft.Extensions.Internal;
using OpenIddict;
@@ -11,12 +12,12 @@ using OpenIddict.Models;
namespace Microsoft.AspNet.Builder {
public static class OpenIddictExtensions {
- public static OpenIddictBuilder AddOpenIddict([NotNull] this IdentityBuilder builder) {
+ public static OpenIddictServices AddOpenIddict([NotNull] this IdentityBuilder builder) {
return builder.AddOpenIddictCore()
.AddEntityFrameworkStore();
}
- public static OpenIddictBuilder AddOpenIddict([NotNull] this IdentityBuilder builder)
+ public static OpenIddictServices AddOpenIddict([NotNull] this IdentityBuilder builder)
where TApplication : Application {
return builder.AddOpenIddictCore()
.AddEntityFrameworkStore();