committed by
GitHub
665 changed files with 129365 additions and 1058 deletions
@ -0,0 +1,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(MicrosoftPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\cloud-tencent\LINGYUN.Abp.Tencent.QQ\LINGYUN.Abp.Tencent.QQ.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
namespace LINGYUN.Abp.Authentication.QQ; |
|||
|
|||
public static class AbpAuthenticationQQConsts |
|||
{ |
|||
public static string AuthenticationScheme { get; set; } = "QQ Connect"; |
|||
public static string DisplayName { get; set; } = "QQ Connect"; |
|||
public static string CallbackPath { get; set; } = "/signin-callback"; |
|||
} |
|||
@ -1,14 +1,12 @@ |
|||
using LINGYUN.Abp.Tencent.QQ; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.IdentityServer; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.QQ; |
|||
namespace LINGYUN.Abp.Authentication.QQ; |
|||
|
|||
[DependsOn(typeof(AbpTencentQQModule))] |
|||
[DependsOn(typeof(AbpIdentityServerDomainModule))] |
|||
public class AbpIdentityServerQQModule : AbpModule |
|||
public class AbpAuthenticationQQModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
@ -1,4 +1,4 @@ |
|||
namespace LINGYUN.Abp.WeChat.Security.Claims |
|||
namespace LINGYUN.Abp.Authentication.QQ |
|||
{ |
|||
/// <summary>
|
|||
/// QQ互联身份类型,可以像 <see cref="Volo.Abp.Security.Claims.AbpClaimTypes"/> 自行配置
|
|||
@ -0,0 +1,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(MicrosoftPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat.Official\LINGYUN.Abp.WeChat.Official.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,67 @@ |
|||
using LINGYUN.Abp.WeChat; |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
|
|||
namespace LINGYUN.Abp.Authentication.WeChat; |
|||
|
|||
public static class AbpAuthenticationWeChatConsts |
|||
{ |
|||
/// <summary>
|
|||
/// 微信个人信息标识
|
|||
/// </summary>
|
|||
public static string ProfileKey => AbpWeChatGlobalConsts.ProfileKey; |
|||
/// <summary>
|
|||
/// 微信提供者标识
|
|||
/// </summary>
|
|||
public static string ProviderKey => AbpWeChatOfficialConsts.ProviderName; |
|||
/// <summary>
|
|||
/// 微信提供者显示名称
|
|||
/// </summary>
|
|||
public static string DisplayName => AbpWeChatGlobalConsts.DisplayName; |
|||
/// <summary>
|
|||
/// 回调地址
|
|||
/// </summary>
|
|||
public static string CallbackPath { get; set; } = "/signin-callback"; |
|||
|
|||
/// <summary>
|
|||
/// 微信客户端外的网页登录
|
|||
/// </summary>
|
|||
public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect"; |
|||
|
|||
/// <summary>
|
|||
/// 微信客户端内的网页登录
|
|||
/// </summary>
|
|||
public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize"; |
|||
|
|||
/// <summary>
|
|||
/// 用户允许授权后通过返回的code换取access_token地址
|
|||
/// </summary>
|
|||
public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token"; |
|||
|
|||
/// <summary>
|
|||
/// 使用access_token获取用户个人信息地址
|
|||
/// </summary>
|
|||
public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo"; |
|||
/// <summary>
|
|||
/// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
|
|||
/// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
|
|||
/// <br />
|
|||
/// <br />
|
|||
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
|
|||
/// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
|
|||
/// </remarks>
|
|||
public const string UserInfoScope = "snsapi_userinfo"; |
|||
/// <summary>
|
|||
/// 不弹出授权页面,直接跳转,只能获取用户openid
|
|||
/// <br />
|
|||
/// <br />
|
|||
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
|
|||
/// 用户感知的就是直接进入了回调页(往往是业务页面)
|
|||
/// </remarks>
|
|||
public const string LoginScope = "snsapi_login"; |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Authentication.WeChat; |
|||
|
|||
[DependsOn(typeof(AbpWeChatOfficialModule))] |
|||
public class AbpAuthenticationWeChatModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services |
|||
.AddAuthentication() |
|||
.AddWeChat(); |
|||
} |
|||
} |
|||
6
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs → aspnet-core/modules/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs
6
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs → aspnet-core/modules/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs
16
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs → aspnet-core/modules/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs
16
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs → aspnet-core/modules/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs
0
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs → aspnet-core/modules/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs
0
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs → aspnet-core/modules/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs
@ -1,5 +1,5 @@ |
|||
using LINGYUN.Abp.IdentityServer.WeChat.Official; |
|||
|
|||
using Microsoft.AspNetCore.Http; |
|||
|
|||
namespace Microsoft.AspNetCore.Builder |
|||
{ |
|||
public static class IdentityServerApplicationBuilderExtensions |
|||
@ -1,12 +1,11 @@ |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
using Microsoft.AspNetCore.Http; |
|||
using System; |
|||
using System.Collections; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat.Official |
|||
namespace Microsoft.AspNetCore.Http |
|||
{ |
|||
public class WeChatOfficialSignatureMiddleware : IMiddleware, ITransientDependency |
|||
{ |
|||
@ -1,10 +1,11 @@ |
|||
using System.Threading.Tasks; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.BackgroundWorkers; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundWorkers.Hangfire |
|||
{ |
|||
public interface IHangfireBackgroundWorkerAdapter : IBackgroundWorker |
|||
{ |
|||
Task ExecuteAsync(); |
|||
Task ExecuteAsync(CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,40 @@ |
|||
# LINGYUN.Abp.Wrapper |
|||
|
|||
包装器模块 |
|||
|
|||
## 配置使用 |
|||
|
|||
```csharp |
|||
[DependsOn(typeof(AbpWrapperModule))] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpWrapperOptions>(options => |
|||
{ |
|||
// 启用包装器 |
|||
options.IsEnabled = true; |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
## 配置项说明 |
|||
|
|||
* AbpWrapperOptions.IsEnabled 是否包装返回结果,默认: false |
|||
* AbpWrapperOptions.CodeWithUnhandled 出现未处理异常时的返回错误代码,默认500 |
|||
* AbpWrapperOptions.CodeWithSuccess 处理成功返回代码,默认0 |
|||
* AbpWrapperOptions.ErrorWithEmptyResult 请求资源时,如果资源为空是否返回错误消息,默认false |
|||
* AbpWrapperOptions.HttpStatusCode 包装后的Http响应代码, 默认: 200 |
|||
* AbpWrapperOptions.CodeWithEmptyResult 当返回空对象时返回错误代码,默认: 404 |
|||
* AbpWrapperOptions.MessageWithEmptyResult 当返回空对象时返回错误消息, 默认: Not Found |
|||
|
|||
* AbpWrapperOptions.IgnorePrefixUrls 指定哪些Url开头的地址不需要处理 |
|||
* AbpWrapperOptions.IgnoreNamespaces 指定哪些命名空间开头不需要处理 |
|||
* AbpWrapperOptions.IgnoreControllers 指定哪些控制器不需要处理 |
|||
* AbpWrapperOptions.IgnoreReturnTypes 指定哪些返回结果类型不需要处理 |
|||
* AbpWrapperOptions.IgnoreExceptions 指定哪些异常类型不需要处理 |
|||
* AbpWrapperOptions.IgnoredInterfaces 指定哪些接口不需要处理(默认实现**IWrapDisabled**接口不进行处理) |
|||
|
|||
|
|||
## 其他 |
|||
|
|||
@ -1,8 +0,0 @@ |
|||
namespace LINGYUN.Abp.IdentityServer.QQ; |
|||
|
|||
public static class AbpIdentityServerQQConsts |
|||
{ |
|||
public static string AuthenticationScheme { get; set; } = "QQ Connect"; |
|||
public static string DisplayName { get; set; } = "QQ Connect"; |
|||
public static string CallbackPath { get; set; } = "/signin-qq"; |
|||
} |
|||
@ -1,26 +0,0 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\WeChat\Localization\en.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\IdentityServer\WeChat\Localization\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.IdentityServer.Domain" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj" /> |
|||
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj" /> |
|||
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat.Official\LINGYUN.Abp.WeChat.Official.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -1,56 +0,0 @@ |
|||
using LINGYUN.Abp.Identity.WeChat; |
|||
using LINGYUN.Abp.IdentityServer.WeChat.MiniProgram; |
|||
using LINGYUN.Abp.IdentityServer.WeChat.Official; |
|||
using LINGYUN.Abp.WeChat.MiniProgram; |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.IdentityServer; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpWeChatOfficialModule), |
|||
typeof(AbpWeChatMiniProgramModule), |
|||
typeof(AbpIdentityWeChatModule), |
|||
typeof(AbpIdentityServerDomainModule))] |
|||
public class AbpIdentityServerWeChatModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
PreConfigure<IIdentityServerBuilder>(builder => |
|||
{ |
|||
builder.AddProfileService<WeChatMiniProgramProfileService>(); |
|||
|
|||
// TODO: 两个类型不通用配置项,不然只需要一个
|
|||
builder.AddExtensionGrantValidator<WeChatMiniProgramGrantValidator>(); |
|||
builder.AddExtensionGrantValidator<WeChatOfficialGrantValidator>(); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpIdentityServerWeChatModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AbpIdentityServerResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/IdentityServer/WeChat/Localization"); |
|||
}); |
|||
|
|||
context.Services |
|||
.AddAuthentication() |
|||
.AddWeChat(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,75 +0,0 @@ |
|||
using IdentityServer4.Models; |
|||
using IdentityServer4.Services; |
|||
using IdentityServer4.Validation; |
|||
using LINGYUN.Abp.WeChat.Localization; |
|||
using LINGYUN.Abp.WeChat.MiniProgram; |
|||
using LINGYUN.Abp.WeChat.MiniProgram.Features; |
|||
using LINGYUN.Abp.WeChat.OpenId; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
using IdentityUser = Volo.Abp.Identity.IdentityUser; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram |
|||
{ |
|||
/// <summary>
|
|||
/// 对于小程序绑定用户的扩展授权验证器
|
|||
/// </summary>
|
|||
public class WeChatMiniProgramGrantValidator : WeChatGrantValidator |
|||
{ |
|||
public override string GrantType => AbpWeChatMiniProgramConsts.GrantType; |
|||
|
|||
public override string LoginProvider => AbpWeChatMiniProgramConsts.ProviderName; |
|||
|
|||
public override string AuthenticationMethod => AbpWeChatMiniProgramConsts.AuthenticationMethod; |
|||
|
|||
protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; } |
|||
|
|||
protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService<IFeatureChecker>(); |
|||
|
|||
public WeChatMiniProgramGrantValidator( |
|||
IEventService eventService, |
|||
IWeChatOpenIdFinder weChatOpenIdFinder, |
|||
UserManager<IdentityUser> userManager, |
|||
IIdentityUserRepository userRepository, |
|||
IdentitySecurityLogManager identitySecurityLogManager, |
|||
IStringLocalizer<Volo.Abp.Identity.Localization.IdentityResource> identityLocalizer, |
|||
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer, |
|||
IStringLocalizer<WeChatResource> wechatLocalizer, |
|||
AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory) |
|||
: base( |
|||
eventService, |
|||
weChatOpenIdFinder, |
|||
userManager, |
|||
userRepository, |
|||
identitySecurityLogManager, |
|||
wechatLocalizer, |
|||
identityLocalizer, |
|||
identityServerLocalizer) |
|||
{ |
|||
MiniProgramOptionsFactory = miniProgramOptionsFactory; |
|||
} |
|||
|
|||
protected override async Task<bool> CheckFeatureAsync(ExtensionGrantValidationContext context) |
|||
{ |
|||
if (!await FeatureChecker.IsEnabledAsync(WeChatMiniProgramFeatures.EnableAuthorization)) |
|||
{ |
|||
context.Result = new GrantValidationResult( |
|||
TokenRequestErrors.InvalidGrant, |
|||
WeChatLocalizer["MiniProgramAuthorizationDisabledMessage"]); |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
protected override async Task<WeChatOpenId> FindOpenIdAsync(string code) |
|||
{ |
|||
var options = await MiniProgramOptionsFactory.CreateAsync(); |
|||
|
|||
return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret); |
|||
} |
|||
} |
|||
} |
|||
@ -1,67 +0,0 @@ |
|||
using IdentityServer4.AspNetIdentity; |
|||
using IdentityServer4.Models; |
|||
using LINGYUN.Abp.WeChat.Security.Claims; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using System.Linq; |
|||
using System.Security.Principal; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Uow; |
|||
using IdentityUser = Volo.Abp.Identity.IdentityUser; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram |
|||
{ |
|||
public class WeChatMiniProgramProfileService : ProfileService<IdentityUser> |
|||
{ |
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
public WeChatMiniProgramProfileService( |
|||
IdentityUserManager userManager, |
|||
IUserClaimsPrincipalFactory<IdentityUser> claimsFactory, |
|||
ICurrentTenant currentTenant) |
|||
: base(userManager, claimsFactory) |
|||
{ |
|||
CurrentTenant = currentTenant; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override async Task GetProfileDataAsync(ProfileDataRequestContext context) |
|||
{ |
|||
using (CurrentTenant.Change(context.Subject.FindTenantId())) |
|||
{ |
|||
await base.GetProfileDataAsync(context); |
|||
|
|||
// TODO: 可以从令牌获取openid, 安全性呢?
|
|||
TryAddWeChatClaim(context, AbpWeChatClaimTypes.OpenId); |
|||
TryAddWeChatClaim(context, AbpWeChatClaimTypes.UnionId); |
|||
} |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override async Task IsActiveAsync(IsActiveContext context) |
|||
{ |
|||
using (CurrentTenant.Change(context.Subject.FindTenantId())) |
|||
{ |
|||
await base.IsActiveAsync(context); |
|||
} |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public override Task<bool> IsUserActiveAsync(IdentityUser user) |
|||
{ |
|||
return Task.FromResult(user.IsActive); |
|||
} |
|||
|
|||
protected virtual void TryAddWeChatClaim(ProfileDataRequestContext context, string weChatClaimType) |
|||
{ |
|||
if (context.RequestedClaimTypes.Any(rc => rc.Contains(weChatClaimType))) |
|||
{ |
|||
var weChatClaim = context.Subject.FindFirst(weChatClaimType); |
|||
if (weChatClaim != null) |
|||
{ |
|||
context.IssuedClaims.Add(weChatClaim); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,75 +0,0 @@ |
|||
using IdentityServer4.Models; |
|||
using IdentityServer4.Services; |
|||
using IdentityServer4.Validation; |
|||
using LINGYUN.Abp.WeChat.Localization; |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
using LINGYUN.Abp.WeChat.Official.Features; |
|||
using LINGYUN.Abp.WeChat.OpenId; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
using IdentityUser = Volo.Abp.Identity.IdentityUser; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat.Official |
|||
{ |
|||
/// <summary>
|
|||
/// 对于公众平台绑定用户的扩展授权验证器
|
|||
/// </summary>
|
|||
public class WeChatOfficialGrantValidator : WeChatGrantValidator |
|||
{ |
|||
public override string GrantType => AbpWeChatOfficialConsts.GrantType; |
|||
|
|||
public override string LoginProvider => AbpWeChatOfficialConsts.ProviderName; |
|||
|
|||
public override string AuthenticationMethod => AbpWeChatOfficialConsts.AuthenticationMethod; |
|||
|
|||
protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; } |
|||
|
|||
protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService<IFeatureChecker>(); |
|||
|
|||
public WeChatOfficialGrantValidator( |
|||
IEventService eventService, |
|||
IWeChatOpenIdFinder weChatOpenIdFinder, |
|||
UserManager<IdentityUser> userManager, |
|||
IIdentityUserRepository userRepository, |
|||
IdentitySecurityLogManager identitySecurityLogManager, |
|||
IStringLocalizer<Volo.Abp.Identity.Localization.IdentityResource> identityLocalizer, |
|||
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer, |
|||
IStringLocalizer<WeChatResource> wechatLocalizer, |
|||
AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory) |
|||
: base( |
|||
eventService, |
|||
weChatOpenIdFinder, |
|||
userManager, |
|||
userRepository, |
|||
identitySecurityLogManager, |
|||
wechatLocalizer, |
|||
identityLocalizer, |
|||
identityServerLocalizer) |
|||
{ |
|||
WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory; |
|||
} |
|||
|
|||
protected override async Task<bool> CheckFeatureAsync(ExtensionGrantValidationContext context) |
|||
{ |
|||
if (!await FeatureChecker.IsEnabledAsync(WeChatOfficialFeatures.EnableAuthorization)) |
|||
{ |
|||
context.Result = new GrantValidationResult( |
|||
TokenRequestErrors.InvalidGrant, |
|||
WeChatLocalizer["OfficialAuthorizationDisabledMessage"]); |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
protected override async Task<WeChatOpenId> FindOpenIdAsync(string code) |
|||
{ |
|||
var options = await WeChatOfficialOptionsFactory.CreateAsync(); |
|||
|
|||
return await WeChatOpenIdFinder.FindAsync(code, options.AppId, options.AppSecret); |
|||
} |
|||
} |
|||
} |
|||
@ -1,71 +0,0 @@ |
|||
using LINGYUN.Abp.WeChat; |
|||
using LINGYUN.Abp.WeChat.Official; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat.Official |
|||
{ |
|||
/// <summary>
|
|||
/// 与微信公众号认证相关的静态(可变)常量
|
|||
/// </summary>
|
|||
public static class WeChatOfficialOAuthConsts |
|||
{ |
|||
/// <summary>
|
|||
/// 微信个人信息标识
|
|||
/// </summary>
|
|||
public static string ProfileKey { get; set; } = "wechat.profile"; |
|||
/// <summary>
|
|||
/// 微信提供者标识
|
|||
/// </summary>
|
|||
public static string ProviderKey => AbpWeChatOfficialConsts.ProviderName; |
|||
/// <summary>
|
|||
/// 微信提供者显示名称
|
|||
/// </summary>
|
|||
public static string DisplayName => AbpWeChatGlobalConsts.DisplayName; |
|||
/// <summary>
|
|||
/// 回调地址
|
|||
/// </summary>
|
|||
public static string CallbackPath { get; set; } = "/signin-wechat"; |
|||
|
|||
/// <summary>
|
|||
/// 微信客户端外的网页登录
|
|||
/// </summary>
|
|||
public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect"; |
|||
|
|||
/// <summary>
|
|||
/// 微信客户端内的网页登录
|
|||
/// </summary>
|
|||
public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize"; |
|||
|
|||
/// <summary>
|
|||
/// 用户允许授权后通过返回的code换取access_token地址
|
|||
/// </summary>
|
|||
public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token"; |
|||
|
|||
/// <summary>
|
|||
/// 使用access_token获取用户个人信息地址
|
|||
/// </summary>
|
|||
public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo"; |
|||
/// <summary>
|
|||
/// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
|
|||
/// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
|
|||
/// <br />
|
|||
/// <br />
|
|||
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
|
|||
/// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
|
|||
/// </remarks>
|
|||
public const string UserInfoScope = "snsapi_userinfo"; |
|||
/// <summary>
|
|||
/// 不弹出授权页面,直接跳转,只能获取用户openid
|
|||
/// <br />
|
|||
/// <br />
|
|||
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
|
|||
/// 用户感知的就是直接进入了回调页(往往是业务页面)
|
|||
/// </remarks>
|
|||
public const string LoginScope = "snsapi_login"; |
|||
} |
|||
} |
|||
@ -1,242 +0,0 @@ |
|||
using IdentityModel; |
|||
using IdentityServer4.Events; |
|||
using IdentityServer4.Models; |
|||
using IdentityServer4.Services; |
|||
using IdentityServer4.Validation; |
|||
using LINGYUN.Abp.WeChat; |
|||
using LINGYUN.Abp.WeChat.Localization; |
|||
using LINGYUN.Abp.WeChat.OpenId; |
|||
using LINGYUN.Abp.WeChat.Security.Claims; |
|||
using LINGYUN.Abp.WeChat.Settings; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.Extensions.Localization; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.IdentityServer; |
|||
using Volo.Abp.IdentityServer.Localization; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Security.Claims; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.Uow; |
|||
|
|||
using IdentityResource = Volo.Abp.Identity.Localization.IdentityResource; |
|||
using IdentityUser = Volo.Abp.Identity.IdentityUser; |
|||
|
|||
namespace LINGYUN.Abp.IdentityServer.WeChat |
|||
{ |
|||
public abstract class WeChatGrantValidator : IExtensionGrantValidator |
|||
{ |
|||
public abstract string GrantType { get; } |
|||
public abstract string LoginProvider { get; } |
|||
public abstract string AuthenticationMethod { get; } |
|||
|
|||
public ILogger Logger { protected get; set; } |
|||
public IAbpLazyServiceProvider ServiceProvider { protected get; set; } |
|||
|
|||
protected IEventService EventService { get; } |
|||
protected IWeChatOpenIdFinder WeChatOpenIdFinder { get; } |
|||
protected IIdentityUserRepository UserRepository { get; } |
|||
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; } |
|||
protected UserManager<IdentityUser> UserManager { get; } |
|||
protected IStringLocalizer<WeChatResource> WeChatLocalizer { get; } |
|||
protected IStringLocalizer<IdentityResource> IdentityLocalizer { get; } |
|||
protected IStringLocalizer<AbpIdentityServerResource> IdentityServerLocalizer { get; } |
|||
|
|||
public WeChatGrantValidator( |
|||
IEventService eventService, |
|||
IWeChatOpenIdFinder weChatOpenIdFinder, |
|||
UserManager<IdentityUser> userManager, |
|||
IIdentityUserRepository userRepository, |
|||
IdentitySecurityLogManager identitySecurityLogManager, |
|||
IStringLocalizer<WeChatResource> wechatLocalizer, |
|||
IStringLocalizer<IdentityResource> identityLocalizer, |
|||
IStringLocalizer<AbpIdentityServerResource> identityServerLocalizer) |
|||
{ |
|||
EventService = eventService; |
|||
UserManager = userManager; |
|||
UserRepository = userRepository; |
|||
IdentitySecurityLogManager = identitySecurityLogManager; |
|||
WeChatOpenIdFinder = weChatOpenIdFinder; |
|||
WeChatLocalizer = wechatLocalizer; |
|||
IdentityLocalizer = identityLocalizer; |
|||
IdentityServerLocalizer = identityServerLocalizer; |
|||
|
|||
Logger = NullLogger<WeChatGrantValidator>.Instance; |
|||
} |
|||
|
|||
protected abstract Task<WeChatOpenId> FindOpenIdAsync(string code); |
|||
|
|||
[UnitOfWork] |
|||
public async Task ValidateAsync(ExtensionGrantValidationContext context) |
|||
{ |
|||
if (!await CheckFeatureAsync(context)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var raw = context.Request.Raw; |
|||
var credential = raw.Get(OidcConstants.TokenRequest.GrantType); |
|||
if (credential == null || !credential.Equals(GrantType)) |
|||
{ |
|||
Logger.LogWarning("Invalid grant type: not allowed"); |
|||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:GrantTypeInvalid"]); |
|||
return; |
|||
} |
|||
|
|||
var wechatCode = raw.Get(AbpWeChatGlobalConsts.TokenName); |
|||
if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace()) |
|||
{ |
|||
Logger.LogWarning("Invalid grant type: wechat code not found"); |
|||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatCodeNotFound"]); |
|||
return; |
|||
} |
|||
|
|||
WeChatOpenId wechatOpenId; |
|||
try |
|||
{ |
|||
wechatOpenId = await FindOpenIdAsync(wechatCode); |
|||
} |
|||
catch(AbpWeChatException e) |
|||
{ |
|||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, e.Message); |
|||
return; |
|||
} |
|||
var currentUser = await UserManager.FindByLoginAsync(LoginProvider, wechatOpenId.OpenId); |
|||
if (currentUser == null) |
|||
{ |
|||
// 检查是否允许自注册
|
|||
var settingProvider = ServiceProvider.LazyGetRequiredService<ISettingProvider>(); |
|||
// TODO 检查启用用户注册是否有必要引用账户模块
|
|||
if (!await settingProvider.IsTrueAsync("Abp.Account.IsSelfRegistrationEnabled") || |
|||
!await settingProvider.IsTrueAsync(WeChatSettingNames.EnabledQuickLogin)) |
|||
{ |
|||
Logger.LogWarning("Invalid grant type: wechat openid not register", wechatOpenId.OpenId); |
|||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatNotRegister"]); |
|||
return; |
|||
} |
|||
var guiGenerator = ServiceProvider.LazyGetRequiredService<IGuidGenerator>(); |
|||
var currentTenant = ServiceProvider.LazyGetRequiredService<ICurrentTenant>(); |
|||
var userName = "wxid-" + wechatOpenId.OpenId.ToMd5().ToLower(); |
|||
var userEmail = $"{userName}@{currentTenant.Name ?? "default"}.io"; |
|||
currentUser = new IdentityUser(guiGenerator.Create(), userName, userEmail, currentTenant.Id); |
|||
(await UserManager.CreateAsync(currentUser)).CheckErrors(); |
|||
(await UserManager.AddLoginAsync( |
|||
currentUser, |
|||
new UserLoginInfo( |
|||
LoginProvider, |
|||
wechatOpenId.OpenId, |
|||
AbpWeChatGlobalConsts.DisplayName))).CheckErrors(); |
|||
} |
|||
|
|||
// 检查是否已锁定
|
|||
if (await UserManager.IsLockedOutAsync(currentUser)) |
|||
{ |
|||
Logger.LogInformation("Authentication failed for username: {username}, reason: locked out", currentUser.UserName); |
|||
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityLocalizer["Volo.Abp.Identity:UserLockedOut"]); |
|||
|
|||
await SaveSecurityLogAsync(context, currentUser, wechatOpenId, IdentityServerSecurityLogActionConsts.LoginLockedout); |
|||
|
|||
return; |
|||
} |
|||
|
|||
await EventService.RaiseAsync(new UserLoginSuccessEvent(currentUser.UserName, wechatOpenId.OpenId, null)); |
|||
|
|||
// 登录之后需要更新安全令牌
|
|||
(await UserManager.UpdateSecurityStampAsync(currentUser)).CheckErrors(); |
|||
|
|||
await SetSuccessResultAsync(context, currentUser, wechatOpenId); |
|||
} |
|||
|
|||
protected virtual Task<bool> CheckFeatureAsync(ExtensionGrantValidationContext context) |
|||
{ |
|||
return Task.FromResult(true); |
|||
} |
|||
|
|||
protected async virtual Task SetSuccessResultAsync(ExtensionGrantValidationContext context, IdentityUser user, WeChatOpenId wechatOpenId) |
|||
{ |
|||
var sub = await UserManager.GetUserIdAsync(user); |
|||
|
|||
Logger.LogInformation("Credentials validated for username: {username}", user.UserName); |
|||
|
|||
var additionalClaims = new List<Claim>(); |
|||
|
|||
await AddCustomClaimsAsync(additionalClaims, user, wechatOpenId, context); |
|||
|
|||
context.Result = new GrantValidationResult( |
|||
sub, |
|||
AuthenticationMethod, |
|||
additionalClaims.ToArray() |
|||
); |
|||
|
|||
await SaveSecurityLogAsync( |
|||
context, |
|||
user, |
|||
wechatOpenId, |
|||
IdentityServerSecurityLogActionConsts.LoginSucceeded); |
|||
} |
|||
|
|||
protected async virtual Task SaveSecurityLogAsync( |
|||
ExtensionGrantValidationContext context, |
|||
IdentityUser user, |
|||
WeChatOpenId wechatOpenId, |
|||
string action) |
|||
{ |
|||
var logContext = new IdentitySecurityLogContext |
|||
{ |
|||
Identity = IdentityServerSecurityLogIdentityConsts.IdentityServer, |
|||
Action = action, |
|||
UserName = user.UserName, |
|||
ClientId = await FindClientIdAsync(context) |
|||
}; |
|||
logContext.WithProperty("GrantType", GrantType); |
|||
logContext.WithProperty("Provider", LoginProvider); |
|||
logContext.WithProperty("Method", AuthenticationMethod); |
|||
|
|||
await IdentitySecurityLogManager.SaveAsync(logContext); |
|||
} |
|||
|
|||
protected virtual Task<string> FindClientIdAsync(ExtensionGrantValidationContext context) |
|||
{ |
|||
return Task.FromResult(context.Request?.Client?.ClientId); |
|||
} |
|||
|
|||
protected virtual Task AddCustomClaimsAsync( |
|||
List<Claim> customClaims, |
|||
IdentityUser user, |
|||
WeChatOpenId wechatOpenId, |
|||
ExtensionGrantValidationContext context) |
|||
{ |
|||
if (user.TenantId.HasValue) |
|||
{ |
|||
customClaims.Add( |
|||
new Claim( |
|||
AbpClaimTypes.TenantId, |
|||
user.TenantId?.ToString() |
|||
) |
|||
); |
|||
} |
|||
|
|||
customClaims.Add( |
|||
new Claim( |
|||
AbpWeChatClaimTypes.OpenId, |
|||
wechatOpenId.OpenId)); |
|||
|
|||
if (!wechatOpenId.UnionId.IsNullOrWhiteSpace()) |
|||
{ |
|||
customClaims.Add( |
|||
new Claim( |
|||
AbpWeChatClaimTypes.UnionId, |
|||
wechatOpenId.UnionId)); |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -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,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\OpenIddict\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\OpenIddict\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Authorization.Abstractions" Version="$(VoloAbpPackageVersion)" /> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="$(VoloAbpPackageVersion)" /> |
|||
<PackageReference Include="Volo.Abp.OpenIddict.Domain.Shared" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,29 @@ |
|||
using Volo.Abp.Authorization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.OpenIddict; |
|||
using Volo.Abp.OpenIddict.Localization; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAuthorizationAbstractionsModule), |
|||
typeof(AbpOpenIddictDomainSharedModule))] |
|||
public class AbpOpenIddictApplicationContractsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpOpenIddictApplicationContractsModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AbpOpenIddictResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/OpenIddict/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
public interface IOpenIddictApplicationAppService : |
|||
ICrudAppService< |
|||
OpenIddictApplicationDto, |
|||
Guid, |
|||
OpenIddictApplicationGetListInput, |
|||
OpenIddictApplicationCreateDto, |
|||
OpenIddictApplicationUpdateDto> |
|||
{ |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictApplicationCreateDto : OpenIddictApplicationCreateOrUpdateDto |
|||
{ |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.OpenIddict.Applications; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
public abstract class OpenIddictApplicationCreateOrUpdateDto : ExtensibleObject |
|||
{ |
|||
[Required] |
|||
[DynamicStringLength(typeof(OpenIddictApplicationConsts), nameof(OpenIddictApplicationConsts.ClientIdMaxLength))] |
|||
public string ClientId { get; set; } |
|||
|
|||
public string ClientSecret { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(OpenIddictApplicationConsts), nameof(OpenIddictApplicationConsts.ConsentTypeMaxLength))] |
|||
public string ConsentType { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public Dictionary<string, string> DisplayNames { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
public List<string> Endpoints { get; set; } = new List<string>(); |
|||
public List<string> GrantTypes { get; set; } = new List<string>(); |
|||
public List<string> ResponseTypes { get; set; } = new List<string>(); |
|||
public List<string> Scopes { get; set; } = new List<string>(); |
|||
|
|||
public List<string> PostLogoutRedirectUris { get; set; } = new List<string>(); |
|||
|
|||
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
public List<string> RedirectUris { get; set; } = new List<string>(); |
|||
|
|||
public List<string> Requirements { get; set; } = new List<string>(); |
|||
|
|||
[DynamicStringLength(typeof(OpenIddictApplicationConsts), nameof(OpenIddictApplicationConsts.TypeMaxLength))] |
|||
public string Type { get; set; } |
|||
|
|||
public string ClientUri { get; set; } |
|||
|
|||
public string LogoUri { get; set; } |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictApplicationDto : ExtensibleAuditedEntityDto<Guid> |
|||
{ |
|||
public string ClientId { get; set; } |
|||
public string ClientSecret { get; set; } |
|||
public string ConsentType { get; set; } |
|||
public string DisplayName { get; set; } |
|||
public Dictionary<string, string> DisplayNames { get; set; } = new Dictionary<string, string>(); |
|||
public List<string> Endpoints { get; set; } = new List<string>(); |
|||
public List<string> GrantTypes { get; set; } = new List<string>(); |
|||
public List<string> ResponseTypes { get; set; } = new List<string>(); |
|||
public List<string> Scopes { get; set; } = new List<string>(); |
|||
public List<string> PostLogoutRedirectUris { get; set; } = new List<string>(); |
|||
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>(); |
|||
public List<string> RedirectUris { get; set; } = new List<string>(); |
|||
public List<string> Requirements { get; set; } = new List<string>(); |
|||
public string Type { get; set; } |
|||
public string ClientUri { get; set; } |
|||
public string LogoUri { get; set; } |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictApplicationGetListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictApplicationUpdateDto : OpenIddictApplicationCreateOrUpdateDto |
|||
{ |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Authorizations; |
|||
|
|||
public interface IOpenIddictAuthorizationAppService : |
|||
IReadOnlyAppService< |
|||
OpenIddictAuthorizationDto, |
|||
Guid, |
|||
OpenIddictAuthorizationGetListInput>, |
|||
IDeleteAppService<Guid> |
|||
{ |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Authorizations; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictAuthorizationDto : ExtensibleAuditedEntityDto<Guid> |
|||
{ |
|||
public Guid? ApplicationId { get; set; } |
|||
public DateTime? CreationDate { get; set; } |
|||
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>(); |
|||
public List<string> Scopes { get; set; } = new List<string>(); |
|||
public string Status { get; set; } |
|||
public string Subject { get; set; } |
|||
public string Type { get; set; } |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Authorizations; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictAuthorizationGetListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
public string Subject { get; set; } |
|||
public Guid? ClientId { get; set; } |
|||
public string Status { get; set; } |
|||
public string Type { get; set; } |
|||
public DateTime? BeginCreationTime { get; set; } |
|||
public DateTime? EndCreationTime { get; set; } |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Permissions:OpenIddict": "OpenIddict", |
|||
"Permissions:Applications": "Applications", |
|||
"Permissions:Scopes": "Scopes", |
|||
"Permissions:Tokens": "Tokens", |
|||
"Permissions:Create": "Create", |
|||
"Permissions:Update": "Update", |
|||
"Permissions:Delete": "Delete", |
|||
"Permissions:ManagePermissions": "Manage Permissions", |
|||
"OpenIddict:Applications:0001": "The application client id {ClientId} already exists!", |
|||
"OpenIddict:Scopes:0001": "The scope name {Name} already exists!", |
|||
"DisplayName:ClientId": "Client Id", |
|||
"DisplayName:ClientSecret": "Client Secret", |
|||
"DisplayName:ConsentType": "Consent Type", |
|||
"DisplayName:DisplayName": "Display Name", |
|||
"DisplayName:DisplayNames": "Display Names", |
|||
"DisplayName:Permissions": "Permissions", |
|||
"DisplayName:PostLogoutRedirectUris": "Post Logout Redirect Uris", |
|||
"DisplayName:Properties": "Properties", |
|||
"DisplayName:RedirectUris": "Redirect Uris", |
|||
"DisplayName:Requirements": "Requirements", |
|||
"DisplayName:Type": "Type", |
|||
"DisplayName:ClientUri": "Client Uri", |
|||
"DisplayName:LogoUri": "Logo", |
|||
"DisplayName:ApplicationId": "Application Id", |
|||
"DisplayName:CreationDate": "Creation Date", |
|||
"DisplayName:Scopes": "Scopes", |
|||
"DisplayName:Status": "Status", |
|||
"DisplayName:Subject": "Subject", |
|||
"DisplayName:Description": "Description", |
|||
"DisplayName:Descriptions": "Descriptions", |
|||
"DisplayName:Name": "Name", |
|||
"DisplayName:Resources": "Resources", |
|||
"DisplayName:AuthorizationId": "Authorization Id", |
|||
"DisplayName:ExpirationDate": "Expiration Date", |
|||
"DisplayName:Payload": "Payload", |
|||
"DisplayName:RedemptionDate": "Redemption Date", |
|||
"DisplayName:ReferenceId": "Reference Id", |
|||
"DisplayName:LastModificationTime": "Modify time", |
|||
"DisplayName:CreationTime": "Creation time" |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Permissions:OpenIddict": "OpenIddict", |
|||
"Permissions:Applications": "应用", |
|||
"Permissions:Scopes": "范围", |
|||
"Permissions:Tokens": "令牌", |
|||
"Permissions:Create": "创建", |
|||
"Permissions:Update": "编辑", |
|||
"Permissions:Delete": "删除", |
|||
"Permissions:ManagePermissions": "管理权限", |
|||
"OpenIddict:Applications:0001": "应用标识 {ClientId} 已经存在!", |
|||
"OpenIddict:Scopes:0001": "范围名称 {Name} 已经存在!", |
|||
"DisplayName:ClientId": "客户端标识", |
|||
"DisplayName:ClientSecret": "客户端密钥", |
|||
"DisplayName:ConsentType": "同意类型", |
|||
"DisplayName:DisplayName": "显示名称", |
|||
"DisplayName:DisplayNames": "显示名称", |
|||
"DisplayName:Permissions": "权限", |
|||
"DisplayName:PostLogoutRedirectUris": "注销后重定向Uri", |
|||
"DisplayName:Properties": "属性", |
|||
"DisplayName:RedirectUris": "重定向Uri", |
|||
"DisplayName:Requirements": "需求", |
|||
"DisplayName:Type": "类型", |
|||
"DisplayName:ClientUri": "客户端Uri", |
|||
"DisplayName:LogoUri": "客户端Logo", |
|||
"DisplayName:ApplicationId": "应用标识", |
|||
"DisplayName:CreationDate": "创建日期", |
|||
"DisplayName:Scopes": "范围", |
|||
"DisplayName:Status": "状态", |
|||
"DisplayName:Subject": "主体", |
|||
"DisplayName:Description": "描述", |
|||
"DisplayName:Descriptions": "描述", |
|||
"DisplayName:Name": "名称", |
|||
"DisplayName:Resources": "资源", |
|||
"DisplayName:AuthorizationId": "授权标识", |
|||
"DisplayName:ExpirationDate": "过期时间", |
|||
"DisplayName:Payload": "有效载荷", |
|||
"DisplayName:RedemptionDate": "偿还时间", |
|||
"DisplayName:ReferenceId": "引用标识", |
|||
"DisplayName:LastModificationTime": "修改时间", |
|||
"DisplayName:CreationTime": "创建时间" |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
public static class OpenIddictApplicationErrorCodes |
|||
{ |
|||
private const string Namespace = "OpenIddict:"; |
|||
|
|||
public static class Applications |
|||
{ |
|||
public const string ClientIdExisted = Namespace + "Applications:0001"; |
|||
} |
|||
|
|||
public static class Authorizations |
|||
{ |
|||
|
|||
} |
|||
|
|||
public static class Scopes |
|||
{ |
|||
public const string NameExisted = Namespace + "Scopes:0001"; |
|||
} |
|||
|
|||
public static class Tokens |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
public class OpenIddictRemoteServiceConsts |
|||
{ |
|||
public const string RemoteServiceName = "AbpOpenIddict"; |
|||
|
|||
public const string ModuleName = "openiddict"; |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.OpenIddict.Localization; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Permissions |
|||
{ |
|||
public class AbpIdentityServerPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var openIddictGroup = context.GetGroupOrNull(AbpOpenIddictPermissions.GroupName); |
|||
if (openIddictGroup == null) |
|||
{ |
|||
openIddictGroup = context |
|||
.AddGroup( |
|||
name: AbpOpenIddictPermissions.GroupName, |
|||
displayName: L("Permissions:OpenIddict"), |
|||
multiTenancySide: MultiTenancySides.Host); |
|||
} |
|||
|
|||
var applications = openIddictGroup.AddPermission( |
|||
AbpOpenIddictPermissions.Applications.Default, |
|||
L("Permissions:Applications"), |
|||
MultiTenancySides.Host); |
|||
applications.AddChild( |
|||
AbpOpenIddictPermissions.Applications.Create, |
|||
L("Permissions:Create"), |
|||
MultiTenancySides.Host); |
|||
applications.AddChild( |
|||
AbpOpenIddictPermissions.Applications.Update, |
|||
L("Permissions:Update"), |
|||
MultiTenancySides.Host); |
|||
applications.AddChild( |
|||
AbpOpenIddictPermissions.Applications.Delete, |
|||
L("Permissions:Delete"), |
|||
MultiTenancySides.Host); |
|||
applications.AddChild( |
|||
AbpOpenIddictPermissions.Applications.ManagePermissions, |
|||
L("Permissions:ManagePermissions"), |
|||
MultiTenancySides.Host); |
|||
|
|||
var authorizations = openIddictGroup.AddPermission( |
|||
AbpOpenIddictPermissions.Authorizations.Default, |
|||
L("Permissions:Authorizations"), |
|||
MultiTenancySides.Host); |
|||
authorizations.AddChild( |
|||
AbpOpenIddictPermissions.Authorizations.Delete, |
|||
L("Permissions:Delete"), |
|||
MultiTenancySides.Host); |
|||
|
|||
var scopes = openIddictGroup.AddPermission( |
|||
AbpOpenIddictPermissions.Scopes.Default, |
|||
L("Permissions:Scopes"), |
|||
MultiTenancySides.Host); |
|||
scopes.AddChild( |
|||
AbpOpenIddictPermissions.Scopes.Create, |
|||
L("Permissions:Create"), |
|||
MultiTenancySides.Host); |
|||
scopes.AddChild( |
|||
AbpOpenIddictPermissions.Scopes.Update, |
|||
L("Permissions:Update"), |
|||
MultiTenancySides.Host); |
|||
scopes.AddChild( |
|||
AbpOpenIddictPermissions.Scopes.Delete, |
|||
L("Permissions:Delete"), |
|||
MultiTenancySides.Host); |
|||
|
|||
var tokens = openIddictGroup.AddPermission( |
|||
AbpOpenIddictPermissions.Tokens.Default, |
|||
L("Permissions:Tokens"), |
|||
MultiTenancySides.Host); |
|||
tokens.AddChild( |
|||
AbpOpenIddictPermissions.Tokens.Delete, |
|||
L("Permissions:Delete"), |
|||
MultiTenancySides.Host); |
|||
} |
|||
|
|||
protected virtual LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AbpOpenIddictResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
namespace LINGYUN.Abp.OpenIddict.Permissions |
|||
{ |
|||
public class AbpOpenIddictPermissions |
|||
{ |
|||
public const string GroupName = "AbpOpenIddict"; |
|||
|
|||
public static class Applications |
|||
{ |
|||
public const string Default = GroupName + ".Applications"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Delete = Default + ".Delete"; |
|||
public const string ManagePermissions = Default + ".ManagePermissions"; |
|||
} |
|||
|
|||
public static class Authorizations |
|||
{ |
|||
public const string Default = GroupName + ".Authorizations"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
|
|||
public static class Scopes |
|||
{ |
|||
public const string Default = GroupName + ".Scopes"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Update = Default + ".Update"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
|
|||
public static class Tokens |
|||
{ |
|||
public const string Default = GroupName + ".Tokens"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
public interface IOpenIddictScopeAppService : |
|||
ICrudAppService< |
|||
OpenIddictScopeDto, |
|||
Guid, |
|||
OpenIddictScopeGetListInput, |
|||
OpenIddictScopeCreateDto, |
|||
OpenIddictScopeUpdateDto> |
|||
{ |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictScopeCreateDto : OpenIddictScopeCreateOrUpdateDto |
|||
{ |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.OpenIddict.Scopes; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
public abstract class OpenIddictScopeCreateOrUpdateDto : ExtensibleObject |
|||
{ |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public Dictionary<string, string> Descriptions { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public Dictionary<string, string> DisplayNames { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
[Required] |
|||
[DynamicStringLength(typeof(OpenIddictScopeConsts), nameof(OpenIddictScopeConsts.NameMaxLength))] |
|||
public string Name { get; set; } |
|||
|
|||
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
public List<string> Resources { get; set; } |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictScopeDto : ExtensibleAuditedEntityDto<Guid> |
|||
{ |
|||
public string Description { get; set; } |
|||
|
|||
public Dictionary<string, string> Descriptions { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public Dictionary<string, string> DisplayNames { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>(); |
|||
|
|||
public List<string> Resources { get; set; } |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictScopeGetListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictScopeUpdateDto : OpenIddictScopeCreateOrUpdateDto |
|||
{ |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Tokens; |
|||
|
|||
public interface IOpenIddictTokenAppService : |
|||
IReadOnlyAppService< |
|||
OpenIddictTokenDto, |
|||
Guid, |
|||
OpenIddictTokenGetListInput>, |
|||
IDeleteAppService<Guid> |
|||
{ |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Tokens; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictTokenDto : ExtensibleAuditedEntityDto<Guid> |
|||
{ |
|||
public Guid? ApplicationId { get; set; } |
|||
|
|||
public Guid? AuthorizationId { get; set; } |
|||
|
|||
public DateTime? CreationDate { get; set; } |
|||
|
|||
public DateTime? ExpirationDate { get; set; } |
|||
|
|||
public string Payload { get; set; } |
|||
|
|||
public string Properties { get; set; } |
|||
|
|||
public DateTime? RedemptionDate { get; set; } |
|||
|
|||
public string ReferenceId { get; set; } |
|||
|
|||
public string Status { get; set; } |
|||
|
|||
public string Subject { get; set; } |
|||
|
|||
public string Type { get; set; } |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Tokens; |
|||
|
|||
[Serializable] |
|||
public class OpenIddictTokenGetListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
public Guid? ClientId { get; set; } |
|||
public Guid? AuthorizationId { get; set; } |
|||
public string Subject { get; set; } |
|||
public string Status { get; set; } |
|||
public string Type { get; set; } |
|||
public string ReferenceId { get; set; } |
|||
public DateTime? BeginExpirationDate { get; set; } |
|||
public DateTime? EndExpirationDate { get; set; } |
|||
public DateTime? BeginCreationTime { get; set; } |
|||
public DateTime? EndCreationTime { get; set; } |
|||
} |
|||
@ -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,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.1</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(VoloAbpPackageVersion)" /> |
|||
<PackageReference Include="Volo.Abp.OpenIddict.Domain" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.OpenIddict.Application.Contracts\LINGYUN.Abp.OpenIddict.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.OpenIddict; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpOpenIddictApplicationContractsModule), |
|||
typeof(AbpOpenIddictDomainModule), |
|||
typeof(AbpDddApplicationModule))] |
|||
public class AbpOpenIddictApplicationModule : AbpModule |
|||
{ |
|||
} |
|||
@ -0,0 +1,86 @@ |
|||
using LINGYUN.Abp.OpenIddict.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.OpenIddict.Applications; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Applications.Default)] |
|||
public class OpenIddictApplicationAppService : OpenIddictApplicationServiceBase, IOpenIddictApplicationAppService |
|||
{ |
|||
protected IOpenIddictApplicationRepository Repository { get; } |
|||
|
|||
public OpenIddictApplicationAppService( |
|||
IOpenIddictApplicationRepository repository) |
|||
{ |
|||
Repository = repository; |
|||
} |
|||
|
|||
public async virtual Task<OpenIddictApplicationDto> GetAsync(Guid id) |
|||
{ |
|||
var application = await Repository.GetAsync(id); |
|||
|
|||
return application.ToDto(JsonSerializer); |
|||
} |
|||
|
|||
public async virtual Task<PagedResultDto<OpenIddictApplicationDto>> GetListAsync(OpenIddictApplicationGetListInput input) |
|||
{ |
|||
var totalCount = await Repository.GetCountAsync(input.Filter); |
|||
var entites = await Repository.GetListAsync(input.Sorting, input.SkipCount, input.MaxResultCount, input.Filter); |
|||
|
|||
return new PagedResultDto<OpenIddictApplicationDto>(totalCount, |
|||
entites.Select(entity => entity.ToDto(JsonSerializer)).ToList()); |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Applications.Create)] |
|||
public async virtual Task<OpenIddictApplicationDto> CreateAsync(OpenIddictApplicationCreateDto input) |
|||
{ |
|||
if (await Repository.FindByClientIdAsync(input.ClientId) != null) |
|||
{ |
|||
throw new BusinessException(OpenIddictApplicationErrorCodes.Applications.ClientIdExisted) |
|||
.WithData(nameof(OpenIddictApplication.ClientId), input.ClientId); |
|||
} |
|||
|
|||
var application = new OpenIddictApplication(GuidGenerator.Create()); |
|||
application = input.ToEntity(application, JsonSerializer); |
|||
|
|||
application = await Repository.InsertAsync(application); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return application.ToDto(JsonSerializer); |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Applications.Update)] |
|||
public async virtual Task<OpenIddictApplicationDto> UpdateAsync(Guid id, OpenIddictApplicationUpdateDto input) |
|||
{ |
|||
var application = await Repository.GetAsync(id); |
|||
|
|||
if (!string.Equals(application.ClientId, input.ClientId) && |
|||
await Repository.FindByClientIdAsync(input.ClientId) != null) |
|||
{ |
|||
throw new BusinessException(OpenIddictApplicationErrorCodes.Applications.ClientIdExisted) |
|||
.WithData(nameof(OpenIddictApplicationCreateDto.ClientId), input.ClientId); |
|||
} |
|||
|
|||
application = input.ToEntity(application, JsonSerializer); |
|||
|
|||
application = await Repository.UpdateAsync(application); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return application.ToDto(JsonSerializer); |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Applications.Delete)] |
|||
public async virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
await Repository.DeleteAsync(id); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
} |
|||
@ -0,0 +1,162 @@ |
|||
using OpenIddict.Abstractions; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.OpenIddict.Applications; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
internal static class OpenIddictApplicationExtensions |
|||
{ |
|||
public static OpenIddictApplication ToEntity(this OpenIddictApplicationCreateOrUpdateDto dto, OpenIddictApplication entity, IJsonSerializer jsonSerializer) |
|||
{ |
|||
Check.NotNull(dto, nameof(dto)); |
|||
Check.NotNull(entity, nameof(entity)); |
|||
|
|||
entity.ClientId = dto.ClientId; |
|||
entity.ClientSecret = dto.ClientSecret; |
|||
entity.ConsentType = dto.ConsentType; |
|||
entity.DisplayName = dto.DisplayName; |
|||
entity.DisplayNames = jsonSerializer.Serialize(dto.DisplayNames); |
|||
entity.PostLogoutRedirectUris = jsonSerializer.Serialize(dto.PostLogoutRedirectUris); |
|||
entity.Properties = jsonSerializer.Serialize(dto.Properties); |
|||
entity.RedirectUris = jsonSerializer.Serialize(dto.RedirectUris); |
|||
entity.Type = dto.Type; |
|||
entity.ClientUri = dto.ClientUri; |
|||
entity.LogoUri = dto.LogoUri; |
|||
|
|||
var requirements = new List<string>(); |
|||
requirements.AddRange( |
|||
dto.Requirements.Select(requirement => |
|||
{ |
|||
if (!requirement.StartsWith(OpenIddictConstants.Requirements.Prefixes.Feature)) |
|||
{ |
|||
return OpenIddictConstants.Requirements.Prefixes.Feature + requirement; |
|||
} |
|||
return requirement; |
|||
})); |
|||
entity.Requirements = jsonSerializer.Serialize(requirements); |
|||
|
|||
var permissions = new List<string>(); |
|||
permissions.AddRange( |
|||
dto.Endpoints.Select(endpoint => |
|||
{ |
|||
if (!endpoint.StartsWith(OpenIddictConstants.Permissions.Prefixes.Endpoint)) |
|||
{ |
|||
return OpenIddictConstants.Permissions.Prefixes.Endpoint + endpoint; |
|||
} |
|||
return endpoint; |
|||
})); |
|||
permissions.AddRange( |
|||
dto.GrantTypes.Select(grantType => |
|||
{ |
|||
if (!grantType.StartsWith(OpenIddictConstants.Permissions.Prefixes.GrantType)) |
|||
{ |
|||
return OpenIddictConstants.Permissions.Prefixes.GrantType + grantType; |
|||
} |
|||
return grantType; |
|||
})); |
|||
permissions.AddRange( |
|||
dto.ResponseTypes.Select(responseType => |
|||
{ |
|||
if (!responseType.StartsWith(OpenIddictConstants.Permissions.Prefixes.ResponseType)) |
|||
{ |
|||
return OpenIddictConstants.Permissions.Prefixes.ResponseType + responseType; |
|||
} |
|||
return responseType; |
|||
})); |
|||
permissions.AddRange( |
|||
dto.Scopes.Select(scope => |
|||
{ |
|||
if (!scope.StartsWith(OpenIddictConstants.Permissions.Prefixes.Scope)) |
|||
{ |
|||
return OpenIddictConstants.Permissions.Prefixes.Scope + scope; |
|||
} |
|||
return scope; |
|||
})); |
|||
entity.Permissions = jsonSerializer.Serialize(permissions); |
|||
|
|||
foreach (var extraProperty in dto.ExtraProperties) |
|||
{ |
|||
entity.ExtraProperties.Remove(extraProperty.Key); |
|||
entity.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return entity; |
|||
} |
|||
|
|||
public static OpenIddictApplicationDto ToDto(this OpenIddictApplication entity, IJsonSerializer jsonSerializer) |
|||
{ |
|||
if (entity == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var dto = new OpenIddictApplicationDto |
|||
{ |
|||
Id = entity.Id, |
|||
ClientId = entity.ClientId, |
|||
ClientSecret = entity.ClientSecret, |
|||
ConsentType = entity.ConsentType, |
|||
DisplayName = entity.DisplayName, |
|||
CreationTime = entity.CreationTime, |
|||
CreatorId = entity.CreatorId, |
|||
LastModificationTime = entity.LastModificationTime, |
|||
LastModifierId = entity.LastModifierId, |
|||
DisplayNames = jsonSerializer.DeserializeToDictionary<string, string>(entity.DisplayNames), |
|||
PostLogoutRedirectUris = jsonSerializer.DeserializeToList<string>(entity.PostLogoutRedirectUris), |
|||
Properties = jsonSerializer.DeserializeToDictionary<string, string>(entity.Properties), |
|||
RedirectUris = jsonSerializer.DeserializeToList<string>(entity.RedirectUris), |
|||
Type = entity.Type, |
|||
ClientUri = entity.ClientUri, |
|||
LogoUri = entity.LogoUri |
|||
}; |
|||
|
|||
var requirements = jsonSerializer.DeserializeToList<string>(entity.Requirements); |
|||
dto.Requirements = requirements |
|||
.Where(HasPrefixKey(OpenIddictConstants.Requirements.Prefixes.Feature)) |
|||
.Select(GetPrefixKey(OpenIddictConstants.Requirements.Prefixes.Feature)) |
|||
.ToList(); |
|||
|
|||
var permissions = jsonSerializer.DeserializeToList<string>(entity.Permissions); |
|||
|
|||
dto.Endpoints = permissions |
|||
.Where(HasPrefixKey(OpenIddictConstants.Permissions.Prefixes.Endpoint)) |
|||
.Select(GetPrefixKey(OpenIddictConstants.Permissions.Prefixes.Endpoint)) |
|||
.ToList(); |
|||
|
|||
dto.GrantTypes = permissions |
|||
.Where(HasPrefixKey(OpenIddictConstants.Permissions.Prefixes.GrantType)) |
|||
.Select(GetPrefixKey(OpenIddictConstants.Permissions.Prefixes.GrantType)) |
|||
.ToList(); |
|||
|
|||
dto.ResponseTypes = permissions |
|||
.Where(HasPrefixKey(OpenIddictConstants.Permissions.Prefixes.ResponseType)) |
|||
.Select(GetPrefixKey(OpenIddictConstants.Permissions.Prefixes.ResponseType)) |
|||
.ToList(); |
|||
|
|||
dto.Scopes = permissions |
|||
.Where(HasPrefixKey(OpenIddictConstants.Permissions.Prefixes.Scope)) |
|||
.Select(GetPrefixKey(OpenIddictConstants.Permissions.Prefixes.Scope)) |
|||
.ToList(); |
|||
|
|||
foreach (var extraProperty in entity.ExtraProperties) |
|||
{ |
|||
dto.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return dto; |
|||
} |
|||
|
|||
private static Func<string, bool> HasPrefixKey(string prefix) |
|||
{ |
|||
return p => p.StartsWith(prefix); |
|||
} |
|||
|
|||
private static Func<string, string> GetPrefixKey(string prefix) |
|||
{ |
|||
return p => p.RemovePreFix(prefix); |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
using LINGYUN.Abp.OpenIddict.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.OpenIddict.Authorizations; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Authorizations; |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Authorizations.Default)] |
|||
public class OpenIddictAuthorizationAppService : OpenIddictApplicationServiceBase, IOpenIddictAuthorizationAppService |
|||
{ |
|||
protected IRepository<OpenIddictAuthorization, Guid> Repository { get; } |
|||
|
|||
public OpenIddictAuthorizationAppService( |
|||
IRepository<OpenIddictAuthorization, Guid> repository) |
|||
{ |
|||
Repository = repository; |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Authorizations.Delete)] |
|||
public async virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
await Repository.DeleteAsync(id); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
public async virtual Task<OpenIddictAuthorizationDto> GetAsync(Guid id) |
|||
{ |
|||
var authorization = await Repository.GetAsync(id); |
|||
|
|||
return authorization.ToDto(JsonSerializer); |
|||
} |
|||
|
|||
public async virtual Task<PagedResultDto<OpenIddictAuthorizationDto>> GetListAsync(OpenIddictAuthorizationGetListInput input) |
|||
{ |
|||
var queryable = await Repository.GetQueryableAsync(); |
|||
if (input.ClientId.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.ApplicationId == input.ClientId); |
|||
} |
|||
if (input.BeginCreationTime.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.CreationTime >= input.BeginCreationTime); |
|||
} |
|||
if (input.EndCreationTime.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.CreationTime <= input.BeginCreationTime); |
|||
} |
|||
if (!input.Status.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Status == input.Status); |
|||
} |
|||
if (!input.Type.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Type == input.Type); |
|||
} |
|||
if (!input.Subject.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Subject == input.Subject); |
|||
} |
|||
if (!input.Filter.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Subject.Contains(input.Filter) || |
|||
x.Status.Contains(input.Filter) || x.Type.Contains(input.Filter) || |
|||
x.Scopes.Contains(input.Filter) || x.Properties.Contains(input.Filter)); |
|||
} |
|||
queryable = queryable |
|||
.OrderBy(input.Sorting ?? $"{nameof(OpenIddictAuthorization.CreationTime)} DESC") |
|||
.PageBy(input.SkipCount, input.MaxResultCount); |
|||
|
|||
var totalCount = await AsyncExecuter.CountAsync(queryable); |
|||
var entites = await AsyncExecuter.ToListAsync(queryable); |
|||
|
|||
return new PagedResultDto<OpenIddictAuthorizationDto>(totalCount, |
|||
entites.Select(entity => entity.ToDto(JsonSerializer)).ToList()); |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.OpenIddict.Authorizations; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Authorizations; |
|||
|
|||
internal static class OpenIddictAuthorizationExtensions |
|||
{ |
|||
public static OpenIddictAuthorizationDto ToDto(this OpenIddictAuthorization entity, IJsonSerializer jsonSerializer) |
|||
{ |
|||
if (entity == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var dto = new OpenIddictAuthorizationDto |
|||
{ |
|||
Id = entity.Id, |
|||
ApplicationId = entity.ApplicationId, |
|||
CreationDate = entity.CreationDate, |
|||
CreationTime = entity.CreationTime, |
|||
CreatorId = entity.CreatorId, |
|||
LastModificationTime = entity.LastModificationTime, |
|||
LastModifierId = entity.LastModifierId, |
|||
Properties = jsonSerializer.DeserializeToDictionary<string, string>(entity.Properties), |
|||
Scopes = jsonSerializer.DeserializeToList<string>(entity.Scopes), |
|||
Status = entity.Status, |
|||
Subject = entity.Subject, |
|||
Type = entity.Type |
|||
}; |
|||
|
|||
foreach (var extraProperty in entity.ExtraProperties) |
|||
{ |
|||
dto.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return dto; |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System.Threading; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.OpenIddict.Localization; |
|||
using Volo.Abp.Threading; |
|||
using Volo.Abp.Json; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
public abstract class OpenIddictApplicationServiceBase : ApplicationService |
|||
{ |
|||
protected IJsonSerializer JsonSerializer => LazyServiceProvider.LazyGetRequiredService<IJsonSerializer>(); |
|||
protected ICancellationTokenProvider CancellationTokenProvider => LazyServiceProvider.LazyGetRequiredService<ICancellationTokenProvider>(); |
|||
protected OpenIddictApplicationServiceBase() |
|||
{ |
|||
LocalizationResource = typeof(AbpOpenIddictResource); |
|||
} |
|||
|
|||
protected virtual CancellationToken GetCancellationToken() |
|||
{ |
|||
return CancellationTokenProvider.FallbackToProvider(); |
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
using LINGYUN.Abp.OpenIddict.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.OpenIddict.Scopes; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Scopes.Default)] |
|||
public class OpenIddictScopeAppService : OpenIddictApplicationServiceBase, IOpenIddictScopeAppService |
|||
{ |
|||
protected IOpenIddictScopeRepository Repository { get; } |
|||
|
|||
public OpenIddictScopeAppService(IOpenIddictScopeRepository repository) |
|||
{ |
|||
Repository = repository; |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Scopes.Create)] |
|||
public async virtual Task<OpenIddictScopeDto> CreateAsync(OpenIddictScopeCreateDto input) |
|||
{ |
|||
if (await Repository.FindByNameAsync(input.Name) != null) |
|||
{ |
|||
throw new BusinessException(OpenIddictApplicationErrorCodes.Scopes.NameExisted) |
|||
.WithData(nameof(OpenIddictScope.Name), input.Name); |
|||
} |
|||
|
|||
var scope = new OpenIddictScope(GuidGenerator.Create()); |
|||
scope = input.ToEntity(scope, JsonSerializer); |
|||
|
|||
scope = await Repository.InsertAsync(scope); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return scope.ToDto(JsonSerializer); |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Scopes.Delete)] |
|||
public async virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
await Repository.DeleteAsync(id); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
public async virtual Task<OpenIddictScopeDto> GetAsync(Guid id) |
|||
{ |
|||
var scope = await Repository.GetAsync(id); |
|||
|
|||
return scope.ToDto(JsonSerializer); |
|||
} |
|||
|
|||
public async virtual Task<PagedResultDto<OpenIddictScopeDto>> GetListAsync(OpenIddictScopeGetListInput input) |
|||
{ |
|||
var totalCount = await Repository.GetCountAsync(input.Filter); |
|||
var entites = await Repository.GetListAsync(input.Sorting, input.SkipCount, input.MaxResultCount, input.Filter); |
|||
|
|||
return new PagedResultDto<OpenIddictScopeDto>(totalCount, |
|||
entites.Select(entity => entity.ToDto(JsonSerializer)).ToList()); |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Scopes.Update)] |
|||
public async virtual Task<OpenIddictScopeDto> UpdateAsync(Guid id, OpenIddictScopeUpdateDto input) |
|||
{ |
|||
var scope = await Repository.GetAsync(id); |
|||
|
|||
if (!string.Equals(scope.Name, input.Name) && |
|||
await Repository.FindByNameAsync(input.Name) != null) |
|||
{ |
|||
throw new BusinessException(OpenIddictApplicationErrorCodes.Scopes.NameExisted) |
|||
.WithData(nameof(OpenIddictScope.Name), input.Name); |
|||
} |
|||
|
|||
scope = input.ToEntity(scope, JsonSerializer); |
|||
|
|||
scope = await Repository.UpdateAsync(scope); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return scope.ToDto(JsonSerializer); |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
using Volo.Abp; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.OpenIddict.Scopes; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Scopes; |
|||
|
|||
internal static class OpenIddictScopeExtensions |
|||
{ |
|||
public static OpenIddictScope ToEntity(this OpenIddictScopeCreateOrUpdateDto dto, OpenIddictScope entity, IJsonSerializer jsonSerializer) |
|||
{ |
|||
Check.NotNull(dto, nameof(dto)); |
|||
Check.NotNull(entity, nameof(entity)); |
|||
|
|||
entity.Description = dto.Description; |
|||
entity.Descriptions = jsonSerializer.Serialize(dto.Descriptions); |
|||
entity.DisplayName = dto.DisplayName; |
|||
entity.DisplayNames = jsonSerializer.Serialize(dto.DisplayNames); |
|||
entity.Name = dto.Name; |
|||
entity.Properties = jsonSerializer.Serialize(dto.Properties); |
|||
entity.Resources = jsonSerializer.Serialize(dto.Resources); |
|||
|
|||
foreach (var extraProperty in dto.ExtraProperties) |
|||
{ |
|||
entity.ExtraProperties.Remove(extraProperty.Key); |
|||
entity.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return entity; |
|||
} |
|||
|
|||
public static OpenIddictScopeDto ToDto(this OpenIddictScope entity, IJsonSerializer jsonSerializer) |
|||
{ |
|||
if (entity == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var dto = new OpenIddictScopeDto |
|||
{ |
|||
Id = entity.Id, |
|||
CreationTime = entity.CreationTime, |
|||
CreatorId = entity.CreatorId, |
|||
LastModificationTime = entity.LastModificationTime, |
|||
LastModifierId = entity.LastModifierId, |
|||
Description = entity.Description, |
|||
Descriptions = jsonSerializer.DeserializeToDictionary<string, string>(entity.Descriptions), |
|||
DisplayName = entity.DisplayName, |
|||
DisplayNames = jsonSerializer.DeserializeToDictionary<string, string>(entity.DisplayNames), |
|||
Name = entity.Name, |
|||
Properties = jsonSerializer.DeserializeToDictionary<string, string>(entity.Properties), |
|||
Resources = jsonSerializer.DeserializeToList<string>(entity.Resources) |
|||
}; |
|||
|
|||
|
|||
foreach (var extraProperty in entity.ExtraProperties) |
|||
{ |
|||
dto.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return dto; |
|||
} |
|||
} |
|||
@ -0,0 +1,94 @@ |
|||
using LINGYUN.Abp.OpenIddict.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Linq.Dynamic.Core; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.OpenIddict.Tokens; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Tokens; |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Tokens.Default)] |
|||
public class OpenIddictTokenAppService : OpenIddictApplicationServiceBase, IOpenIddictTokenAppService |
|||
{ |
|||
protected IRepository<OpenIddictToken, Guid> Repository { get; } |
|||
|
|||
public OpenIddictTokenAppService(IRepository<OpenIddictToken, Guid> repository) |
|||
{ |
|||
Repository = repository; |
|||
} |
|||
|
|||
[Authorize(AbpOpenIddictPermissions.Tokens.Delete)] |
|||
public async virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
await Repository.DeleteAsync(id); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
} |
|||
|
|||
public async virtual Task<OpenIddictTokenDto> GetAsync(Guid id) |
|||
{ |
|||
var scope = await Repository.GetAsync(id); |
|||
|
|||
return scope.ToDto(); |
|||
} |
|||
|
|||
public async virtual Task<PagedResultDto<OpenIddictTokenDto>> GetListAsync(OpenIddictTokenGetListInput input) |
|||
{ |
|||
var queryable = await Repository.GetQueryableAsync(); |
|||
if (input.ClientId.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.ApplicationId == input.ClientId); |
|||
} |
|||
if (input.BeginCreationTime.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.CreationTime >= input.BeginCreationTime); |
|||
} |
|||
if (input.EndCreationTime.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.CreationTime <= input.BeginCreationTime); |
|||
} |
|||
if (input.BeginExpirationDate.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.ExpirationDate >= input.BeginCreationTime); |
|||
} |
|||
if (input.EndExpirationDate.HasValue) |
|||
{ |
|||
queryable = queryable.Where(x => x.ExpirationDate <= input.BeginCreationTime); |
|||
} |
|||
if (!input.Status.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Status == input.Status); |
|||
} |
|||
if (!input.Type.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Type == input.Type); |
|||
} |
|||
if (!input.Subject.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Subject == input.Subject); |
|||
} |
|||
if (!input.ReferenceId.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.ReferenceId == input.ReferenceId); |
|||
} |
|||
if (!input.Filter.IsNullOrWhiteSpace()) |
|||
{ |
|||
queryable = queryable.Where(x => x.Subject.Contains(input.Filter) || |
|||
x.Status.Contains(input.Filter) || x.Type.Contains(input.Filter) || |
|||
x.Payload.Contains(input.Filter) || x.Properties.Contains(input.Filter) || |
|||
x.ReferenceId.Contains(input.ReferenceId)); |
|||
} |
|||
queryable = queryable |
|||
.OrderBy(input.Sorting ?? $"{nameof(OpenIddictToken.CreationTime)} DESC") |
|||
.PageBy(input.SkipCount, input.MaxResultCount); |
|||
|
|||
var totalCount = await AsyncExecuter.CountAsync(queryable); |
|||
var entites = await AsyncExecuter.ToListAsync(queryable); |
|||
|
|||
return new PagedResultDto<OpenIddictTokenDto>(totalCount, |
|||
entites.Select(entity => entity.ToDto()).ToList()); |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using Volo.Abp; |
|||
using Volo.Abp.OpenIddict.Tokens; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Tokens; |
|||
|
|||
internal static class OpenIddictTokenExtensions |
|||
{ |
|||
public static OpenIddictToken ToEntity(this OpenIddictTokenDto dto, OpenIddictToken entity) |
|||
{ |
|||
Check.NotNull(dto, nameof(dto)); |
|||
Check.NotNull(entity, nameof(entity)); |
|||
|
|||
entity.ApplicationId = dto.ApplicationId; |
|||
entity.AuthorizationId = dto.AuthorizationId; |
|||
entity.CreationDate = dto.CreationDate; |
|||
entity.ExpirationDate = dto.ExpirationDate; |
|||
entity.Payload = dto.Payload; |
|||
entity.Properties = dto.Properties; |
|||
entity.RedemptionDate = dto.RedemptionDate; |
|||
entity.ReferenceId = dto.ReferenceId; |
|||
entity.Status = dto.Status; |
|||
entity.Subject = dto.Subject; |
|||
entity.Type = dto.Type; |
|||
|
|||
foreach (var extraProperty in dto.ExtraProperties) |
|||
{ |
|||
entity.ExtraProperties.Remove(extraProperty.Key); |
|||
entity.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return entity; |
|||
} |
|||
|
|||
public static OpenIddictTokenDto ToDto(this OpenIddictToken entity) |
|||
{ |
|||
if (entity == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var model = new OpenIddictTokenDto |
|||
{ |
|||
Id = entity.Id, |
|||
ApplicationId = entity.ApplicationId, |
|||
AuthorizationId = entity.AuthorizationId, |
|||
CreationDate = entity.CreationDate, |
|||
CreationTime = entity.CreationTime, |
|||
CreatorId = entity.CreatorId, |
|||
LastModificationTime = entity.LastModificationTime, |
|||
LastModifierId = entity.LastModifierId, |
|||
ExpirationDate = entity.ExpirationDate, |
|||
Payload = entity.Payload, |
|||
Properties = entity.Properties, |
|||
RedemptionDate = entity.RedemptionDate, |
|||
ReferenceId = entity.ReferenceId, |
|||
Status = entity.Status, |
|||
Subject = entity.Subject, |
|||
Type = entity.Type |
|||
}; |
|||
|
|||
foreach (var extraProperty in entity.ExtraProperties) |
|||
{ |
|||
model.ExtraProperties.Add(extraProperty.Key, extraProperty.Value); |
|||
} |
|||
|
|||
return model; |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.Json; |
|||
internal static class IJsonSerializerExtensions |
|||
{ |
|||
public static List<TResult> DeserializeToList<TResult>(this IJsonSerializer serializer, string source) |
|||
{ |
|||
if (source.IsNullOrWhiteSpace()) |
|||
{ |
|||
return new List<TResult>(); |
|||
} |
|||
|
|||
return serializer.Deserialize<List<TResult>>(source); |
|||
} |
|||
|
|||
public static Dictionary<TKey, TValue> DeserializeToDictionary<TKey, TValue>(this IJsonSerializer serializer, string source) |
|||
{ |
|||
if (source.IsNullOrWhiteSpace()) |
|||
{ |
|||
return new Dictionary<TKey, TValue>(); |
|||
} |
|||
|
|||
return serializer.Deserialize<Dictionary<TKey, TValue>>(source); |
|||
} |
|||
} |
|||
@ -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,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\dapr\LINGYUN.Abp.Dapr.Client\LINGYUN.Abp.Dapr.Client.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.OpenIddict.Application.Contracts\LINGYUN.Abp.OpenIddict.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,18 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using LINGYUN.Abp.Dapr.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpOpenIddictApplicationContractsModule), |
|||
typeof(AbpDaprClientModule))] |
|||
public class AbpOpenIddictDaprClientModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddStaticDaprClientProxies( |
|||
typeof(AbpOpenIddictApplicationContractsModule).Assembly, |
|||
OpenIddictRemoteServiceConsts.RemoteServiceName); |
|||
} |
|||
} |
|||
@ -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,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.OpenIddict.Application.Contracts\LINGYUN.Abp.OpenIddict.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,18 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpOpenIddictApplicationContractsModule), |
|||
typeof(AbpHttpClientModule))] |
|||
public class AbpOpenIddictHttpApiClientModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddStaticHttpClientProxies( |
|||
typeof(AbpOpenIddictApplicationContractsModule).Assembly, |
|||
OpenIddictRemoteServiceConsts.RemoteServiceName); |
|||
} |
|||
} |
|||
@ -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,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.OpenIddict.Application.Contracts\LINGYUN.Abp.OpenIddict.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,38 @@ |
|||
using Localization.Resources.AbpUi; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.OpenIddict.Localization; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpOpenIddictApplicationContractsModule), |
|||
typeof(AbpAspNetCoreMvcModule))] |
|||
public class AbpOpenIddictHttpApiModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource(typeof(AbpOpenIddictResource), typeof(AbpOpenIddictApplicationContractsModule).Assembly); |
|||
}); |
|||
|
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpOpenIddictHttpApiModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<AbpOpenIddictResource>() |
|||
.AddBaseTypes(typeof(AbpUiResource)); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
using LINGYUN.Abp.OpenIddict.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Applications; |
|||
|
|||
[Controller] |
|||
[Authorize(AbpOpenIddictPermissions.Applications.Default)] |
|||
[RemoteService(Name = OpenIddictRemoteServiceConsts.RemoteServiceName)] |
|||
[Area(OpenIddictRemoteServiceConsts.ModuleName)] |
|||
[Route("api/openiddict/applications")] |
|||
public class OpenIddictApplicationController : OpenIddictControllerBase, IOpenIddictApplicationAppService |
|||
{ |
|||
protected IOpenIddictApplicationAppService Service { get; } |
|||
|
|||
public OpenIddictApplicationController(IOpenIddictApplicationAppService service) |
|||
{ |
|||
Service = service; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public virtual Task<OpenIddictApplicationDto> GetAsync(Guid id) |
|||
{ |
|||
return Service.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual Task<PagedResultDto<OpenIddictApplicationDto>> GetListAsync(OpenIddictApplicationGetListInput input) |
|||
{ |
|||
return Service.GetListAsync(input); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(AbpOpenIddictPermissions.Applications.Create)] |
|||
public virtual Task<OpenIddictApplicationDto> CreateAsync(OpenIddictApplicationCreateDto input) |
|||
{ |
|||
return Service.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
[Authorize(AbpOpenIddictPermissions.Applications.Update)] |
|||
public virtual Task<OpenIddictApplicationDto> UpdateAsync(Guid id, OpenIddictApplicationUpdateDto input) |
|||
{ |
|||
return Service.UpdateAsync(id, input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
[Authorize(AbpOpenIddictPermissions.Applications.Delete)] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return Service.DeleteAsync(id); |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using LINGYUN.Abp.OpenIddict.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.OpenIddict.Authorizations; |
|||
|
|||
[Controller] |
|||
[Authorize(AbpOpenIddictPermissions.Authorizations.Default)] |
|||
[RemoteService(Name = OpenIddictRemoteServiceConsts.RemoteServiceName)] |
|||
[Area(OpenIddictRemoteServiceConsts.ModuleName)] |
|||
[Route("api/openiddict/authorizations")] |
|||
public class OpenIddictAuthorizationController : OpenIddictControllerBase, IOpenIddictAuthorizationAppService |
|||
{ |
|||
protected IOpenIddictAuthorizationAppService Service { get; } |
|||
|
|||
public OpenIddictAuthorizationController(IOpenIddictAuthorizationAppService service) |
|||
{ |
|||
Service = service; |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
[Authorize(AbpOpenIddictPermissions.Authorizations.Delete)] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return Service.DeleteAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public virtual Task<OpenIddictAuthorizationDto> GetAsync(Guid id) |
|||
{ |
|||
return Service.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual Task<PagedResultDto<OpenIddictAuthorizationDto>> GetListAsync(OpenIddictAuthorizationGetListInput input) |
|||
{ |
|||
return Service.GetListAsync(input); |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue