Asp.Net Core IdentityServer4 管理面板集成
前言
IdentityServer4(以下简称 Id4) 是 Asp.Net Core 中一个非常流行的 OpenId Connect 和 OAuth 2.0 框架,可以轻松集成到 Asp.Net Core 应用中,并且与 Asp.Net Core Identity 也可以轻松集成。博客园也有大佬发布了很多关于 Id4 的相关文章。比如晓晨Master的系列入门教程:IdentityServer4 中文文档与实战,我也是看他的教程学习入门的,教程基于 .Net Core 2.x,但是影响不大。
但是这个教程还有一个遗憾,没有关于如何管理 Id4 数据的部分,而 Id4 本身的数据模型还是有点小复杂的,直接去改数据库心里发慌,也不是长久之计。Id4 作为开源框架也为商业化留了一手,就是关于 Id4 的管理,需要付费才能获得 Id4 团队准备的管理模块。幸好万能的 Github 上有大神开源了自制的管理模块。其中最著名的应该就是Skoruba.IdentityServer4.Admin了。这个管理模块包含了一些基本包、3个可执行项目(主身份服务器,网页版管理器和 Web Api 版管理器)和一个 VS 解决方案模板。从零开始搭建项目没什么问题,但如果已经有一个包含 Id4 的项目的情况下要怎么办呢?问题就在于要如何把解决方案模板中的管理器项目移花接木到自己的主项目中,在一些情况下,甚至可能需要把管理器直接集成到现有项目。经过一段时间的研究,终于把这个问题搞定了,在此也分享给各位园友。
正文
集成改造过程中,我下载了管理项目源码、创建了模板解决方案用作参考,也 copy 了部分代码到我的主项目中,如果各位需要在我的演示基础上继续改造,也可以提前准备这些代码参考。同时由于原始项目对 AutoMapper 的使用方式与 DI 集成的使用方式冲突,我没有使用内置服务实现,使用了我改造后的服务实现。
接下来简述一下我的改造步骤,由于改造项目持续时间较长,可能有疏漏。可以到文章末尾下载我的项目实际运行体验。
- 在 Startup.ConfigureServices 中注册 AutoMapper,因为我的配置文件分散在不同项目中,写法比较特殊;改造 Id4 的 AutoMapper 相关代码:
AutoMapper.IConfigurationProvider config = new MapperConfiguration(cfg =>
{
var profileTypes =
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.IsSubclassOf(typeof(Profile)) && !type.IsGenericType && !type.IsAbstract
select type;
var profiles = profileTypes.Select(x =>
{
try
{
return (Profile)Activator.CreateInstance(x);
}
catch (MissingMethodException ex)
{
return null;
}
catch(Exception ex)
{
throw ex;
}
}).Where(x => x != null);
cfg.AddProfiles(profiles);
});
services.AddSingleton(config);
services.AddScoped<IMapper, Mapper>();
- Id4 Mappers 的改造思路是去掉内置的 IMapper 实例,让管理服务把注入的 Imapper 作为参数传递给辅助方法。这里以其中一个为例,其他类似的都这么操作。把管理服务中的各种 ToModel() 和 ToEntity() 改成 ToModel(mapper) 和 ToEntity(mapper),别忘了在服务中注入 IMapper,从源码中拷贝服务源码并修改。
public static class PersistedGrantMappers
{
//static PersistedGrantMappers()
//{
// Mapper = new MapperConfiguration(cfg => cfg.AddProfile<PersistedGrantMapperProfile>())
// .CreateMapper();
//}
//internal static IMapper Mapper { get; }
public static PersistedGrantsDto ToModel(this PagedList<PersistedGrantDataView> grant, IMapper mapper)
{
return grant == null ? null : mapper.Map<PersistedGrantsDto>(grant);
}
public static PersistedGrantsDto ToModel(this PagedList<PersistedGrant> grant, IMapper mapper)
{
return grant == null ? null : mapper.Map<PersistedGrantsDto>(grant);
}
public static PersistedGrantDto ToModel(this PersistedGrant grant, IMapper mapper)
{
return grant == null ? null : mapper.Map<PersistedGrantDto>(grant);
}
}
- 对比模板项目代码和自己项目代码进行融合,比如复制控制器、视图、js脚本、css样式、resx资源等各种新增文件,修改 Startup 注册 Id4 管理的各种代码,引入 TagHelper 等修改文件。这个部分就是需要耐心和细心,没什么技术含量。注意把注册服务的代码改成注册改造后的服务实现。根据需要改造视图等等。代码比较分散,就不贴了,有兴趣的朋友去我的项目中看吧。
效果预览
地址为:https://localhost:5001/IdentityServer/ConfigHome
Swagger UI 地址为:https://localhost:5001/swagger/index.html。可以通过点击 Authorize 按钮登录管理账号,完全可视化操作,没有任何难度门槛。注意上面的说明,为不同的登录账号选择对应的 scopes,不然 Id4 会返回授权请求错误。一个 client 请求授权的各种资源和权限必须在 Id4 中提前登记备案,请求的权限和登记备案过的权限不一致会被驳回授权请求。
注意事项
-
Id4 管理模板使用了 resx 管理多语言翻译,和我项目使用的方案不兼容,为此我专门改造了 Asp.Net Core 本地化服务,详情见我的博客:Asp.Net Core 混合全球化与本地化支持。
-
项目中保留了2个融合改造后的独立网页管理项目和 Web Api 管理项目,所以本示例一共包含4个管理入口,分别是集成在主项目中的网页和 Api 端口、独立的网页和 Api 端口。
-
初始账号中所有入口都只有 admin 有权访问 Id4 管理端口,端口已经由 Id4 的初始设置进行保护。所有账号的初始密码为:Pass123$。
结语
完成改造后,才算是完整集成了 Id4 这个框架,永远用教程代码里写死的那些 Client 终归不是长久之计。
转载请完整保留以下内容并在显眼位置标注,未经授权删除以下内容进行转载盗用的,保留追究法律责任的权利!
本文地址:https://www.cnblogs.com/coredx/p/12318135.html
完整源代码:Github
里面有各种小东西,这只是其中之一,不嫌弃的话可以Star一下。