mirror of https://github.com/abpframework/abp.git
committed by
GitHub
112 changed files with 1569 additions and 528 deletions
@ -0,0 +1,46 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Localization; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers |
||||
|
{ |
||||
|
public class AbpTagHelperLocalizer : IAbpTagHelperLocalizer |
||||
|
{ |
||||
|
private readonly IStringLocalizerFactory _stringLocalizerFactory; |
||||
|
private readonly AbpMvcDataAnnotationsLocalizationOptions _options; |
||||
|
|
||||
|
public AbpTagHelperLocalizer(IOptions<AbpMvcDataAnnotationsLocalizationOptions> options, IStringLocalizerFactory stringLocalizerFactory) |
||||
|
{ |
||||
|
_stringLocalizerFactory = stringLocalizerFactory; |
||||
|
_options = options.Value; |
||||
|
} |
||||
|
|
||||
|
public string GetLocalizedText(string text, ModelExplorer explorer) |
||||
|
{ |
||||
|
var localizer = GetStringLocalizer(explorer); |
||||
|
|
||||
|
return localizer == null ? text : localizer[text].Value; |
||||
|
} |
||||
|
|
||||
|
public IStringLocalizer GetLocalizer(ModelExplorer explorer) |
||||
|
{ |
||||
|
return GetStringLocalizer(explorer); |
||||
|
} |
||||
|
|
||||
|
private IStringLocalizer GetStringLocalizer(ModelExplorer explorer) |
||||
|
{ |
||||
|
IStringLocalizer localizer = null; |
||||
|
var resourceType = _options.AssemblyResources.GetOrDefault(explorer.Container.ModelType.Assembly); |
||||
|
|
||||
|
if (resourceType != null) |
||||
|
{ |
||||
|
localizer = _stringLocalizerFactory.Create(resourceType); |
||||
|
} |
||||
|
|
||||
|
return localizer; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers |
||||
|
{ |
||||
|
public interface IAbpTagHelperLocalizer : ITransientDependency |
||||
|
{ |
||||
|
string GetLocalizedText(string text, ModelExplorer explorer); |
||||
|
|
||||
|
IStringLocalizer GetLocalizer(ModelExplorer explorer); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.Http.Client.IdentityModel</AssemblyName> |
||||
|
<PackageId>Volo.Abp.Http.Client.IdentityModel</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="IdentityModel" Version="3.10.4" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Http.Client\Volo.Abp.Http.Client.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.IdentityModel\Volo.Abp.IdentityModel.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Volo.Abp.IdentityModel; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.IdentityModel |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpHttpClientModule), |
||||
|
typeof(AbpIdentityModelModule) |
||||
|
)] |
||||
|
public class AbpHttpClientIdentityModelModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
using System.Net.Http.Headers; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authentication; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client.Authentication; |
||||
|
using Volo.Abp.IdentityModel; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.IdentityModel |
||||
|
{ |
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
public class IdentityModelRemoteServiceHttpClientAuthenticator : IRemoteServiceHttpClientAuthenticator, ITransientDependency |
||||
|
{ |
||||
|
public IHttpContextAccessor HttpContextAccessor { get; set; } |
||||
|
|
||||
|
protected IIdentityModelHttpClientAuthenticator IdentityModelHttpClientAuthenticator { get; } |
||||
|
|
||||
|
public IdentityModelRemoteServiceHttpClientAuthenticator(IIdentityModelHttpClientAuthenticator identityModelHttpClientAuthenticator) |
||||
|
{ |
||||
|
IdentityModelHttpClientAuthenticator = identityModelHttpClientAuthenticator; |
||||
|
} |
||||
|
|
||||
|
public async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) |
||||
|
{ |
||||
|
var accessToken = await GetAccessTokenFromHttpContextOrNullAsync(); |
||||
|
|
||||
|
if (accessToken != null) |
||||
|
{ |
||||
|
//TODO: "Bearer" should be configurable
|
||||
|
context.Client.DefaultRequestHeaders.Authorization |
||||
|
= new AuthenticationHeaderValue("Bearer", accessToken); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
await IdentityModelHttpClientAuthenticator.Authenticate( |
||||
|
new IdentityModelHttpClientAuthenticateContext( |
||||
|
context.Client, |
||||
|
context.RemoteService.GetIdentityClient() |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<string> GetAccessTokenFromHttpContextOrNullAsync() |
||||
|
{ |
||||
|
//TODO: What if the access_token in the current Http Request is not usable for this client?
|
||||
|
var httpContext = HttpContextAccessor?.HttpContext; |
||||
|
if (httpContext == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return await httpContext.GetTokenAsync("access_token"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client |
||||
|
{ |
||||
|
public static class RemoteServiceConfigurationExtensions |
||||
|
{ |
||||
|
public const string IdentityClient = "IdentityClient"; |
||||
|
|
||||
|
[CanBeNull] |
||||
|
public static string GetIdentityClient([NotNull] this RemoteServiceConfiguration configuration) |
||||
|
{ |
||||
|
Check.NotNullOrEmpty(configuration, nameof(configuration)); |
||||
|
|
||||
|
return configuration.GetOrDefault(IdentityClient); |
||||
|
} |
||||
|
|
||||
|
public static RemoteServiceConfiguration SetIdentityClient([NotNull] this RemoteServiceConfiguration configuration, [CanBeNull] string value) |
||||
|
{ |
||||
|
configuration[IdentityClient] = value; |
||||
|
return configuration; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,23 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Authentication; |
|
||||
using Microsoft.AspNetCore.Http; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
|
|
||||
namespace Volo.Abp.Http.Client.Authentication |
|
||||
{ |
|
||||
public class HttpContextAccessTokenProvider : IAccessTokenProvider, ISingletonDependency |
|
||||
{ |
|
||||
public IHttpContextAccessor HttpContextAccessor { get; set; } |
|
||||
|
|
||||
public async Task<string> GetOrNullAsync() |
|
||||
{ |
|
||||
var httpContext = HttpContextAccessor?.HttpContext; |
|
||||
if (httpContext == null) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return await httpContext.GetTokenAsync("access_token"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,9 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Volo.Abp.Http.Client.Authentication |
|
||||
{ |
|
||||
public interface IAccessTokenProvider //TODO: Not sure if this class should be here
|
|
||||
{ |
|
||||
Task<string> GetOrNullAsync(); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.Authentication |
||||
|
{ |
||||
|
public interface IRemoteServiceHttpClientAuthenticator |
||||
|
{ |
||||
|
Task Authenticate(RemoteServiceHttpClientAuthenticateContext context); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.Authentication |
||||
|
{ |
||||
|
[Dependency(TryRegister = true)] |
||||
|
public class NullRemoteServiceHttpClientAuthenticator : IRemoteServiceHttpClientAuthenticator, ISingletonDependency |
||||
|
{ |
||||
|
public Task Authenticate(RemoteServiceHttpClientAuthenticateContext context) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System.Net.Http; |
||||
|
|
||||
|
namespace Volo.Abp.Http.Client.Authentication |
||||
|
{ |
||||
|
public class RemoteServiceHttpClientAuthenticateContext |
||||
|
{ |
||||
|
public HttpClient Client { get; } |
||||
|
|
||||
|
public HttpRequestMessage Request { get; } |
||||
|
|
||||
|
public RemoteServiceConfiguration RemoteService { get; } |
||||
|
|
||||
|
public RemoteServiceHttpClientAuthenticateContext( |
||||
|
HttpClient client, |
||||
|
HttpRequestMessage request, |
||||
|
RemoteServiceConfiguration remoteService) |
||||
|
{ |
||||
|
Client = client; |
||||
|
Request = request; |
||||
|
RemoteService = remoteService; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.IdentityModel</AssemblyName> |
||||
|
<PackageId>Volo.Abp.IdentityModel</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="IdentityModel" Version="3.10.4" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,15 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
public class AbpIdentityModelModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var configuration = context.Services.GetConfiguration(); |
||||
|
|
||||
|
Configure<IdentityClientOptions>(configuration); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
public interface IIdentityModelHttpClientAuthenticator |
||||
|
{ |
||||
|
Task Authenticate(IdentityModelHttpClientAuthenticateContext context); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using IdentityModel; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
public class IdentityClientConfiguration : Dictionary<string, string> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Possible values: "client_credentials" or "password".
|
||||
|
/// Default value: "client_credentials".
|
||||
|
/// </summary>
|
||||
|
public string GrantType |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(GrantType)); |
||||
|
set => this[GrantType] = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Client Id.
|
||||
|
/// </summary>
|
||||
|
public string ClientId |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(ClientId)); |
||||
|
set => this[ClientId] = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Client secret (as plain text - without hashed).
|
||||
|
/// </summary>
|
||||
|
public string ClientSecret |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(ClientSecret)); |
||||
|
set => this[ClientSecret] = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// User name.
|
||||
|
/// Valid only if <see cref="GrantType"/> is "password".
|
||||
|
/// </summary>
|
||||
|
public string UserName |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(UserName)); |
||||
|
set => this[UserName] = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Password of the <see cref="UserName"/>.
|
||||
|
/// Valid only if <see cref="GrantType"/> is "password".
|
||||
|
/// </summary>
|
||||
|
public string UserPassword |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(UserPassword)); |
||||
|
set => this[UserPassword] = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Authority.
|
||||
|
/// </summary>
|
||||
|
public string Authority |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(Authority)); |
||||
|
set => this[Authority] = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Scope.
|
||||
|
/// </summary>
|
||||
|
public string Scope |
||||
|
{ |
||||
|
get => this.GetOrDefault(nameof(Scope)); |
||||
|
set => this[Scope] = value; |
||||
|
} |
||||
|
|
||||
|
public IdentityClientConfiguration() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public IdentityClientConfiguration( |
||||
|
string clientId, |
||||
|
string clientSecret, |
||||
|
string grantType = OidcConstants.GrantTypes.ClientCredentials, |
||||
|
string userName = null, |
||||
|
string userPassword = null) |
||||
|
{ |
||||
|
this[nameof(ClientId)] = clientId; |
||||
|
this[nameof(ClientSecret)] = clientSecret; |
||||
|
this[nameof(GrantType)] = grantType; |
||||
|
this[nameof(UserName)] = userName; |
||||
|
this[nameof(UserPassword)] = userPassword; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
public class IdentityClientConfigurationDictionary : Dictionary<string, IdentityClientConfiguration> |
||||
|
{ |
||||
|
public const string DefaultName = "Default"; |
||||
|
|
||||
|
public IdentityClientConfiguration Default |
||||
|
{ |
||||
|
get => this.GetOrDefault(DefaultName); |
||||
|
set => this[DefaultName] = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
public class IdentityClientOptions |
||||
|
{ |
||||
|
public IdentityClientConfigurationDictionary IdentityClients { get; set; } |
||||
|
|
||||
|
public IdentityClientOptions() |
||||
|
{ |
||||
|
IdentityClients = new IdentityClientConfigurationDictionary(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System.Net.Http; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
public class IdentityModelHttpClientAuthenticateContext |
||||
|
{ |
||||
|
public HttpClient Client { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The identity client name configured with the <see cref="IdentityClientOptions"/>.
|
||||
|
/// </summary>
|
||||
|
public string IdentityClientName { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
///
|
||||
|
/// </summary>
|
||||
|
/// <param name="client"><see cref="HttpClient"/> object to be authorized</param>
|
||||
|
/// <param name="identityClientName">The identity client name configured with the <see cref="IdentityClientOptions"/>.</param>
|
||||
|
public IdentityModelHttpClientAuthenticateContext( |
||||
|
HttpClient client, |
||||
|
string identityClientName = null) |
||||
|
{ |
||||
|
Client = client; |
||||
|
IdentityClientName = identityClientName; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Net.Http.Headers; |
||||
|
using System.Threading.Tasks; |
||||
|
using IdentityModel; |
||||
|
using IdentityModel.Client; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityModel |
||||
|
{ |
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
public class IdentityModelHttpClientAuthenticator : IIdentityModelHttpClientAuthenticator, ITransientDependency |
||||
|
{ |
||||
|
protected IdentityClientOptions ClientOptions { get; } |
||||
|
|
||||
|
public IdentityModelHttpClientAuthenticator( |
||||
|
IOptions<IdentityClientOptions> options) |
||||
|
{ |
||||
|
ClientOptions = options.Value; |
||||
|
} |
||||
|
|
||||
|
public async Task Authenticate(IdentityModelHttpClientAuthenticateContext context) |
||||
|
{ |
||||
|
var accessToken = await GetAccessTokenFromServerOrNullAsync(context); |
||||
|
|
||||
|
if (accessToken != null) |
||||
|
{ |
||||
|
//TODO: "Bearer" should be configurable
|
||||
|
context.Client.DefaultRequestHeaders.Authorization |
||||
|
= new AuthenticationHeaderValue("Bearer", accessToken); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<string> GetAccessTokenFromServerOrNullAsync(IdentityModelHttpClientAuthenticateContext context) |
||||
|
{ |
||||
|
var configuration = GetClientConfiguration(context); |
||||
|
|
||||
|
if (configuration == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
var discoveryResponse = await GetDiscoveryResponse(configuration); |
||||
|
if (discoveryResponse.IsError) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
var tokenResponse = await GetTokenResponse(discoveryResponse, configuration); |
||||
|
if (tokenResponse.IsError) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return tokenResponse.AccessToken; |
||||
|
} |
||||
|
|
||||
|
private IdentityClientConfiguration GetClientConfiguration(IdentityModelHttpClientAuthenticateContext context) |
||||
|
{ |
||||
|
if (context.IdentityClientName.IsNullOrEmpty()) |
||||
|
{ |
||||
|
return ClientOptions.IdentityClients.Default; |
||||
|
} |
||||
|
|
||||
|
return ClientOptions.IdentityClients.GetOrDefault(context.IdentityClientName) ?? |
||||
|
ClientOptions.IdentityClients.Default; |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<DiscoveryResponse> GetDiscoveryResponse(IdentityClientConfiguration configuration) |
||||
|
{ |
||||
|
return await DiscoveryClient.GetAsync(configuration.Authority); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<TokenResponse> GetTokenResponse(DiscoveryResponse discoveryResponse, IdentityClientConfiguration configuration) |
||||
|
{ |
||||
|
var tokenClient = new TokenClient(discoveryResponse.TokenEndpoint, configuration.ClientId, configuration.ClientSecret); |
||||
|
|
||||
|
switch (configuration.GrantType) |
||||
|
{ |
||||
|
case OidcConstants.GrantTypes.ClientCredentials: |
||||
|
return await tokenClient.RequestClientCredentialsAsync( |
||||
|
configuration.Scope |
||||
|
); |
||||
|
case OidcConstants.GrantTypes.Password: |
||||
|
return await tokenClient.RequestResourceOwnerPasswordAsync( |
||||
|
configuration.UserName, |
||||
|
configuration.UserPassword, |
||||
|
configuration.Scope |
||||
|
); |
||||
|
default: |
||||
|
throw new AbpException("Grant type was not implemented: " + configuration.GrantType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.Identity.AspNetCore</AssemblyName> |
||||
|
<PackageId>Volo.Abp.Identity.AspNetCore</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,38 @@ |
|||||
|
using Microsoft.AspNetCore.Identity; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.Identity.AspNetCore |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpIdentityDomainModule) |
||||
|
)] |
||||
|
public class AbpIdentityAspNetCoreModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services |
||||
|
.GetObject<IdentityBuilder>() |
||||
|
.AddDefaultTokenProviders() |
||||
|
.AddSignInManager(); |
||||
|
|
||||
|
//(TODO: Extract an extension method like IdentityBuilder.AddAbpSecurityStampValidator())
|
||||
|
context.Services.AddScoped<AbpSecurityStampValidator>(); |
||||
|
context.Services.AddScoped(typeof(SecurityStampValidator<IdentityUser>), provider => provider.GetService(typeof(AbpSecurityStampValidator))); |
||||
|
context.Services.AddScoped(typeof(ISecurityStampValidator), provider => provider.GetService(typeof(AbpSecurityStampValidator))); |
||||
|
|
||||
|
var options = context.Services.ExecutePreConfiguredActions(new AbpIdentityAspNetCoreOptions()); |
||||
|
|
||||
|
if (options.ConfigureAuthentication) |
||||
|
{ |
||||
|
context.Services |
||||
|
.AddAuthentication(o => |
||||
|
{ |
||||
|
o.DefaultScheme = IdentityConstants.ApplicationScheme; |
||||
|
o.DefaultSignInScheme = IdentityConstants.ExternalScheme; |
||||
|
}) |
||||
|
.AddIdentityCookies(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
namespace Volo.Abp.Identity.AspNetCore |
||||
|
{ |
||||
|
public class AbpIdentityAspNetCoreOptions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Default: true.
|
||||
|
/// </summary>
|
||||
|
public bool ConfigureAuthentication { get; set; } = true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityServer.IdentityResources |
||||
|
{ |
||||
|
public interface IIdentityResourceDataSeeder |
||||
|
{ |
||||
|
Task CreateStandardResourcesAsync(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.Identity; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityServer.IdentityResources |
||||
|
{ |
||||
|
public class IdentityResourceDataSeeder : IIdentityResourceDataSeeder, ITransientDependency |
||||
|
{ |
||||
|
protected IIdentityClaimTypeRepository ClaimTypeRepository { get; } |
||||
|
protected IIdentityResourceRepository IdentityResourceRepository { get; } |
||||
|
protected IGuidGenerator GuidGenerator { get; } |
||||
|
|
||||
|
public IdentityResourceDataSeeder( |
||||
|
IIdentityResourceRepository identityResourceRepository, |
||||
|
IGuidGenerator guidGenerator, |
||||
|
IIdentityClaimTypeRepository claimTypeRepository) |
||||
|
{ |
||||
|
IdentityResourceRepository = identityResourceRepository; |
||||
|
GuidGenerator = guidGenerator; |
||||
|
ClaimTypeRepository = claimTypeRepository; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task CreateStandardResourcesAsync() |
||||
|
{ |
||||
|
var resources = new IdentityServer4.Models.IdentityResource[] |
||||
|
{ |
||||
|
new IdentityServer4.Models.IdentityResources.OpenId(), |
||||
|
new IdentityServer4.Models.IdentityResources.Profile(), |
||||
|
new IdentityServer4.Models.IdentityResources.Email(), |
||||
|
new IdentityServer4.Models.IdentityResources.Address(), |
||||
|
new IdentityServer4.Models.IdentityResources.Phone() |
||||
|
}; |
||||
|
|
||||
|
foreach (var resource in resources) |
||||
|
{ |
||||
|
foreach (var claimType in resource.UserClaims) |
||||
|
{ |
||||
|
await AddClaimTypeIfNotExistsAsync(claimType); |
||||
|
} |
||||
|
|
||||
|
await AddIdentityResourceIfNotExistsAsync(resource); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task AddIdentityResourceIfNotExistsAsync(IdentityServer4.Models.IdentityResource resource) |
||||
|
{ |
||||
|
if (await IdentityResourceRepository.FindByNameAsync(resource.Name) != null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await IdentityResourceRepository.InsertAsync( |
||||
|
new IdentityResource( |
||||
|
GuidGenerator.Create(), |
||||
|
resource |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task AddClaimTypeIfNotExistsAsync(string claimType) |
||||
|
{ |
||||
|
if (await ClaimTypeRepository.AnyAsync(claimType)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await ClaimTypeRepository.InsertAsync( |
||||
|
new IdentityClaimType( |
||||
|
GuidGenerator.Create(), |
||||
|
claimType, |
||||
|
isStatic: true |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.IdentityServer |
||||
|
{ |
||||
|
public class AbpIdentityServerTestData : ISingletonDependency |
||||
|
{ |
||||
|
public Guid Client1Id { get; } = Guid.NewGuid(); |
||||
|
|
||||
|
public Guid ApiResource1Id { get; } = Guid.NewGuid(); |
||||
|
|
||||
|
public Guid IdentityResource1Id { get; } = Guid.NewGuid(); |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue