mirror of https://github.com/abpframework/abp.git
16 changed files with 265 additions and 40 deletions
@ -1,27 +0,0 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:2922/", |
|||
"sslPort": 44394 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Volo.Abp.Account.Web.IdentityServer": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "https://localhost:5001;http://localhost:5000" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.OpenIddict; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace Volo.Abp.Account.Web; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAccountWebModule), |
|||
typeof(AbpOpenIddictAspNetCoreModule) |
|||
)] |
|||
public class AbpAccountWebOpenIddictModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAccountWebOpenIddictModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAccountWebOpenIddictModule>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,134 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using OpenIddict.Abstractions; |
|||
using OpenIddict.Server; |
|||
using OpenIddict.Server.AspNetCore; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace Volo.Abp.Account.Web.Pages.Account; |
|||
|
|||
[ExposeServices(typeof(LoginModel))] |
|||
public class OpenIddictSupportedLoginModel : LoginModel |
|||
{ |
|||
public OpenIddictSupportedLoginModel( |
|||
IAuthenticationSchemeProvider schemeProvider, |
|||
IOptions<AbpAccountOptions> accountOptions, |
|||
IOptions<IdentityOptions> identityOptions) |
|||
: base(schemeProvider, accountOptions, identityOptions) |
|||
{ |
|||
} |
|||
|
|||
public async override Task<IActionResult> OnGetAsync() |
|||
{ |
|||
LoginInput = new LoginInputModel(); |
|||
|
|||
var request = await GetOpenIddictRequestFromReturnUrlAsync(ReturnUrl); |
|||
if (request?.ClientId != null) |
|||
{ |
|||
ShowCancelButton = true; |
|||
|
|||
LoginInput.UserNameOrEmailAddress = request.LoginHint; |
|||
|
|||
//TODO: Reference AspNetCore MultiTenancy module and use options to get the tenant key!
|
|||
var tenant = request.GetParameter(TenantResolverConsts.DefaultTenantKey)?.ToString(); |
|||
if (!string.IsNullOrEmpty(tenant)) |
|||
{ |
|||
CurrentTenant.Change(Guid.Parse(tenant)); |
|||
Response.Cookies.Append(TenantResolverConsts.DefaultTenantKey, tenant); |
|||
} |
|||
} |
|||
|
|||
return await base.OnGetAsync(); |
|||
} |
|||
|
|||
public async override Task<IActionResult> OnPostAsync(string action) |
|||
{ |
|||
if (action == "Cancel") |
|||
{ |
|||
var request = await GetOpenIddictRequestFromReturnUrlAsync(ReturnUrl); |
|||
if (request?.ClientId == null) |
|||
{ |
|||
return Redirect("~/"); |
|||
} |
|||
|
|||
var transaction = HttpContext.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction; |
|||
|
|||
transaction.EndpointType = OpenIddictServerEndpointType.Authorization; |
|||
transaction.Request = request; |
|||
|
|||
var notification = new OpenIddictServerEvents.ValidateAuthorizationRequestContext(transaction); |
|||
transaction.SetProperty(typeof(OpenIddictServerEvents.ValidateAuthorizationRequestContext).FullName!, notification); |
|||
|
|||
return Forbid(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); |
|||
} |
|||
|
|||
return await base.OnPostAsync(action); |
|||
} |
|||
|
|||
protected virtual Task<OpenIddictRequest> GetOpenIddictRequestFromReturnUrlAsync(string returnUrl) |
|||
{ |
|||
if (!returnUrl.IsNullOrWhiteSpace()) |
|||
{ |
|||
var qm = returnUrl.IndexOf("?", StringComparison.Ordinal); |
|||
if (qm > 0) |
|||
{ |
|||
return Task.FromResult(new OpenIddictRequest(returnUrl.Substring(qm + 1) |
|||
.Split("&") |
|||
.Select(x => |
|||
x.Split("=").Length == 2 |
|||
? new KeyValuePair<string, string>(x.Split("=")[0], WebUtility.UrlDecode(x.Split("=")[1])) |
|||
: new KeyValuePair<string, string>(null, null)) |
|||
.Where(x => x.Key != null))); |
|||
} |
|||
} |
|||
|
|||
return Task.FromResult<OpenIddictRequest>(null); |
|||
} |
|||
|
|||
public async override Task<IActionResult> OnPostExternalLogin(string provider) |
|||
{ |
|||
if (AccountOptions.WindowsAuthenticationSchemeName == provider) |
|||
{ |
|||
return await ProcessWindowsLoginAsync(); |
|||
} |
|||
|
|||
return await base.OnPostExternalLogin(provider); |
|||
} |
|||
|
|||
protected virtual async Task<IActionResult> ProcessWindowsLoginAsync() |
|||
{ |
|||
var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName); |
|||
if (result.Succeeded) |
|||
{ |
|||
var props = new AuthenticationProperties() |
|||
{ |
|||
RedirectUri = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash }), |
|||
Items = |
|||
{ |
|||
{ |
|||
"LoginProvider", AccountOptions.WindowsAuthenticationSchemeName |
|||
} |
|||
} |
|||
}; |
|||
|
|||
var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName); |
|||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, result.Principal.FindFirstValue(ClaimTypes.PrimarySid))); |
|||
id.AddClaim(new Claim(ClaimTypes.Name, result.Principal.FindFirstValue(ClaimTypes.Name))); |
|||
|
|||
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props); |
|||
|
|||
return Redirect(props.RedirectUri!); |
|||
} |
|||
|
|||
return Challenge(AccountOptions.WindowsAuthenticationSchemeName); |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap |
|||
@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling |
|||
@ -0,0 +1,34 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Account.Web.OpenIddict</AssemblyName> |
|||
<PackageId>Volo.Abp.Account.Web.OpenIddict</PackageId> |
|||
<IsPackable>true</IsPackable> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> |
|||
<RootNamespace>Volo.Abp.Account.Web</RootNamespace> |
|||
<OutputType>Library</OutputType> |
|||
</PropertyGroup> |
|||
|
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\openiddict\src\Volo.Abp.OpenIddict.AspNetCore\Volo.Abp.OpenIddict.AspNetCore.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.Account.Web\Volo.Abp.Account.Web.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="$(MicrosoftPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
Loading…
Reference in new issue