用户打开登录界面,输入用户名密码先行登录,服务端先行校验用户名密码是否有效,有效则返回用户实例(User),这时进入认证准备阶段,根据用户实例携带的身份信息(Claim),创建身份证(ClaimsIdentity),然后将身份证交给身份证持有者(ClaimsPrincipal)持有。接下来进入真正的认证阶段,根据配置的认证方案(IAuthenticationScheme),使用相对应的认证处理器(IAuthenticationHandler)进行认证 。认证成功后发放授权令牌(AuthorizationToken)。该授权令牌包含后续授权阶段需要的全部信息。
授权流程简介授权就是对于用户身份信息(Claims)的验证,,授权又分以下几种种:
基于Role的授权
基于Scheme的授权
基于Policy的授权
授权主要与以下几个核心对象打交道:
IAuthorizationRequirement(授权条件)
IAuthorizationService(授权服务)
AuthorizationPolicy(授权策略)
IAuthorizationHandler (授权处理器)
AuthorizationResult(授权结果)
那授权流程是怎样的呢?
当收到授权请求后,由授权服务(IAuthorizationService)根据资源上指定的授权策略(AuthorizationPolicy)中包含的授权条件(IAuthorizationRequirement),找到相对应的授权处理器(IAuthorizationHandler )来判断授权令牌中包含的身份信息是否满足授权条件,并返回授权结果。
中间件集成简单了解了下认证和授权流程后,我们来了解Identity microservice是如何集成相关中间件的。
1. 首先是映射自定义扩展的User和Role // 映射自定义的User,Role services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>()//配置使用EF持久化存储 .AddDefaultTokenProviders();//配置默认的TokenProvider用于变更密码和修改email时生成Token 2. 配置IdentityServer服务 // Adds IdentityServer services.AddIdentityServer(x => { x.IssuerUri = "null"; x.Authentication.CookieLifetime = TimeSpan.FromHours(2); }) .AddSigningCredential(Certificate.Get()) .AddAspNetIdentity<ApplicationUser>() .AddConfigurationStore(options => { options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sqlServerOptionsAction: sqlOptions => { sqlOptions.MigrationsAssembly(migrationsAssembly); //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }); }) .AddOperationalStore(options => { options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString, sqlServerOptionsAction: sqlOptions => { sqlOptions.MigrationsAssembly(migrationsAssembly); //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }); }) .Services.AddTransient<IProfileService, ProfileService>();IdentityServer默认直接在内存中存储配置数据(客户端和资源)和操作数据(令牌,代码和和用户的授权信息consents)。这显然在生产环境是不合适的,如果服务所在主机宕机,那么内存中的数据就会丢失,所以有必要持久化到数据库。
其中AddConfigurationStore和AddOperationalStore扩展方法就是用来来指定配置数据和操作数据基于EF进行持久化。
从已知的体系结构来说,我们需要预置Client和Resource:
Client
public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl) { return new List<Client> { // SPA OpenId Client Client(Implicit) new Client // Xamarin Client(Hybrid) new Client // MVC Client(Hybrid) new Client // MVC TEST Client(Hybrid) new Client // Locations Swagger UI(Implicit) new Client // Marketing Swagger UI(Implicit) new Client // Basket Swagger UI(Implicit) new Client // Ordering Swagger UI(Implicit) new Client // Mobile Shopping Aggregattor Swagger UI(Implicit) new Client // Web Shopping Aggregattor Swagger UI(Implicit) new Client }; }