Browse Source

Refactor

pull/12084/head
maliming 5 years ago
parent
commit
a6014e5672
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 36
      modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/Account/OpenIddictSupportedLoginModel.cs
  2. 14
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictHttpContextExtensions.cs
  3. 32
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictRequestHelper.cs
  4. 32
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ClaimDestinations/AbpOpenIddictClaimDestinationsManager.cs
  5. 13
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AbpOpenIdDictControllerBase.cs
  6. 4
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs
  7. 15
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.cs
  8. 20
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/AbpOpenIddictExtensionGrantsOptions.cs
  9. 17
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/ExtensionGrantContext.cs
  10. 11
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/IExtensionGrant.cs
  11. 6
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/ITokenExtensionGrant.cs

36
modules/account/src/Volo.Abp.Account.Web.OpenIddict/Pages/Account/OpenIddictSupportedLoginModel.cs

@ -1,37 +1,37 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using OpenIddict.Abstractions;
using OpenIddict.Server; using OpenIddict.Server;
using OpenIddict.Server.AspNetCore; using OpenIddict.Server.AspNetCore;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Volo.Abp.OpenIddict;
namespace Volo.Abp.Account.Web.Pages.Account; namespace Volo.Abp.Account.Web.Pages.Account;
[ExposeServices(typeof(LoginModel))] [ExposeServices(typeof(LoginModel))]
public class OpenIddictSupportedLoginModel : LoginModel public class OpenIddictSupportedLoginModel : LoginModel
{ {
protected AbpOpenIddictRequestHelper OpenIddictRequestHelper { get; }
public OpenIddictSupportedLoginModel( public OpenIddictSupportedLoginModel(
IAuthenticationSchemeProvider schemeProvider, IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions, IOptions<AbpAccountOptions> accountOptions,
IOptions<IdentityOptions> identityOptions) IOptions<IdentityOptions> identityOptions,
AbpOpenIddictRequestHelper openIddictRequestHelper)
: base(schemeProvider, accountOptions, identityOptions) : base(schemeProvider, accountOptions, identityOptions)
{ {
OpenIddictRequestHelper = openIddictRequestHelper;
} }
public async override Task<IActionResult> OnGetAsync() public async override Task<IActionResult> OnGetAsync()
{ {
LoginInput = new LoginInputModel(); LoginInput = new LoginInputModel();
var request = await GetOpenIddictRequestFromReturnUrlAsync(ReturnUrl); var request = await OpenIddictRequestHelper.GetFromReturnUrlAsync(ReturnUrl);
if (request?.ClientId != null) if (request?.ClientId != null)
{ {
ShowCancelButton = true; ShowCancelButton = true;
@ -54,9 +54,9 @@ public class OpenIddictSupportedLoginModel : LoginModel
{ {
if (action == "Cancel") if (action == "Cancel")
{ {
var request = await GetOpenIddictRequestFromReturnUrlAsync(ReturnUrl); var request = await OpenIddictRequestHelper.GetFromReturnUrlAsync(ReturnUrl);
var transaction = HttpContext.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction; var transaction = HttpContext.GetOpenIddictServerTransaction();
if (request?.ClientId != null && transaction != null) if (request?.ClientId != null && transaction != null)
{ {
transaction.EndpointType = OpenIddictServerEndpointType.Authorization; transaction.EndpointType = OpenIddictServerEndpointType.Authorization;
@ -74,26 +74,6 @@ public class OpenIddictSupportedLoginModel : LoginModel
return await base.OnPostAsync(action); 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) public async override Task<IActionResult> OnPostExternalLogin(string provider)
{ {
if (AccountOptions.WindowsAuthenticationSchemeName == provider) if (AccountOptions.WindowsAuthenticationSchemeName == provider)

14
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictHttpContextExtensions.cs

@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Http;
using OpenIddict.Server;
using OpenIddict.Server.AspNetCore;
namespace Volo.Abp.OpenIddict;
public static class AbpOpenIddictHttpContextExtensions
{
public static OpenIddictServerTransaction GetOpenIddictServerTransaction(this HttpContext context)
{
Check.NotNull(context, nameof(context));
return context.Features.Get<OpenIddictServerAspNetCoreFeature>()?.Transaction;
}
}

32
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictRequestHelper.cs

@ -0,0 +1,32 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using OpenIddict.Abstractions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictRequestHelper : ITransientDependency
{
public virtual Task<OpenIddictRequest> GetFromReturnUrlAsync(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);
}
}

32
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ClaimDestinations/AbpOpenIddictClaimDestinationsManager.cs

@ -0,0 +1,32 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.OpenIddict;
public class AbpOpenIddictClaimDestinationsManager : ISingletonDependency
{
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IOptions<AbpOpenIddictClaimDestinationsOptions> Options { get; }
public AbpOpenIddictClaimDestinationsManager(IServiceScopeFactory serviceScopeFactory, IOptions<AbpOpenIddictClaimDestinationsOptions> options)
{
ServiceScopeFactory = serviceScopeFactory;
Options = options;
}
public virtual async Task SetAsync(ClaimsPrincipal principal)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
foreach (var providerType in Options.Value.ClaimDestinationsProvider)
{
var provider = (IAbpOpenIddictClaimDestinationsProvider)scope.ServiceProvider.GetRequiredService(providerType);
await provider.SetDestinationsAsync(new AbpOpenIddictClaimDestinationsProviderContext(scope.ServiceProvider, principal, principal.Claims.ToArray()));
}
}
}
}

13
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AbpOpenIdDictControllerBase.cs

@ -25,14 +25,14 @@ public abstract class AbpOpenIdDictControllerBase : AbpController
protected IOpenIddictAuthorizationManager AuthorizationManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictAuthorizationManager>(); protected IOpenIddictAuthorizationManager AuthorizationManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictAuthorizationManager>();
protected IOpenIddictScopeManager ScopeManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictScopeManager>(); protected IOpenIddictScopeManager ScopeManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictScopeManager>();
protected IOpenIddictTokenManager TokenManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictTokenManager>(); protected IOpenIddictTokenManager TokenManager => LazyServiceProvider.LazyGetRequiredService<IOpenIddictTokenManager>();
protected IOptions<AbpOpenIddictClaimDestinationsOptions> OpenIddictClaimDestinationsOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpOpenIddictClaimDestinationsOptions>>(); protected AbpOpenIddictClaimDestinationsManager OpenIddictClaimDestinationsManager => LazyServiceProvider.LazyGetRequiredService<AbpOpenIddictClaimDestinationsManager>();
protected AbpOpenIdDictControllerBase() protected AbpOpenIdDictControllerBase()
{ {
LocalizationResource = typeof(AbpOpenIddictResource); LocalizationResource = typeof(AbpOpenIddictResource);
} }
protected virtual Task<OpenIddictRequest> GetOpenIddictServerRequest(HttpContext httpContext) protected virtual Task<OpenIddictRequest> GetOpenIddictServerRequestAsync(HttpContext httpContext)
{ {
var request = HttpContext.GetOpenIddictServerRequest() ?? var request = HttpContext.GetOpenIddictServerRequest() ??
throw new InvalidOperationException(L["TheOpenIDConnectRequestCannotBeRetrieved"]); throw new InvalidOperationException(L["TheOpenIDConnectRequestCannotBeRetrieved"]);
@ -57,13 +57,6 @@ public abstract class AbpOpenIdDictControllerBase : AbpController
protected virtual async Task SetClaimsDestinationsAsync(ClaimsPrincipal principal) protected virtual async Task SetClaimsDestinationsAsync(ClaimsPrincipal principal)
{ {
using (var scope = LazyServiceProvider.LazyGetRequiredService<IServiceProvider>().CreateScope()) await OpenIddictClaimDestinationsManager.SetAsync(principal);
{
foreach (var providerType in OpenIddictClaimDestinationsOptions.Value.ClaimDestinationsProvider)
{
var provider = (IAbpOpenIddictClaimDestinationsProvider)scope.ServiceProvider.GetRequiredService(providerType);
await provider.SetDestinationsAsync(new AbpOpenIddictClaimDestinationsProviderContext(scope.ServiceProvider, principal, principal.Claims.ToArray()));
}
}
} }
} }

4
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs

@ -22,7 +22,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
[IgnoreAntiforgeryToken] [IgnoreAntiforgeryToken]
public virtual async Task<IActionResult> HandleAsync() public virtual async Task<IActionResult> HandleAsync()
{ {
var request = await GetOpenIddictServerRequest(HttpContext); var request = await GetOpenIddictServerRequestAsync(HttpContext);
// If prompt=login was specified by the client application, // If prompt=login was specified by the client application,
// immediately return the user agent to the login page. // immediately return the user agent to the login page.
@ -162,7 +162,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
[Authorize, AbpFormValueRequired("submit.Accept")] [Authorize, AbpFormValueRequired("submit.Accept")]
public virtual async Task<IActionResult> HandleAcceptConsentAsync() public virtual async Task<IActionResult> HandleAcceptConsentAsync()
{ {
var request = await GetOpenIddictServerRequest(HttpContext); var request = await GetOpenIddictServerRequestAsync(HttpContext);
// Retrieve the profile of the logged in user. // Retrieve the profile of the logged in user.
var user = await UserManager.GetUserAsync(User) ?? var user = await UserManager.GetUserAsync(User) ??

15
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/TokenController.cs

@ -1,6 +1,10 @@
using System.Threading.Tasks; using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using Volo.Abp.OpenIddict.ExtensionGrantTypes;
namespace Volo.Abp.OpenIddict.Controllers; namespace Volo.Abp.OpenIddict.Controllers;
@ -10,7 +14,7 @@ public partial class TokenController : AbpOpenIdDictControllerBase
[HttpGet, HttpPost, Produces("application/json")] [HttpGet, HttpPost, Produces("application/json")]
public virtual async Task<IActionResult> HandleAsync() public virtual async Task<IActionResult> HandleAsync()
{ {
var request = await GetOpenIddictServerRequest(HttpContext); var request = await GetOpenIddictServerRequestAsync(HttpContext);
if (request.IsPasswordGrantType()) if (request.IsPasswordGrantType())
{ {
@ -37,6 +41,13 @@ public partial class TokenController : AbpOpenIdDictControllerBase
return await HandleClientCredentialsAsync(request); return await HandleClientCredentialsAsync(request);
} }
var extensionGrantsOptions = HttpContext.RequestServices.GetRequiredService<IOptions<AbpOpenIddictExtensionGrantsOptions>>();
var extensionTokenGrant = extensionGrantsOptions.Value.Find<ITokenExtensionGrant>(request.GrantType);
if (extensionTokenGrant != null)
{
return await extensionTokenGrant.HandleAsync(new ExtensionGrantContext(HttpContext, request));
}
throw new AbpException(string.Format(L["TheSpecifiedGrantTypeIsNotImplemented"], request.GrantType)); throw new AbpException(string.Format(L["TheSpecifiedGrantTypeIsNotImplemented"], request.GrantType));
} }
} }

20
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/AbpOpenIddictExtensionGrantsOptions.cs

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Linq;
namespace Volo.Abp.OpenIddict.ExtensionGrantTypes;
public class AbpOpenIddictExtensionGrantsOptions
{
public Dictionary<string, IExtensionGrant> Grants { get; }
public AbpOpenIddictExtensionGrantsOptions()
{
Grants = new Dictionary<string, IExtensionGrant>();
}
public TExtensionGrantType Find<TExtensionGrantType>(string name)
where TExtensionGrantType : IExtensionGrant
{
return (TExtensionGrantType)Grants.FirstOrDefault(x => x.Key == name && x.Value is TExtensionGrantType).Value;
}
}

17
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/ExtensionGrantContext.cs

@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Http;
using OpenIddict.Abstractions;
namespace Volo.Abp.OpenIddict.ExtensionGrantTypes;
public class ExtensionGrantContext
{
public HttpContext HttpContext { get; }
public OpenIddictRequest Request { get; }
public ExtensionGrantContext(HttpContext httpContext, OpenIddictRequest request)
{
HttpContext = httpContext;
Request = request;
}
}

11
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/IExtensionGrant.cs

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.OpenIddict.ExtensionGrantTypes;
public interface IExtensionGrant
{
string Name { get; }
Task<IActionResult> HandleAsync(ExtensionGrantContext context);
}

6
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/ExtensionGrantTypes/ITokenExtensionGrant.cs

@ -0,0 +1,6 @@
namespace Volo.Abp.OpenIddict.ExtensionGrantTypes;
public interface ITokenExtensionGrant : IExtensionGrant
{
}
Loading…
Cancel
Save