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 AspNet.Security.OpenIdConnect.Extensions |
||||
@using Microsoft.IdentityModel.Protocols.OpenIdConnect |
@using Microsoft.IdentityModel.Protocols.OpenIdConnect |
||||
@using OpenIddict.Models |
|
||||
|
|
||||
@model Tuple<OpenIdConnectMessage, Application> |
@model Tuple<OpenIdConnectMessage, string> |
||||
|
|
||||
<div class="jumbotron"> |
<div class="jumbotron"> |
||||
<h1>Authorization</h1> |
<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">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.DisplayName</strong> will be able to access the following endpoints: @string.Join(" ; ", Model.Item1.GetResources())</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"> |
<form enctype="application/x-www-form-urlencoded" method="post"> |
||||
@Html.AntiForgeryToken() |
@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-*", |
"version": "1.0.0-alpha1-*", |
||||
|
|
||||
"resource": "Views/**", |
|
||||
|
|
||||
"dependencies": { |
"dependencies": { |
||||
"Microsoft.AspNet.Cors": "6.0.0-*", |
"OpenIddict.EF": "1.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-*", |
|
||||
|
|
||||
"Microsoft.Extensions.NotNullAttribute.Sources": { |
"Microsoft.Extensions.NotNullAttribute.Sources": { |
||||
"type": "build", |
"type": "build", |
||||
"version": "1.0.0-*" |
"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": { |
"frameworks": { |
||||
"dnx451": { |
"dnx451": { }, |
||||
"dependencies": { |
"dnxcore50": { } |
||||
"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-*" |
|
||||
} |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
Loading…
Reference in new issue