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

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 接上一篇,众所周知一个网站的用户登录是非常重要,一站式的登录(SSO)也成了大家讨论的热点。微软在这个Demo中,把登录单独拉了出来,形成了一个Service,用户的注册、登录、找回密码等都在其中进行。

上一篇,众所周知一个网站的用户登录是非常重要,一站式的登录(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:最近工作不是很忙,所以有些时间去研究这些,如果中途断档的话,还请大家见谅!

相关文章
|
1天前
|
消息中间件 监控 API
构建高效微服务架构是后端开发的关键
【5月更文挑战第22天】构建高效微服务架构是后端开发的关键,涉及核心原则如服务独立、去中心化、自治和轻量级通信。优势包括可扩展性、独立性、技术灵活性和团队协作。最佳实践包括恰当的服务拆分、选择RESTful API、RPC或消息队列进行通信、处理数据一致性和分布式事务、实施服务治理与监控,以及确保安全性与权限控制。随着技术进步,未来将探索服务网格、容器化和云原生技术,以提升微服务架构的效能和适应性。
9 0
|
2天前
|
消息中间件 安全 数据管理
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第21天】 在现代软件开发的浪潮中,微服务架构已经成为一种流行且有效的解决方案。它通过将复杂的应用拆分成一组小服务来增强系统的可维护性、扩展性和技术多样性。本文深入探讨了构建高效微服务架构的关键要素,包括服务划分原则、通信机制、数据管理以及安全性考量。通过对这些核心组件的分析,我们将揭示如何优化后端开发流程,以适应快速变化的市场需求和技术演进。
|
2天前
|
消息中间件 设计模式 开发者
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第21天】 在快速迭代的软件开发领域,微服务架构已经成为支持复杂应用和持续交付的关键设计模式。本文将深入探索微服务的核心原则、技术栈选择以及它们如何影响现代后端开发流程。通过分析微服务的设计理念和最佳实践,我们将了解如何构建一个既灵活又高效的系统,以应对不断变化的业务需求和技术挑战。
|
2天前
|
消息中间件 数据管理 持续交付
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第21天】 随着企业应用的复杂性不断增长,传统的单体应用已难以满足快速迭代和灵活部署的需求。微服务架构作为解决方案,其优势在于模块化设计、独立部署和可扩展性,为后端开发带来了新的思路和方法。本文将探讨如何构建高效的微服务架构,涵盖关键组件的选择、网络通信机制、数据管理策略以及持续集成与持续部署(CI/CD)的实践。我们的目标是为后端开发者提供一套可行的技术指南,帮助他们在面对不断变化的业务需求时,能够设计出既稳定又灵活的服务架构。
|
2天前
|
消息中间件 监控 数据管理
构建高效微服务架构:从理论到实践
【5月更文挑战第21天】 在现代软件开发的浪潮中,微服务架构已成为企业追求敏捷开发、持续交付和系统弹性的关键解决方案。本文深入探讨了构建一个高效微服务架构的核心原则与实践策略,旨在为开发者提供一个清晰的指南,帮助他们在设计分布式系统时做出明智的决策。我们将从微服务的基本概念出发,逐步展开对关键组件、通信机制和数据管理的讨论,并分享实际案例分析以验证理论的有效性。
|
2天前
|
缓存 负载均衡 数据库
构建高性能微服务架构:策略与实践
【5月更文挑战第21天】 随着现代业务需求的不断演进,传统的单体应用架构已难以满足快速迭代和灵活部署的要求。微服务架构应运而生,以其服务的细粒度、独立性和弹性优势成为企业转型的重要选择。本文将深入探讨如何构建一个高性能的微服务系统,从服务划分原则到性能优化技巧,旨在为开发者提供一套系统的微服务性能提升方案。文章将重点讨论在设计高并发、低延迟的微服务时需要考虑的关键因素,包括服务治理、缓存策略、负载均衡以及异步通信机制等。
|
2天前
|
消息中间件 监控 持续交付
构建高效微服务架构:后端开发的新范式
【5月更文挑战第21天】在现代软件开发的浪潮中,微服务架构已经成为了实现业务敏捷性、可扩展性和技术多样性的关键。本文将探讨构建一个高效微服务架构的最佳实践,包括服务划分原则、通信机制、数据一致性以及服务的监控与维护。通过这些实践,后端开发者能够更好地应对复杂系统的开发挑战,同时保持系统的灵活性和稳定性。
|
2天前
|
存储 Kubernetes 开发者
构建高效微服务架构:后端开发者的终极指南
【5月更文挑战第21天】随着现代软件开发的不断演进,微服务架构已成为实现可扩展、灵活和容错系统的关键。本文将深入探讨微服务的核心概念、设计原则以及如何利用最佳实践构建一个高效的微服务系统。我们将分析微服务的优势与挑战,并展示如何在现实世界中应用这些知识来优化后端应用程序的性能和可靠性。
|
3天前
|
监控 测试技术 持续交付
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第20天】 随着企业级应用的复杂度日益增加,微服务架构已成为解决传统单体应用弊端、实现敏捷开发和部署的关键。本文将深入探讨构建高效微服务架构的策略与实践,涉及核心组件的选择、服务划分原则、以及持续集成/持续部署(CI/CD)流程的优化。通过分析具体案例,我们将展示如何在保证系统稳定性的同时,提高系统的可扩展性、可维护性和技术栈的多样性。文章不仅适用于正在考虑转型至微服务架构的团队,也为寻求提升现有微服务性能的开发者提供参考。
|
3天前
|
运维 监控 负载均衡
探索微服务架构下的服务网格
【5月更文挑战第20天】 在当今日益复杂的分布式系统中,微服务架构已成为企业技术栈的重要组成部分。随着微服务数量的膨胀和网络通信的复杂化,传统的服务发现与负载均衡机制显得力不从心。本文将深入探讨服务网格这一新兴模式,它如何在微服务环境中提供更灵活、动态且高效的服务间通信解决方案。我们将剖析服务网格的核心组件、工作原理以及它如何简化分布式系统的运维难题。

推荐镜像

更多