Identity Service - 解析微软微服务架构eShopOnContainers(二)

 

上一篇,众所周知一个网站的用户登录是非常重要,一站式的登录(SSO)也成了大家讨论的热点。微软在这个Demo中,把登录单独拉了出来,形成了一个Service,用户的注册、登录、找回密码等都在其中进行。

这套service是基于IdentityServer4开发的, 它是一套基于 .Net Core的OAuth2和OpenID框架,这套框架目前已经很完善了,我们可以把它使用到任何项目中。

我们先看下目录结构:

从目录结构可以看出它是一套MVC架构的网站,我们可以单独进行运行和调试,当然,我们也可以把它放进自己的项目中。

从.Net Core开始,我们看代码的顺序从Web.config转到了Program.cs中,我们来看下IdentityService的Program:

  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. var host = new WebHostBuilder()
  6. .UseKestrel()
  7. .UseHealthChecks("/hc") //多了一个健康检查
  8. .UseContentRoot(Directory.GetCurrentDirectory())
  9. .UseIISIntegration()
  10. .UseStartup<Startup>()
  11. .Build();
  12.  
  13. host.Run();
  14. }
  15. }

跟普通的.Net Core项目类似,不过多了一个UseHealthChecks,从名字上也能看出,这是一个对项目健康的检查,有兴趣的话到时候我们另外开篇介绍。看完Program我们看下Startup

在初始化的时候,我们看到的代码基本与系统相同,多了一个加入builder.AddUserSecrets(), 这是一个用户信息加密方法,避免我们在提交共享项目的时候,会把自己一些重要信息泄露,有兴趣的朋友可以看下Secret Manager Tools

在ConfigureServices中,我们看到有一段代码:

  1. services.AddDataProtection(opts =>
  2. {
  3. opts.ApplicationDiscriminator = "eshop.identity";
  4. });

这段代码意思是加了一个唯一标示符给应用程序,这在集群环境中是非常必要的,我们可以通过这个唯一标识来判断是否是同一个应用(我们的同一应用可能会分布在不同server上),具体可以看园内大神的专题:Asp.Net Core 数据保护

Going Down:

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

又是Health检查,这次检查了与数据库连接的状态。

  1. services.AddTransient<IEmailSender, AuthMessageSender>(); //邮件发送服务
  2. services.AddTransient<ISmsSender, AuthMessageSender>(); //短信发送服务
  3. services.AddTransient<ILoginService<ApplicationUser>, EFLoginService>(); //EF 登录服务
  4. services.AddTransient<IRedirectService, RedirectService>(); //重定向服务
  5.  
  6. //callbacks urls from config:
  7. Dictionary<string, string> clientUrls = new Dictionary<string, string>();
  8. clientUrls.Add("Mvc", Configuration.GetValue<string>("MvcClient"));
  9. clientUrls.Add("Spa", Configuration.GetValue<string>("SpaClient"));
  10. clientUrls.Add("Xamarin", Configuration.GetValue<string>("XamarinCallback"));
  11.  
  12. // Adds IdentityServer
  13. services.AddIdentityServer(x => x.IssuerUri = "null")
  14. .AddSigningCredential(Certificate.Get())
  15. .AddInMemoryApiResources(Config.GetApis())
  16. .AddInMemoryIdentityResources(Config.GetResources())
  17. .AddInMemoryClients(Config.GetClients(clientUrls))
  18. .AddAspNetIdentity<ApplicationUser>()
  19. .Services.AddTransient<IProfileService, ProfileService>();

为identityserver4 进行相关配置。Startup中的Configure没什么特别的。

简单的看了下Identity项目,好像就是教你怎么使用IdentityServer4,So,你可以在博客园中找到好多相关资料,这里就不重复介绍了。

在这个service中,发现了很多没有用到的类和属性,估计是为了以后扩展用的吧。

例如:

  1. var user = await _loginService.FindByUsername(model.Email);
  2. if (await _loginService.ValidateCredentials(user, model.Password))
  3. {
  4. AuthenticationProperties props = null;
  5. if (model.RememberMe)
  6. {
  7. props = new AuthenticationProperties
  8. {
  9. IsPersistent = true,
  10. ExpiresUtc = DateTimeOffset.UtcNow.AddYears(10)
  11. };
  12. };
  13.  
  14. await _loginService.SignIn(user);
  15. // make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint
  16. if (_interaction.IsValidReturnUrl(model.ReturnUrl))
  17. {
  18. return Redirect(model.ReturnUrl);
  19. }
  20.  
  21. return Redirect("~/");
  22. }

这是AccountController用户登录的一段代码,其中的props属性进行了设置,但是在后面没有使用到,因为是为以后支持持续化登录做的准备吧。还有在Services目录中的ProfileService,在项目中也没有进行调用,相信在后面的版本中会加上去的。

运行部署

了解了项目后,我们再来进行运行和部署。

首先,我们需要一台MSSQL Server,因为我们需要保存用户数据,建议用SQL 2008 update3以上,为何用update3以上后面会说,当然你也可以使用其他类型的数据库,比如MySql,Sqlite等。

其次,把Identity项目设置为启动项目,试着Ctrl+F5运行,看看是否运行成功。

当你能在浏览器看到这个页面的时候,说明程序运行正常,配置也正确,接下来看下如何在docker中运行。

1、右键项目-发布,把项目编译发布到某个文件夹中。

2、打开你的终端,如果是win10之前的系统,请打开Docker Quickstart Terminal

我用的是win7,使用的是Quickstart终端,其他系统只要是使用linux container的都一样,否则怎么叫“build once, run anywhere”呢。

3、在终端上先cd到你的发布目录,如果不在同一个驱动器下的,使用 /(driver)/ 代替driver:,例如,我的项目发布在D:\Projects\publish

  1. cd /d/projects/publish

在你的终端看到输入处上一行有这个目录的,说明你已经进入到这个目录了,如:

4、用ls查看下这个目录,你会看到编译后的文件都在这里(release),在文件夹中,你会看到dockerfile文件,这个相当于docker的批处理文件,我们看下内容,具体如何写,可以看博客园中其他大神的教程:

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

5、在终端运行docker build命令,创建你的image(请注意最后的“.”,这个代表的当前目录):

  1. docker build -t identity:01 .

6、成功后,我们使用docker images 可以查看,如果在list中有identity的话,说明我们创建成功了

7、run起来

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

ok,所有操作完毕,可以用我们的浏览器打开,输入http://localhost:8888

撒都没有,撒情况!!!!

通过检查,终于知道了原因,我们使用的docker-toolbox,所以它会借助于VritualBox来创建一个linux运行环境,所以我们必须把虚拟机中的端口映射到我的本机!

想着这下总归可以了吧,谁知道。。。。。还是无法访问,在quickstart中,我输入了docker logs identity 看到如下日志:

这什么鬼,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,终于看到了熟悉的页面:

写在最后

在Identity Service中,我们看到了一些新的东西,比如secret manager tool,healthcheck等,虽说它是基于identityServer4搭建的,但至少它教会了我们如何使用identityServer4,而且我们完全可以单独把它拉出来作为我们自己的user server,我也是第一次接触IdentityServer4,以后大家可以一起学习讨论下,感觉非常强大。最后我们学习了如何单独搭建和部署identity service,并使其能够在docker中正常运行。

Identity Service的更多相关文章

  1. OpenStack (1) - Keystone OpenStack Identity Service

    echo deb http://ubuntu-cloud.archive.canonical.com/ubuntu precise-updates/grizzly main >> /etc ...

  2. Identity Service - 解析微软微服务架构eShopOnContainers(二)

    接上一篇,众所周知一个网站的用户登录是非常重要,一站式的登录(SSO)也成了大家讨论的热点.微软在这个Demo中,把登录单独拉了出来,形成了一个Service,用户的注册.登录.找回密码等都在其中进行 ...

  3. eShopOnContainers 看微服务③:Identity Service

    引言 通常,服务所公开的资源和 API 必须仅限受信任的特定用户和客户端访问.那进行 API 级别信任决策的第一步就是身份认证——确定用户身份是否可靠. 在微服务场景中,身份认证通常统一处理.一般有两 ...

  4. openstack setup demo Identity service

    openstack Identity service 名叫keystone.它提供了用户校验,以及服务目录查询(即列出所有的服务以及相关信息)等功能. keystone 主要包含以下几个部分 Serv ...

  5. 3. Configure the Identity Service

    Controller Node: 安装认证服务: 1. sudo apt-get install keystone   2. sudo vi /etc/keystone/keystone.conf [ ...

  6. Discovering versions from the identity service failed when creating the password plugin.

    If you are behind the proxy, then you have to set no_proxy environmental variable for your localhost ...

  7. Openstack service default port

    Block Storage (cinder) 8776 publicurl and adminurl Compute API (nova-api) 8773 EC2 API 8774 openstac ...

  8. Catalog Service - 解析微软微服务架构eShopOnContainers(三)

    上一篇我们说了Identity Service,因为其基于IdentityServer4开发的,所以知识点不是很多,今天我们来看下Catalog Service,今后的讲解都会把不同的.重点的拿出来讲 ...

  9. Asp.net core Identity + identity server + angular 学习笔记 (第一篇)

    用了很长一段时间了, 但是一直没有做过任何笔记,感觉 identity 太多东西要写了, 提不起劲. 但是时间一久很多东西都记不清了. 还是写一轮吧. 加深记忆. 这是 0-1 的笔记, 会写好多篇. ...

随机推荐

  1. JQuery调用iframe子页面函数/对象的方法

    父页面有个ID为mainfrm的iframe,iframe连接b.html,该页面有个函数test 在父页面调用b.html的test方法为: $("#mainfrm")[0].c ...

  2. linux cpu占用100%排查

    某服务器上部署了若干tomcat实例,即若干垂直切分的Java站点服务,以及若干Java微服务,突然收到运维的CPU异常告警. 问:如何定位是哪个服务进程导致CPU过载,哪个线程导致CPU过载,哪段代 ...

  3. PS 滤镜— —水波效果

    clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorithm'); I=imread ...

  4. Django | 执行项目下指定的脚本

    1 描述 有时候会碰到这样的场景,对于一些业务升级,我需要把数据库数据做些处理,同时又想以 Django 项目的环境变量执行脚本,这个时候使用 python 脚本是再适合不过的手段了. 2 使用自带的 ...

  5. float浮动改变display类型

    position:absolute和float都会隐式的改变display类型. 也就是说,不论之前是什么类型的元素(display:none除外),只要设置了position:absolute或fl ...

  6. VijosP1250:分组背包

    背景 Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了~ 描述 机器人们都想知道谁是最勇敢的,于是它们比赛搬运一些物品. 它们到了一个仓库,里面有n个物品,每个物品都有一个价 ...

  7. POJ1860(ford判环)

    Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24243   Accepted: 881 ...

  8. MYSQL学习二 关于左连接

    工作中有如下的SQL, 针对A.ID ='abcdefg', left  join  B和C两个表,来查找其他信息.就算是B和C中没有任何满足条件的记录,最后结果也肯定不是空.因为A.ID ='abc ...

  9. webSocket 简单介绍

    WebSocket :WebSocket协议支持(在受控环境中运行不受信任的代码的)客户端与(选择加入该代码的通信的)远程主机之间进行全双工通信.                       简单的说 ...

  10. matlab在处理图像时为什么把数据转换为double型?

    1 有些函数支持double型,而不支持uint8的数据类型,所以要转换 2 精度问题了,因为uint8进行数据处理的时候,容易造成数据溢出或精度不够. 为了节省存储空间,matlab为图像提供了特殊 ...