使用.Net Core + Vue + IdentityServer4 + Ocelot 實現一個簡單的DEMO +源碼

来源:https://www.cnblogs.com/lifeng618/archive/2019/08/26/11405281.html
-Advertisement-
Play Games

.Net Core + Vue + IdentityServer4 + Ocelot ...


運行環境

Vue 使用的是D2admin: https://doc.d2admin.fairyever.com/zh/
Github地址:https://github.com/Fengddd/PermissionAdmin.git
Net Core的環境:Webapi 使用的是:NET Core SDK2.1 IdentityServer和Ocelot:NET Core SDK2.2
Github地址:https://github.com/Fengddd/IdentityServerOcelotDemo.git
我也是在初學階段,所以有些地方可能描述的不是很清楚,可以下載源碼查看,也可能大家一起交流,學習

建立IdentityServer4項目


根據 https://www.cnblogs.com/edisonchou/p/identityserver4_foundation_and_quickstart_01.html 根據Edison Zhou大佬的博客,配置好 QuickStart UI 以及IdentityServer的依賴項
新建IdentityServer4的配置文件IdentityConfig

   public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new IdentityResource[]
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResource("delimitClaim","delimitClaim",new List<string>(){ "role", "name"}),  //在Claims添加role 和 name信息
        };
    }     
    public static IEnumerable<ApiResource> GetApiResource()
    {
        return new List<ApiResource>
        {              
            new ApiResource("identityServerApi", "identityServerApi"),
        };
    }
   public static IEnumerable<Client> GetClients()
    {
         new Client
            {                
                ClientId = "js", //客戶端Id
                ClientName = "JavaScript Client", //客戶端名稱
                AllowedGrantTypes = GrantTypes.Code, //授權模式
                //AllowedGrantTypes = GrantTypes.Implicit,
                RequirePkce = true,
                RequireClientSecret = false,
                RequireConsent = false, //禁用 consent 頁面確認                    
                AllowAccessTokensViaBrowser = true,
                AlwaysIncludeUserClaimsInIdToken = true,
                RedirectUris =
                {
                    "http://localhost:8080/#/IdentityServerCallBack",  //登陸後回調頁面 
                    "http://localhost:8080/#/IdentityServerRefreshToken" //刷新Token的頁面
                },
                PostLogoutRedirectUris = { "http://localhost:8080/#/IdentityServerClient" },//註銷退出後跳轉的頁面(登錄頁)                   
                AllowedCorsOrigins = { "http://localhost:8080" }, //跨域
                AccessTokenLifetime = 60, //AccessToken 的有效時間
                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "identityServerApi", //授權的Scopes
                    "delimitClaim" //Claims 信息
                },
                AllowOfflineAccess = true,                  
            }
    }

有時我們需要自定義驗證以及自定義一些Claim的信息,所以需要實現 IProfileService 介面

public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.LogProfileRequest(Logger);
        //判斷是否有請求Claim信息
        if (context.RequestedClaimTypes.Any())
        {
            var userClaims = new List<Claim>
            {
                new Claim("demo1", "測試1"),
                new Claim("demo2", "測試2"),
            };
            List<TestUser> userList = new List<TestUser>()
            {
                new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7896362",Password = "123456",Username="李鋒",Claims = userClaims},
                new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7855555",Password = "123456",Username="張三"},
            };
            TestUserStore userStore = new TestUserStore(userList);
            //根據用戶唯一標識查找用戶信息
            var user = userStore.FindBySubjectId(context.Subject.GetSubjectId());
            if (user != null)
            {
                //調用此方法以後內部會進行過濾,只將用戶請求的Claim加入到 context.IssuedClaims 集合中 這樣我們的請求方便能正常獲取到所需Claim
                context.AddRequestedClaims(user.Claims);
            }
            //context.IssuedClaims=userClaims;
        }
        context.LogIssuedClaims(Logger);
        return Task.CompletedTask;
    }     
    /// <summary>
    /// 驗證用戶是否有效 例如:token創建或者驗證
    /// </summary>
    /// <param name="context">The context.</param>
    /// <returns></returns>
    public virtual Task IsActiveAsync(IsActiveContext context)
    {
        Logger.LogDebug("IsActive called from: {caller}", context.Caller);
        var userClaims = new List<Claim>
        {
            new Claim("demo1", "測試1"),
            new Claim("demo2", "測試2"),
        };
        List<TestUser> userList = new List<TestUser>()
        {
            new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7896362",Password = "123456",Username="李鋒",Claims = userClaims},
            new TestUser(){SubjectId = "cfac01a9-ba15-4678-bccb-cc22d7855555",Password = "123456",Username="張三"},
        };
        TestUserStore userStore = new TestUserStore(userList);
        var user = userStore.FindBySubjectId(context.Subject.GetSubjectId());
        context.IsActive = user?.IsActive == true;
        return Task.CompletedTask;
    }

其中關於Claims的地方這裡做測試所以直接實例出來的數據,這裡可以通過讀取資料庫進行驗證,以及添加Claims的信息
在Startup 的ConfigureServices 註入IdentityServer信息 ,Configure下註冊UseIdentityServer中間件

  services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
            .AddInMemoryApiResources(IdentityConfig.GetApiResource())
            .AddInMemoryClients(IdentityConfig.GetClients())
            //.AddTestUsers(IdentityConfig.GetUsers().ToList())
            .AddProfileService<IdentityProfileService>(); //使用的是Code模式,使用自定義Claims信息
            //.AddResourceOwnerValidator<IdentityResourceOwnerPasswordValidator>();

 app.UseIdentityServer();

然後找到QuickStart中的登錄方法,這裡修改為從資料庫讀取驗證用戶信息

建立Vue項目


安裝依賴項:oidc-client :npm install oidc-client --save axios:npm install axios --save
添加 IdentityServerClient 頁面

添加 IdentityServerCallBack頁面

添加 IdentityServerCallBack頁面

訪問IdentityServerClient 頁面時會自動跳轉到IdentityServer4的登錄頁面,輸入賬號密碼,驗證成功之後,會跳轉到IdentityServerCallBack頁面,然後在IdentityServerCallBack頁面設置路由,跳轉到目標頁面
這裡主要講哈前端的配置,建議看https://www.cnblogs.com/FireworksEasyCool/p/10576911.html教程和oidc-client官方文檔https://github.com/IdentityModel/oidc-client-js/wiki

註意使用:自動刷新Token使用自動刷新Token需要accessTokenExpiringNotificationTime和automaticSilentRenew 一起設置,當AccssToken要過期前:accessTokenExpiringNotificationTime設置的時間,會去請求
IdentityServer4 connect/token介面,刷新Token,請求到Token以後會觸發addUserLoaded事件,我們可以把Token 保存在瀏覽器的緩存中(cookies,localstorage)中,然後在Axios中全局攔截請求,添加headers
信息

Authorization 是token的信息,X-Claims是Claims的信息,傳遞Authorization 是為了IdentityServer 進行驗證授權,X-Claims是為了後面結合Ocelot,攜帶一些Ocelot下游需要的參數進去

建立OcelotGateWay項目


添加Ocelot.json文件

"ReRoutes": [
  {
  "DownstreamPathTemplate": "/api/{url}",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": 44375
    }
  ],
  "UpstreamPathTemplate": "/api/{url}",
  "UpstreamHttpMethod": [ "Get", "Post" ],
  "Priority": 2,
  "AuthenticationOptions": {
    "AuthenticationProviderKey": "IdentityServerKey",
    "AllowScopes": [ "identityServerApi", "delimitClaim" ]
  },
  "RateLimitOptions": {
    "ClientWhiteList": [  //白名單
    ],
    "EnableRateLimiting": true, //啟用限流
    "Period": "1m", 
    "PeriodTimespan": 30,
    "Limit": 5
  },
  "QoSOptions": {
    "ExceptionsAllowedBeforeBreaking": 3,
    "DurationOfBreak": 3000,
    "TimeoutValue": 5000
 }

]
}

AuthenticationOptions 表示認證的信息:IdentityServer4驗證信息,AuthenticationProviderKey 填寫 AddIdentityServerAuthentication 的key 一致,然後配置跨域,註冊中間件

    services.AddAuthentication()
            .AddIdentityServerAuthentication("IdentityServerKey", options =>
            {
                options.Authority = "http://localhost:17491";
                options.ApiName = "identityServerApi";
                options.SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Both;
                options.RequireHttpsMetadata = false;
            });
        services.AddOcelot()
            .AddConsul()
            .AddPolly();
        //配置跨域處理
        services.AddCors(options =>
        {
            options.AddPolicy("any", builder =>
            {
                builder.AllowAnyOrigin() //允許任何來源的主機訪問
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();//指定處理cookie
            });
        });
       //配置Cors
        app.UseCors("any");
        app.UseAuthentication();

Program中添加

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        return WebHost.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddOcelot(hostingContext.HostingEnvironment) //ocelot合併配置文件,不能出現同樣的一個埠,多個路由
                        .AddEnvironmentVariables();
                })
              .UseStartup<Startup>();
    }

學習的資料鏈接,參考資料

Edison Zhou:https://www.cnblogs.com/edisonchou/p/integration_authentication-authorization_service_foundation.html IdentityServer4和ocelot
曉晨Master:https://www.cnblogs.com/stulzq/category/1060023.html IdentityServer4
solenovex :https://www.cnblogs.com/cgzl/tag/identity%20server%204/ IdentityServer4 bibi上還有IdentityServer4視頻喔
滅蒙鳥:https://www.jianshu.com/p/fde63052a3a5 入門教程:JS認證和WebAPI
.Net框架學苑:https://www.cnblogs.com/letyouknowdotnet/category/1481970.html ocelot 一系列教程


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上接(abp(net core)+easyui+efcore實現倉儲管理系統——使用 WEBAPI實現CURD (十四)),在這一篇文章中我們實現更新與刪除供應商的相關功能。 至此,完成了供應商信息的增刪改查,但是我們沒有寫一行與增刪改查有關的c#代碼,都是由ABP提供了AsyncCrudA... ...
  • 最近研究了PIE SDK文本元素的繪製相關內容,因為在我們的開發中,希望可以做到在打開一個Shp文件後,讀取到屬性表的所有欄位,然後可以選擇一些需要的欄位,將這些欄位的所有要素值的文本,繪製到shp圖中相應的要素位置上。 我主要是通過PIE的官方博文(https://www.cnblogs.com/ ...
  • 場景 Winform中DevExpress的TreeList的入門使用教程(附源碼下載): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100075677 https://www.cnblogs.com/badaoliumang ...
  • 客服消息簡介 當用戶和公眾號產生特定動作的交互時(具體動作列表請見下方說明),微信將會把消息數據推送給開發者,開發者可以在一段時間內(目前修改為48小時)調用客服介面,通過POST一個JSON數據包來發送消息給普通用戶。此介面主要用於客服等有人工消息處理環節的功能,方便開發者為用戶提供更加優質的服務 ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
  • 想到了兩種方法來實現,分別利用了List.Sort()和Dictionary.OrderBy()方法,代碼如下: 輸出正常! 總覺得應該有很方便的方法來實現,奈何想不出來。。。 ...
  • 目前知道的情況被調用的C/C++函數只能是全局函數 不能調用類中的成員方法 被調用的C函數必須使用extern “C“包含,保證採用的導出函數名生成規則和.NET一致 函數調用約定通常使用WINAPI也就是__stdcall,.net預設也是__stdcall .net可以和c++同時用cdecl調 ...
  • 場景 Winform控制項-DevExpress18下載安裝註冊以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100061243 在上面安裝完DevExpress的基礎上使用其Treelist控制項。 然後就可以新 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...