27 changed files with 682 additions and 327 deletions
@ -0,0 +1,14 @@ |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNet.Identity; |
|||
|
|||
namespace OpenIddict { |
|||
public interface IOpenIddictStore<TUser, TApplication> : IUserStore<TUser> where TUser : class where TApplication : class { |
|||
Task<TApplication> FindApplicationByIdAsync(string identifier, CancellationToken cancellationToken); |
|||
Task<TApplication> FindApplicationByLogoutRedirectUri(string url, CancellationToken cancellationToken); |
|||
Task<string> GetApplicationTypeAsync(TApplication application, CancellationToken cancellationToken); |
|||
Task<string> GetDisplayNameAsync(TApplication application, CancellationToken cancellationToken); |
|||
Task<string> GetRedirectUriAsync(TApplication application, CancellationToken cancellationToken); |
|||
Task<bool> ValidateSecretAsync(TApplication application, string secret, CancellationToken cancellationToken); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
|||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|||
</PropertyGroup> |
|||
|
|||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" /> |
|||
<PropertyGroup Label="Globals"> |
|||
<ProjectGuid>e60cf8ca-6313-4359-be43-afcbb927ea30</ProjectGuid> |
|||
<RootNamespace>OpenIddict.Core</RootNamespace> |
|||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath> |
|||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
</PropertyGroup> |
|||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" /> |
|||
</Project> |
|||
@ -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 OpenIddictBuilder { |
|||
internal OpenIddictBuilder(IServiceCollection services) { |
|||
Services = services; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the type corresponding to the Application entity.
|
|||
/// </summary>
|
|||
public Type ApplicationType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the type corresponding to the Role entity.
|
|||
/// </summary>
|
|||
public Type RoleType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the type corresponding to the User entity.
|
|||
/// </summary>
|
|||
public Type UserType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the services used by OpenIddict.
|
|||
/// </summary>
|
|||
public IServiceCollection Services { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace OpenIddict { |
|||
public static class OpenIddictConstants { |
|||
public static class ApplicationTypes { |
|||
public const string Confidential = "confidential"; |
|||
public const string Public = "public"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,201 @@ |
|||
/* |
|||
* 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 System.Diagnostics; |
|||
using System.Reflection; |
|||
using AspNet.Security.OpenIdConnect.Server; |
|||
using Microsoft.AspNet.FileProviders; |
|||
using Microsoft.AspNet.Http; |
|||
using Microsoft.AspNet.Identity; |
|||
using Microsoft.AspNet.StaticFiles; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Internal; |
|||
using OpenIddict; |
|||
|
|||
#if DNX451
|
|||
using NWebsec.Owin; |
|||
#endif
|
|||
|
|||
namespace Microsoft.AspNet.Builder { |
|||
public static class OpenIddictExtensions { |
|||
public static OpenIddictBuilder AddOpenIddictCore<TApplication>( |
|||
[NotNull] this IdentityBuilder builder) where TApplication : class { |
|||
builder.Services.AddSingleton( |
|||
typeof(OpenIdConnectServerProvider), |
|||
typeof(OpenIddictProvider<,>).MakeGenericType( |
|||
builder.UserType, typeof(TApplication))); |
|||
|
|||
builder.Services.AddScoped( |
|||
typeof(OpenIddictManager<,>).MakeGenericType( |
|||
builder.UserType, typeof(TApplication))); |
|||
|
|||
var services = new OpenIddictBuilder(builder.Services) { |
|||
ApplicationType = typeof(TApplication), |
|||
RoleType = builder.RoleType, |
|||
UserType = builder.UserType |
|||
}; |
|||
|
|||
builder.Services.AddInstance(services); |
|||
|
|||
return services; |
|||
} |
|||
|
|||
public static IApplicationBuilder UseOpenIddict( |
|||
[NotNull] this IApplicationBuilder app, |
|||
[NotNull] Action<OpenIddictOptions> configuration) { |
|||
var instance = new OpenIddictOptions(); |
|||
|
|||
// Turn ApplicationCanDisplayErrors on to ensure ASP.NET MVC 6
|
|||
// handles errored requests and returns an appropriate error page.
|
|||
instance.ApplicationCanDisplayErrors = true; |
|||
|
|||
// Call the configuration delegate defined by the user.
|
|||
configuration(instance); |
|||
|
|||
var types = app.ApplicationServices.GetRequiredService<OpenIddictBuilder>(); |
|||
|
|||
// Run OpenIddict 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 next(context); |
|||
}); |
|||
|
|||
#if DNX451
|
|||
builder.UseKatana(owin => { |
|||
// Insert a new middleware responsible of setting the Content-Security-Policy header.
|
|||
// See https://nwebsec.codeplex.com/wikipage?title=Configuring%20Content%20Security%20Policy&referringTitle=NWebsec
|
|||
owin.UseCsp(options => options.DefaultSources(directive => directive.Self()) |
|||
.ImageSources(directive => directive.Self().CustomSources("*")) |
|||
.ScriptSources(directive => directive.UnsafeInline()) |
|||
.StyleSources(directive => directive.Self().UnsafeInline())); |
|||
|
|||
// Insert a new middleware responsible of setting the X-Content-Type-Options header.
|
|||
// See https://nwebsec.codeplex.com/wikipage?title=Configuring%20security%20headers&referringTitle=NWebsec
|
|||
owin.UseXContentTypeOptions(); |
|||
|
|||
// Insert a new middleware responsible of setting the X-Frame-Options header.
|
|||
// See https://nwebsec.codeplex.com/wikipage?title=Configuring%20security%20headers&referringTitle=NWebsec
|
|||
owin.UseXfo(options => options.Deny()); |
|||
|
|||
// Insert a new middleware responsible of setting the X-Xss-Protection header.
|
|||
// See https://nwebsec.codeplex.com/wikipage?title=Configuring%20security%20headers&referringTitle=NWebsec
|
|||
owin.UseXXssProtection(options => options.EnabledWithBlockMode()); |
|||
}); |
|||
#endif
|
|||
if (!instance.UseCustomViews) { |
|||
builder.UseStaticFiles(new StaticFileOptions { |
|||
FileProvider = new EmbeddedFileProvider( |
|||
assembly: Assembly.Load(new AssemblyName("OpenIddict.Assets")), |
|||
baseNamespace: "OpenIddict.Assets") |
|||
}); |
|||
} |
|||
|
|||
builder.UseCors(options => { |
|||
options.AllowAnyHeader(); |
|||
options.AllowAnyMethod(); |
|||
options.AllowAnyOrigin(); |
|||
options.AllowCredentials(); |
|||
}); |
|||
|
|||
// Add OpenIdConnectServerMiddleware to the ASP.NET 5 pipeline.
|
|||
builder.UseOpenIdConnectServer(options => { |
|||
// Resolve the OpenIddict provider from the global services container.
|
|||
options.Provider = app.ApplicationServices.GetRequiredService<OpenIdConnectServerProvider>(); |
|||
|
|||
// 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; |
|||
}); |
|||
|
|||
// 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<dynamic, dynamic>.Authorize) |
|||
}); |
|||
|
|||
routes.MapRoute("{7148DB83}", instance.AuthorizationEndpointPath.Value.Substring(1) + "/accept", new { |
|||
controller = typeof(OpenIddictController<,>).Name, |
|||
action = nameof(OpenIddictController<dynamic, dynamic>.Accept) |
|||
}); |
|||
|
|||
routes.MapRoute("{23438BCC}", instance.AuthorizationEndpointPath.Value.Substring(1) + "/deny", new { |
|||
controller = typeof(OpenIddictController<,>).Name, |
|||
action = nameof(OpenIddictController<dynamic, dynamic>.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<dynamic, dynamic>.Logout) |
|||
}); |
|||
} |
|||
}); |
|||
}, services => { |
|||
services.AddAuthentication(); |
|||
services.AddCaching(); |
|||
|
|||
services.AddMvc() |
|||
// Register the OpenIddict controller.
|
|||
.AddControllersAsServices(new[] { |
|||
typeof(OpenIddictController<,>).MakeGenericType(types.UserType, types.ApplicationType) |
|||
}) |
|||
|
|||
// Update the Razor options to use an embedded provider
|
|||
// extracting its views from the current assembly.
|
|||
.AddRazorOptions(options => { |
|||
if (!instance.UseCustomViews) { |
|||
options.FileProvider = new EmbeddedFileProvider( |
|||
assembly: typeof(OpenIddictOptions).GetTypeInfo().Assembly, |
|||
baseNamespace: "OpenIddict.Core"); |
|||
} |
|||
}); |
|||
|
|||
// Register the sign-in manager in the isolated container.
|
|||
services.AddScoped(typeof(SignInManager<>).MakeGenericType(types.UserType), provider => { |
|||
var accessor = provider.GetRequiredService<IHttpContextAccessor>(); |
|||
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(types.UserType)); |
|||
}); |
|||
|
|||
// Register the user manager in the isolated container.
|
|||
services.AddScoped(typeof(OpenIddictManager<,>).MakeGenericType(types.UserType, types.ApplicationType), provider => { |
|||
var accessor = provider.GetRequiredService<IHttpContextAccessor>(); |
|||
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(types.UserType, types.ApplicationType)); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNet.Http; |
|||
using Microsoft.AspNet.Identity; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Internal; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.OptionsModel; |
|||
|
|||
namespace OpenIddict { |
|||
public class OpenIddictManager<TUser, TApplication> : UserManager<TUser> where TUser : class where TApplication : class { |
|||
public OpenIddictManager([NotNull] IServiceProvider services) |
|||
: base(services: services, |
|||
store: services.GetService<IOpenIddictStore<TUser, TApplication>>(), |
|||
optionsAccessor: services.GetService<IOptions<IdentityOptions>>(), |
|||
passwordHasher: services.GetService<IPasswordHasher<TUser>>(), |
|||
userValidators: services.GetServices<IUserValidator<TUser>>(), |
|||
passwordValidators: services.GetServices<IPasswordValidator<TUser>>(), |
|||
keyNormalizer: services.GetService<ILookupNormalizer>(), |
|||
errors: services.GetService<IdentityErrorDescriber>(), |
|||
logger: services.GetService<ILogger<UserManager<TUser>>>(), |
|||
contextAccessor: services.GetService<IHttpContextAccessor>()) { |
|||
Context = services.GetRequiredService<IHttpContextAccessor>().HttpContext; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the HTTP context associated with the current manager.
|
|||
/// </summary>
|
|||
public virtual HttpContext Context { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the store associated with the current manager.
|
|||
/// </summary>
|
|||
public virtual new IOpenIddictStore<TUser, TApplication> Store { |
|||
get { return base.Store as IOpenIddictStore<TUser, TApplication>; } |
|||
} |
|||
|
|||
public virtual Task<TApplication> FindApplicationByIdAsync(string identifier) { |
|||
return Store.FindApplicationByIdAsync(identifier, Context.RequestAborted); |
|||
} |
|||
|
|||
public virtual Task<TApplication> FindApplicationByLogoutRedirectUri(string url) { |
|||
return Store.FindApplicationByLogoutRedirectUri(url, Context.RequestAborted); |
|||
} |
|||
|
|||
public virtual Task<string> GetApplicationTypeAsync(TApplication application) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Store.GetApplicationTypeAsync(application, Context.RequestAborted); |
|||
} |
|||
|
|||
public virtual Task<string> GetDisplayNameAsync(TApplication application) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Store.GetDisplayNameAsync(application, Context.RequestAborted); |
|||
} |
|||
|
|||
public virtual Task<string> GetRedirectUriAsync(TApplication application) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Store.GetRedirectUriAsync(application, Context.RequestAborted); |
|||
} |
|||
|
|||
public virtual Task<bool> ValidateSecretAsync(TApplication application, string secret) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Store.ValidateSecretAsync(application, secret, Context.RequestAborted); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyTitle("OpenIddict.Core")] |
|||
[assembly: AssemblyDescription("")] |
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("OpenIddict.Core")] |
|||
[assembly: AssemblyCopyright("Copyright © 2015")] |
|||
[assembly: AssemblyTrademark("")] |
|||
[assembly: AssemblyCulture("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("e60cf8ca-6313-4359-be43-afcbb927ea30")] |
|||
@ -1,14 +1,13 @@ |
|||
@using AspNet.Security.OpenIdConnect.Extensions |
|||
@using Microsoft.IdentityModel.Protocols.OpenIdConnect |
|||
@using OpenIddict.Models |
|||
|
|||
@model Tuple<OpenIdConnectMessage, Application> |
|||
@model Tuple<OpenIdConnectMessage, string> |
|||
|
|||
<div class="jumbotron"> |
|||
<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> |
|||
<p class="lead text-left">Do you wanna grant <strong>@Model.Item2</strong> an access to your resources? (scopes requested: @Model.Item1.Scope)</p> |
|||
<p class="lead text-left"><strong>@Model.Item2</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() |
|||
@ -0,0 +1,41 @@ |
|||
{ |
|||
"version": "1.0.0-alpha1-*", |
|||
|
|||
"resource": "Views/**", |
|||
|
|||
"dependencies": { |
|||
"Microsoft.AspNet.Cors": "6.0.0-*", |
|||
"Microsoft.AspNet.FileProviders.Embedded": "1.0.0-*", |
|||
"Microsoft.AspNet.Identity": "3.0.0-*", |
|||
"Microsoft.AspNet.Mvc": "6.0.0-*", |
|||
"Microsoft.AspNet.StaticFiles": "1.0.0-*", |
|||
|
|||
"Microsoft.Extensions.Configuration.Json": "1.0.0-*", |
|||
|
|||
"Microsoft.Extensions.NotNullAttribute.Sources": { |
|||
"type": "build", |
|||
"version": "1.0.0-*" |
|||
}, |
|||
|
|||
"AspNet.Hosting.Extensions": "1.0.0-*", |
|||
"AspNet.Security.OpenIdConnect.Server": "1.0.0-*", |
|||
|
|||
"OpenIddict.Assets": "1.0.0-*" |
|||
}, |
|||
|
|||
"frameworks": { |
|||
"dnx451": { |
|||
"dependencies": { |
|||
"AspNet.Hosting.Katana.Extensions": "1.0.0-*", |
|||
"NWebsec.Owin": "1.0.0" |
|||
} |
|||
}, |
|||
|
|||
"dnxcore50": { |
|||
"dependencies": { |
|||
"System.Linq": "4.0.1-*", |
|||
"System.Runtime.Serialization.Primitives": "4.0.11-*" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
|||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|||
</PropertyGroup> |
|||
|
|||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" /> |
|||
<PropertyGroup Label="Globals"> |
|||
<ProjectGuid>d2450929-ed0e-420d-b475-327924f9701c</ProjectGuid> |
|||
<RootNamespace>OpenIddict.EF</RootNamespace> |
|||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath> |
|||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
</PropertyGroup> |
|||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" /> |
|||
</Project> |
|||
@ -0,0 +1,74 @@ |
|||
/* |
|||
* 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 System.Linq; |
|||
using System.Reflection; |
|||
using Microsoft.AspNet.Identity; |
|||
using Microsoft.AspNet.Identity.EntityFramework; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Internal; |
|||
using OpenIddict; |
|||
|
|||
namespace Microsoft.AspNet.Builder { |
|||
public static class OpenIddictExtensions { |
|||
public static OpenIddictBuilder AddEntityFrameworkStore([NotNull] this OpenIddictBuilder builder) { |
|||
// Resolve the key type from the user type definition.
|
|||
var keyType = ResolveKeyType(builder); |
|||
|
|||
builder.Services.AddScoped( |
|||
typeof(IOpenIddictStore<,>).MakeGenericType(builder.UserType, builder.ApplicationType), |
|||
typeof(OpenIddictStore<,,,>).MakeGenericType(builder.UserType, builder.ApplicationType, builder.RoleType, keyType)); |
|||
|
|||
var type = typeof(OpenIddictContext<,,,>).MakeGenericType(new[] { |
|||
/* TUser: */ builder.UserType, |
|||
/* TApplication: */ builder.ApplicationType, |
|||
/* TRole: */ builder.RoleType, |
|||
/* TKey: */ keyType |
|||
}); |
|||
|
|||
builder.Services.AddScoped(type, provider => { |
|||
// Resolve the user store from the parent container and extract the associated context.
|
|||
dynamic store = provider.GetRequiredService(typeof(IUserStore<>).MakeGenericType(builder.UserType)); |
|||
|
|||
dynamic context = store?.Context; |
|||
if (!type.GetTypeInfo().IsAssignableFrom(context?.GetType())) { |
|||
throw new InvalidOperationException( |
|||
"Only EntityFramework contexts derived from " + |
|||
"OpenIddictContext can be used with OpenIddict."); |
|||
} |
|||
|
|||
return context; |
|||
}); |
|||
|
|||
return builder; |
|||
} |
|||
|
|||
private static Type ResolveKeyType([NotNull] OpenIddictBuilder builder) { |
|||
TypeInfo type; |
|||
for (type = builder.UserType.GetTypeInfo(); type != null; type = type.BaseType?.GetTypeInfo()) { |
|||
if (!type.IsGenericType) { |
|||
continue; |
|||
} |
|||
|
|||
var definition = type.GetGenericTypeDefinition(); |
|||
if (definition == null) { |
|||
continue; |
|||
} |
|||
|
|||
if (definition != typeof(IdentityUser<>)) { |
|||
continue; |
|||
} |
|||
|
|||
return type.AsType().GetGenericArguments().Single(); |
|||
} |
|||
|
|||
throw new InvalidOperationException( |
|||
"The type of the key identifier used by the user " + |
|||
$"entity '{builder.UserType}' cannot be automatically inferred."); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNet.Identity.EntityFramework; |
|||
using Microsoft.Data.Entity; |
|||
using OpenIddict.Models; |
|||
|
|||
namespace OpenIddict { |
|||
public class OpenIddictStore<TUser, TApplication, TRole, TKey> : UserStore<TUser, TRole, OpenIddictContext<TUser, TApplication, TRole, TKey>, TKey>, IOpenIddictStore<TUser, TApplication> |
|||
where TUser : IdentityUser<TKey> |
|||
where TApplication : Application |
|||
where TRole : IdentityRole<TKey> |
|||
where TKey : IEquatable<TKey> { |
|||
public OpenIddictStore(OpenIddictContext<TUser, TApplication, TRole, TKey> context) |
|||
: base(context) { |
|||
} |
|||
|
|||
public virtual Task<TApplication> FindApplicationByIdAsync(string identifier, CancellationToken cancellationToken) { |
|||
return Context.Applications.SingleOrDefaultAsync(application => application.ApplicationID == identifier, cancellationToken); |
|||
} |
|||
|
|||
public virtual Task<TApplication> FindApplicationByLogoutRedirectUri(string url, CancellationToken cancellationToken) { |
|||
return Context.Applications.SingleOrDefaultAsync(application => application.LogoutRedirectUri == url, cancellationToken); |
|||
} |
|||
|
|||
public virtual Task<string> GetApplicationTypeAsync(TApplication application, CancellationToken cancellationToken) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
switch (application.Type) { |
|||
case ApplicationType.Confidential: |
|||
return Task.FromResult(OpenIddictConstants.ApplicationTypes.Confidential); |
|||
|
|||
case ApplicationType.Public: |
|||
return Task.FromResult(OpenIddictConstants.ApplicationTypes.Public); |
|||
|
|||
default: |
|||
throw new InvalidOperationException($"Unsupported application type ('{application.Type.ToString()}')."); |
|||
} |
|||
} |
|||
|
|||
public virtual Task<string> GetDisplayNameAsync(TApplication application, CancellationToken cancellationToken) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Task.FromResult(application.DisplayName); |
|||
} |
|||
|
|||
public virtual Task<string> GetRedirectUriAsync(TApplication application, CancellationToken cancellationToken) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Task.FromResult(application.RedirectUri); |
|||
} |
|||
|
|||
public virtual Task<bool> ValidateSecretAsync(TApplication application, string secret, CancellationToken cancellationToken) { |
|||
if (application == null) { |
|||
throw new ArgumentNullException(nameof(application)); |
|||
} |
|||
|
|||
return Task.FromResult(string.Equals(application.Secret, secret, StringComparison.Ordinal)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
{ |
|||
"version": "1.0.0-alpha1-*", |
|||
|
|||
"dependencies": { |
|||
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-*", |
|||
|
|||
"Microsoft.Extensions.NotNullAttribute.Sources": { |
|||
"type": "build", |
|||
"version": "1.0.0-*" |
|||
}, |
|||
|
|||
"OpenIddict.Core": "1.0.0-*", |
|||
"OpenIddict.Models": "1.0.0-*" |
|||
}, |
|||
|
|||
"frameworks": { |
|||
"dnx451": { }, |
|||
"dnxcore50": { } |
|||
} |
|||
} |
|||
@ -1,42 +1,17 @@ |
|||
{ |
|||
"version": "1.0.0-alpha1-*", |
|||
|
|||
"resource": "Views/**", |
|||
|
|||
"dependencies": { |
|||
"Microsoft.AspNet.Cors": "6.0.0-*", |
|||
"Microsoft.AspNet.FileProviders.Embedded": "1.0.0-*", |
|||
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-*", |
|||
"Microsoft.AspNet.Mvc": "6.0.0-*", |
|||
"Microsoft.AspNet.StaticFiles": "1.0.0-*", |
|||
|
|||
"Microsoft.Extensions.Configuration.Json": "1.0.0-*", |
|||
"OpenIddict.EF": "1.0.0-*", |
|||
|
|||
"Microsoft.Extensions.NotNullAttribute.Sources": { |
|||
"type": "build", |
|||
"version": "1.0.0-*" |
|||
}, |
|||
|
|||
"AspNet.Hosting.Extensions": "1.0.0-*", |
|||
"AspNet.Security.OpenIdConnect.Server": "1.0.0-*", |
|||
|
|||
"OpenIddict.Assets": "1.0.0-*", |
|||
"OpenIddict.Models": "1.0.0-*" |
|||
} |
|||
}, |
|||
|
|||
"frameworks": { |
|||
"dnx451": { |
|||
"dependencies": { |
|||
"AspNet.Hosting.Katana.Extensions": "1.0.0-*", |
|||
"NWebsec.Owin": "1.0.0" |
|||
} |
|||
}, |
|||
|
|||
"dnxcore50": { |
|||
"dependencies": { |
|||
"System.Linq": "4.0.1-*", |
|||
"System.Runtime.Serialization.Primitives": "4.0.11-*" |
|||
} |
|||
} |
|||
"dnx451": { }, |
|||
"dnxcore50": { } |
|||
} |
|||
} |
|||
Loading…
Reference in new issue