Identity Service - 解析微軟微服務架構eShopOnContainers(二)

来源:http://www.cnblogs.com/inday/archive/2017/05/31/identity-service-eshoponcontainers.html
-Advertisement-
Play Games

接上一篇,眾所周知一個網站的用戶登錄是非常重要,一站式的登錄(SSO)也成了大家討論的熱點。微軟在這個Demo中,把登錄單獨拉了出來,形成了一個Service,用戶的註冊、登錄、找回密碼等都在其中進行。這套service是基於IdentityServer4開發的, 它是一套基於 .Net Core的... ...


上一篇,眾所周知一個網站的用戶登錄是非常重要,一站式的登錄(SSO)也成了大家討論的熱點。微軟在這個Demo中,把登錄單獨拉了出來,形成了一個Service,用戶的註冊、登錄、找回密碼等都在其中進行。

這套service是基於IdentityServer4開發的, 它是一套基於 .Net Core的OAuth2和OpenID框架,這套框架目前已經很完善了,我們可以把它使用到任何項目中。

我們先看下目錄結構:

image

從目錄結構可以看出它是一套MVC架構的網站,我們可以單獨進行運行和調試,當然,我們也可以把它放進自己的項目中。

從.Net Core開始,我們看代碼的順序從Web.config轉到了Program.cs中,我們來看下IdentityService的Program:

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseHealthChecks("/hc") //多了一個健康檢查
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}
跟普通的.Net Core項目類似,不過多了一個UseHealthChecks,從名字上也能看出,這是一個對項目健康的檢查,有興趣的話到時候我們另外開篇介紹。看完Program我們看下Startup

在初始化的時候,我們看到的代碼基本與系統相同,多了一個加入builder.AddUserSecrets(), 這是一個用戶信息加密方法,避免我們在提交共用項目的時候,會把自己一些重要信息泄露,有興趣的朋友可以看下Secret Manager Tools

在ConfigureServices中,我們看到有一段代碼:

services.AddDataProtection(opts =>
{
    opts.ApplicationDiscriminator = "eshop.identity";
});

這段代碼意思是加了一個唯一標示符給應用程式,這在集群環境中是非常必要的,我們可以通過這個唯一標識來判斷是否是同一個應用(我們的同一應用可能會分佈在不同server上),具體可以看園內大神的專題:Asp.Net Core 數據保護

Going Down:

services.AddHealthChecks(checks =>
{
    var minutes = 1;
    if (int.TryParse(Configuration["HealthCheck:Timeout"], out var minutesParsed))
    {
        minutes = minutesParsed;
    }
    checks.AddSqlCheck("Identity_Db", Configuration.GetConnectionString("DefaultConnection"), TimeSpan.FromMinutes(minutes));
});

又是Health檢查,這次檢查了與資料庫連接的狀態。

services.AddTransient<IEmailSender, AuthMessageSender>();   //郵件發送服務
services.AddTransient<ISmsSender, AuthMessageSender>();     //簡訊發送服務
services.AddTransient<ILoginService<ApplicationUser>, EFLoginService>();    //EF 登錄服務
services.AddTransient<IRedirectService, RedirectService>(); //重定向服務

//callbacks urls from config:
Dictionary<string, string> clientUrls = new Dictionary<string, string>();
clientUrls.Add("Mvc", Configuration.GetValue<string>("MvcClient"));
clientUrls.Add("Spa", Configuration.GetValue<string>("SpaClient"));
clientUrls.Add("Xamarin", Configuration.GetValue<string>("XamarinCallback"));

// Adds IdentityServer
services.AddIdentityServer(x => x.IssuerUri = "null")
    .AddSigningCredential(Certificate.Get())
    .AddInMemoryApiResources(Config.GetApis())
    .AddInMemoryIdentityResources(Config.GetResources())
    .AddInMemoryClients(Config.GetClients(clientUrls))
    .AddAspNetIdentity<ApplicationUser>()
    .Services.AddTransient<IProfileService, ProfileService>();

為identityserver4 進行相關配置。Startup中的Configure沒什麼特別的。

簡單的看了下Identity項目,好像就是教你怎麼使用IdentityServer4,So,你可以在博客園中找到好多相關資料,這裡就不重覆介紹了。

在這個service中,發現了很多沒有用到的類和屬性,估計是為了以後擴展用的吧。

例如:

var user = await _loginService.FindByUsername(model.Email);
if (await _loginService.ValidateCredentials(user, model.Password))
{
    AuthenticationProperties props = null;
    if (model.RememberMe)
    {
        props = new AuthenticationProperties
        {
            IsPersistent = true,
            ExpiresUtc = DateTimeOffset.UtcNow.AddYears(10)
        };
    };

    await _loginService.SignIn(user);
    // make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint
    if (_interaction.IsValidReturnUrl(model.ReturnUrl))
    {
        return Redirect(model.ReturnUrl);
    }

    return Redirect("~/");
}

這是AccountController用戶登錄的一段代碼,其中的props屬性進行了設置,但是在後面沒有使用到,因為是為以後支持持續化登錄做的準備吧。還有在Services目錄中的ProfileService,在項目中也沒有進行調用,相信在後面的版本中會加上去的。

運行部署

瞭解了項目後,我們再來進行運行和部署。

首先,我們需要一臺MSSQL Server,因為我們需要保存用戶數據,建議用SQL 2008 update3以上,為何用update3以上後面會說,當然你也可以使用其他類型的資料庫,比如MySql,Sqlite等。

其次,把Identity項目設置為啟動項目,試著Ctrl+F5運行,看看是否運行成功。

afdd4fc5-de60-4ac6-ba1e-32bf2a776271

當你能在瀏覽器看到這個頁面的時候,說明程式運行正常,配置也正確,接下來看下如何在docker中運行。

1、右鍵項目-發佈,把項目編譯發佈到某個文件夾中。

2、打開你的終端,如果是win10之前的系統,請打開Docker Quickstart Terminal

我用的是win7,使用的是Quickstart終端,其他系統只要是使用linux container的都一樣,否則怎麼叫“build once, run anywhere”呢。

3、在終端上先cd到你的發佈目錄,如果不在同一個驅動器下的,使用 /(driver)/ 代替driver:,例如,我的項目發佈在D:\Projects\publish

    cd /d/projects/publish

在你的終端看到輸入處上一行有這個目錄的,說明你已經進入到這個目錄了,如:

image

4、用ls查看下這個目錄,你會看到編譯後的文件都在這裡(release),在文件夾中,你會看到dockerfile文件,這個相當於docker的批處理文件,我們看下內容,具體如何寫,可以看博客園中其他大神的教程:

FROM microsoft/aspnetcore:1.1
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "Identity.API.dll"]

5、在終端運行docker build命令,創建你的image(請註意最後的“.”,這個代表的當前目錄):

docker build -t identity:01 .

6、成功後,我們使用docker images 可以查看,如果在list中有identity的話,說明我們創建成功了

7、run起來

docker run -p 8888:80 --name identity -d identity:01

ok,所有操作完畢,可以用我們的瀏覽器打開,輸入http://localhost:8888

imageimage

撒都沒有,撒情況!!!!

通過檢查,終於知道了原因,我們使用的docker-toolbox,所以它會藉助於VritualBox來創建一個linux運行環境,所以我們必須把虛擬機中的埠映射到我的本機!

d01f9762-76dd-45a4-82f3-a79f54b40718

想著這下總歸可以了吧,誰知道。。。。。還是無法訪問,在quickstart中,我輸入了docker logs identity 看到如下日誌:

image

這什麼鬼,time out!!可我iis運行都是正常的啊,不存在資料庫連接不上的問題吧!這個問題足足困擾了我2天,晚上也睡不好,第3天早上,突然想到會不會linux容器的關係呢?之前google的都是錯誤信息,所以撒都沒有搜出來,我改了下關鍵字 linux containers connection sqlserver,果不其然,在一個issue中發現了答案:

https://github.com/aspnet/EntityFramework/issues/4702#issuecomment-193382793

原來我們的sql2008沒有支持這種登錄request,我們必須升級到update3才能解決這個問題,為了讓教程繼續,我購買了azure的1元試用,更換了connection後,我重新build和run,終於看到了熟悉的頁面:

image


寫在最後

在Identity Service中,我們看到了一些新的東西,比如secret manager tool,healthcheck等,雖說它是基於identityServer4搭建的,但至少它教會了我們如何使用identityServer4,而且我們完全可以單獨把它拉出來作為我們自己的user server,我也是第一次接觸IdentityServer4,以後大家可以一起學習討論下,感覺非常強大。最後我們學習瞭如何單獨搭建和部署identity service,並使其能夠在docker中正常運行。

PS:最近工作不是很忙,所以有些時間去研究這些,如果中途斷檔的話,還請大家見諒!

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

-Advertisement-
Play Games
更多相關文章
  • 今天在研究C#代碼問題的時候遇到了一個Visual Studio的小問題。在Visual Studio 2013中,使用Find All References功能不能找到同一類型不同版本的所有引用,具體情況請見下麵例子。 為了更方便的展示這個問題,我寫了兩段小代碼測試。如下圖,TestFindAll ...
  • var lst = new List<ModelTest>(); lst.Add(new ModelTest() { Code = "1", Name = "一" }); lst.Add(new ModelTest() { Code = "2", Name = "二" }); lst.Add(new ...
  • 最近項目上要用到跑馬燈的效果,和網上不太相同的是,網上大部分都是連續的,而我們要求的是不連續的。 也就是是,界面上就展示4項(展示項數可變),如果有7項要展示的話,則不斷的在4個空格裡左跳,當然,銜接上效果不是很好看。 然後,需要支持點擊以後進行移除掉不再顯示的內容。 效果如下: 思路大致如下: 1 ...
  • jlink 如何 離開 keil、IAR 監控變數呢? 目前 jlink的 api 可以做到,自己可以用C# 做一個 上位機,監控RAM裡面的變數。而不用打開keil 調試。還可以 刷寫 flash,可以用在產品量產的刷寫上。 SEGGER 的 jlink sdk並不是免費的,在調試API 過程中, ...
  • 最近在做一個資源對接項目,對方的介面中要求我們把文件的md5值傳過去,搜了一下找到這個方法,記錄之。 ...
  • 一、目標樣式 我們要實現上圖中的效果,需要如下的操作: 二、資源分享代碼 註:Client.Share.SendURL("URL地址") 分享文本:Client.Share.SendText("文本") 分享圖片:Client.Share.SendImage("圖片") 分享截屏:Client.Sh ...
  • 在angularjs中,想在文本框中,驗證用戶輸入的字元串是否為日期時間。剛開始時,Insus.NET想到的是正則,這隻是驗證到日期與時間的格式是否正確而已,而對於2月最後一天或是30或是31號,還是無能為力。 因此,Insus.NET想使用angularjs的自定義指令來驗證解決此問題。在ASP. ...
  • 1,這是因為用線程式控制制子窗體,刷新數據的時候會影響主窗體,因為主次窗體是以 Main man = new Main(); man.ShowDialog();形式存在 2,解決辦法: 新建公共類,Bool屬性並賦值,在需要調用刷新數據方法地方通過給刷新數據的方法套一個事件,在通過Timer 控制項結束當 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...