前言
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一下。
