在項目中自定義集成IdentityService4

来源:https://www.cnblogs.com/queque/archive/2022/06/01/16326873.html
-Advertisement-
Play Games

OAuth2.0協議 在開始之前呢,需要我們對一些認證授權協議有一定的瞭解。 OAuth 2.0 的一個簡單解釋 http://www.ruanyifeng.com/blog/2019/04/oauth_design.html 理解 OAuth 2.0 https://www.ruanyifeng. ...


OAuth2.0協議

在開始之前呢,需要我們對一些認證授權協議有一定的瞭解。

OAuth 2.0 的一個簡單解釋
http://www.ruanyifeng.com/blog/2019/04/oauth_design.html

理解 OAuth 2.0
https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

GitHub OAuth 第三方登錄示例教程
http://www.ruanyifeng.com/blog/2019/04/github-oauth.html

IdentityService4 配置說明

當然,前提是我希望你已經對一些官方示例進行了實踐,如果沒有,下麵鏈接中有中文的案例演示

http://www.identityserver.com.cn/

在官方文檔中我們可以在導航欄看到一些配置項,其實常用的只有Client這一項

https://identityserver4.readthedocs.io/en/latest/index.html

開始操作

先簡單概述一下我們需要做的事情:

1、存儲IdentityService4配置信息
2、存儲用戶數據 (採用ASP.NET Core Identity)

針對上面兩項,官方都有實現,都有針對各自的案例,我們只需要做一個簡單的集合,按需集合進項目中。

建立一個空web項目

.NET Core 版本不做要求 3.1、 5.0、 6.0 都可以實現 ,需要註意的是6.0版本的IdentityService4已經沒有升級了,有一些Nuget包可能是過時的,當出現時,根據提示改為自己需要的版本即可。

我個人喜歡建立MVC,因為方便,中間件都有,懶得一個個引用了

添加所需NuGet包

Startup.cs文件中註冊Identity

// 配置cookie策略 (此配置下方會講解)
builder.Services.Configure<CookiePolicyOptions>(options =>
{
    //讓IdentityService4框架在http的情況下可以寫入cookie
    options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
});
//註冊Identity
//IdentityDB遷移命令
//Add-Migration InitialIAspNetIdentityConfigurationDbMigration -c ApplicationDbContext -o Data/Migrations/AspNetIdentity
builder.Services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(configuration.GetConnectionString("IdentityDb"), sql => sql.MigrationsAssembly(migrationsAssembly)));
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
    //密碼配置
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequireDigit = false;
    options.Password.RequiredLength = 6;
    options.Password.RequireUppercase = false;
})
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

用的是SqlServer,如若使用MySQL替換Nuget包即可,Oracle有點特殊,自行探索,太麻煩就不說了
ApplicationUser 、ApplicationRole 是我自定義擴展Identity的用戶和角色,這我就不多說了,用過Identity的都知道

Startup.cs文件中註冊IdentityService4

IdentityService4用了兩個DbContext,一個存儲配置信息,一個存儲操作信息

//註冊ID4
builder.Services.AddIdentityServer()
                   .AddConfigurationStore(options =>
                   {
                       //Add-Migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
                       options.ConfigureDbContext = b => b.UseSqlServer(configuration.GetConnectionString("IdentityDb"), sql => sql.MigrationsAssembly(migrationsAssembly));
                   })
                   .AddOperationalStore(options =>
                   {
                       //Add-Migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
                       options.ConfigureDbContext = b => b.UseSqlServer(configuration.GetConnectionString("IdentityDb"), sql => sql.MigrationsAssembly(migrationsAssembly));
                   })
                   .AddAspNetIdentity<ApplicationUser>()
                   .AddDeveloperSigningCredential(true);

在授權中間件前,引入IdentityService4中間件

資料庫遷移

此處需要將Identity的Dbcontext上下文,和IdentityService4的兩個DbContext上下文 遷移進資料庫中,遷移命令上面已有,執行即可。

//IdentityDB遷移命令
//Add-Migration InitialIAspNetIdentityConfigurationDbMigration -c ApplicationDbContext -o Data/Migrations/AspNetIdentity

//Add-Migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb

//Add-Migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb

添加自定義所需的頁面(登錄、註冊等)

這些頁面來自官方免費的管理UI、或者Identity,代碼在源碼中,自行拷貝即可

如需其他功能頁面,按需從官方Copy即可

添加測試種子數據

此處代碼太多,自行去源碼查看,講一下原理:

將IdentityService的Client、Scope等配置信息存儲到資料庫中 , 初始化用戶、角色 信息

編譯運行,不報錯,成功!

校驗一下

在當前項目新增一個Api控制器,返回當前Token所包含的聲明信息

註意紅色部分,需要我們添加jwt認證

添加Jwt身份認證

我們在上面註冊服務時,IS4預設使用的是Cookie認證

所以在添加JwtBearer認證

string identityServerUrl = configuration["Perfect:Identity:Url"]; //當前項目地址
            //添加jwt認證方案
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                  .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
                  {
                      options.Authority = identityServerUrl;
                      options.RequireHttpsMetadata = false;
                      options.TokenValidationParameters.ValidateAudience = false;
                      options.TokenValidationParameters.ValidateLifetime = true;
                      options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;
                  });

配置swagger認證

先添加一個過濾器

 public class SecurityRequirementsOperationFilter : IOperationFilter
    {
        /// <summary>
        /// Add Security Definitions and Requirements
        /// https://github.com/domaindrivendev/Swashbuckle.AspNetCore#add-security-definitions-and-requirements
        /// </summary>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            bool hasAuthorize = context.MethodInfo.DeclaringType?.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any() == true || context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
            bool hasAllowAnonymous = context.MethodInfo.DeclaringType?.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any() == true || context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Any();

            if (hasAuthorize && !hasAllowAnonymous)
            {
                operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
                operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });

                OpenApiSecurityScheme oAuthScheme = new OpenApiSecurityScheme()
                {
                    Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
                };

                operation.Security = new List<OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        [oAuthScheme] =new []{ "Perfect.Api" }
                    }
                };
            }
        }
    }

在Startup中註冊,客戶端ID、和客戶端密鑰 來自步驟 “添加測試種子數據” 中

 //configuration["xx"]是來自配置文件的取值
 //添加Swagger文檔
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc(configuration["Perfect:Swagger:Name"], new OpenApiInfo
                {
                    Title = configuration["Perfect:Swagger:Title"],
                    Version = configuration["Perfect:Swagger:Version"],
                    Description = configuration["Perfect:Swagger:Description"],
                    Contact = new OpenApiContact
                    {
                        Name = configuration["Perfect:Swagger:Contact:Name"],
                        Email = configuration["Perfect:Swagger:Contact:Email"]
                    }
                });

                c.OperationFilter<SecurityRequirementsOperationFilter>();

                c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.OAuth2,
                    Flows = new OpenApiOAuthFlows
                    {
                        AuthorizationCode = new OpenApiOAuthFlow
                        {
                            AuthorizationUrl = new Uri($"{identityServerUrl}/connect/authorize"),
                            TokenUrl = new Uri($"{identityServerUrl}/connect/token"),
                            Scopes = new Dictionary<string, string>
                            {
                                { "openapi", "介面訪問許可權" },
                            }
                        }
                    }
                });

                 
            });

在中間件管道中使用

app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint(string.Format("/swagger/{0}/swagger.json", configuration["Perfect:Swagger:Name"]), configuration["Perfect:Swagger:Title"]);
                c.OAuthClientId(configuration["Perfect:Swagger:ClientId"]);
                c.OAuthClientSecret(configuration["Perfect:Swagger:ClientSecret"]);
                c.OAuthAppName(configuration["Perfect:Swagger:AppName"]);
                c.OAuthUsePkce();
            });

編譯運行,打開swagger頁面

源碼地址:https://github.com/dreamdocker/zerostack

以上教學來自零度課堂,本人只是分享,無其他意義,開會員記得找我哦!

我自是年少,韶華傾負。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 2018年2月28日Spring Boot進入2.0時代,距今已經超過4年了。 2022 年 11 月 Spring Boot 3.0 將正式發佈,它將基於 Spring Framework 6.0,並且需要 Java 17 或更高版本,同時它也將是Jakarta EE 9的第一個 Spring B ...
  • 快速安裝 pip install matplotlib 折線圖 快速入門 import matplotlib.pyplot as plt import random x=range(10) # 定義x軸的數據 y=[random.uniform(15,35) for i in x] # 定義y軸的數 ...
  • 一、日誌文件輸出說明 日誌目錄: /nchome/nclogs/servername/ ,其中servername集群時目錄類似為master,ncMem01等。非集群時目錄為:server1(服務名) 模塊 輸出格式 說明 anonymous anony-log.log 業務日誌,如果沒有配置模塊 ...
  • 作者:代碼的色彩 鏈接:https://juejin.cn/post/7062662600437268493 1.前言 你是否對大廠展示的五花八門,花花綠綠的架構設計圖所深深吸引,當我們想用幾張圖來介紹下業務系統,是不是對著畫布不知從何下手?作為技術扛把子的筒子們是不是需要一張圖來描述系統,讓系統各 ...
  • 概念 棧(stack)是一種運算受限的線性表。棧只能從末尾插入或刪除數據。我們把這一端稱為棧頂,對應地,把另一端稱為棧底。 隊列(queue)是一種線性表。它允許在表的某一端進行插入操作,在另一端進行刪除操作。我們把進行刪除操作的一端稱作隊列的隊尾,把進行插入操作的一端稱作隊列的隊首。 實現 註:由 ...
  • Liunx安裝Nacos 一,準備安裝包 github下載點 同時請確認Linux已安裝jdk 二,在/usr/local/目錄下創建一個文件夾用於上傳和解壓Nacos cd /usr/local/ #這裡創建文件夾名字可隨意,解壓後會生成一個名為nacos的文件夾,後續會移動至/usr/local ...
  • 最近通過WPF開發項目,為了對WPF知識點進行總結,所以利用業餘時間,開發一個學生信息管理系統【Student Information Management System】。前三篇文章進行了框架搭建和模塊劃分,後臺WebApi介面編寫,以及課程管理模塊開發,本文在前三篇基礎之上,繼續深入開發學生信息... ...
  • 最近在看 C++ 的虛方法調用實現原理,大概就是說在 class 的首位置存放著一個指向 vtable array 指針數組 的指針,而 vtable array 中的每一個指針元素指向的就是各自的 虛方法,實現方式很有意思,哈哈,現在我很好奇 C# 中如何實現的。 一: C# 中的多態玩法 1. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...