增加验证服务
1.创建名为AuthService 的core 空项目
2.修改startup文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ConsulRegisterHelper; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace AuthService { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { //注入IdentityServer服务 services.AddIdentityServer() .AddDeveloperSigningCredential()//开发临时证书 .AddInMemoryClients(ApiConfig.GetClients()) .AddInMemoryApiResources(ApiConfig.GetApiResources()) .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()//添加自定义验证 .AddProfileService<ProfileService>(); ; } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer(); app.RegisterConsul(lifetime, new ServiceEntity { IP = NetworkHelper.LocalIPAddress, Port = Convert.ToInt32(Configuration.GetSection("Setting")["Port"]), ServiceName = Configuration.GetSection("Setting")["ServiceName"], ConsulIP = Configuration.GetSection("Setting")["ConsulIP"], ConsulPort = Convert.ToInt32(Configuration.GetSection("Setting")["ConsulPort"]) }); app.Run(async (context) => { await context.Response.WriteAsync("身份验证服务启动成功!"); }); } } }
3.修改Program
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace AuthService { public class Program { public static string StartPort; public static void Main(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true) .Build(); StartPort = config.GetSection("Setting")["Port"]; CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseUrls($"http://*:{StartPort}") .UseStartup<Startup>(); } }
4.增加setting文件节点
"Setting": {
"Port": "7500",
"ServiceName": "authService",
"ConsulIP": "localhost",
"ConsulPort": "8500"
}
5.增加身份验证自定义用户验证相关
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using IdentityServer4.Models; using IdentityServer4.Services; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AuthService { public class ProfileService : IProfileService { public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var claims = context.Subject.Claims.ToList(); context.IssuedClaims = claims.ToList(); } public async Task IsActiveAsync(IsActiveContext context) { context.IsActive = true; } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using IdentityServer4.Models; using IdentityServer4.Validation; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; namespace AuthService { public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator { public Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { //ToDo:验证自定义用户 //LoginUser loginUser = null; bool isAuthenticated = context.UserName=="aaa"&&context.Password=="1"? true :false; //loginUserService.Authenticate(context.UserName, context.Password, out loginUser); if (!isAuthenticated) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "账户名密码错误"); } else { context.Result = new GrantValidationResult( subject: context.UserName, authenticationMethod: "custom", claims: new Claim[] { new Claim("Name", context.UserName), new Claim("Id", ""), new Claim("RealName", ""), new Claim("Email", "") } ); } return Task.CompletedTask; } } }
6.增加示例数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using IdentityServer4.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AuthService { /// <summary> /// 因为此处采用in-memory,所以硬编码一些api,以及client /// </summary> public class ApiConfig { /// <summary> /// 定义ApiResource 这里的资源(Resources)指的就是我们的API /// </summary> /// <returns>ApiResource枚举</returns> public static IEnumerable<ApiResource> GetApiResources() { return new[] { new ApiResource("demoAPi", "测试API"), }; } /// <summary> /// 定义受信任的客户端 Client /// </summary> /// <returns></returns> public static IEnumerable<Client> GetClients() { return new[] { new Client { ClientId = "OcelotDemo",//客户端的标识,要是惟一的 ClientSecrets = new [] { new Secret("123456".Sha256()) },//客户端密码,进行了加密 AllowedGrantTypes = GrantTypes.ClientCredentials,//授权方式,这里采用的是客户端认证模式,只要ClientId,以及ClientSecrets正确即可访问对应的AllowedScopes里面的api资源 AllowedScopes = new [] { "demoAPi"}//定义这个客户端可以访问的APi资源数组 } }; } } }
改变网关
1.修改Startup.cs
增加节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
services.AddAuthentication() .AddIdentityServerAuthentication(Configuration.GetSection("Setting")["AuthScheme"], options => { options.Authority = Configuration.GetSection("Setting")["AuthUrl"]; options.ApiName = Configuration.GetSection("Setting")["AuthApiName"]; options.SupportedTokens = SupportedTokens.Both; options.RequireHttpsMetadata = false; });
2.修改网关配置
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//添加身份验证 "AuthenticationOptions": { "AuthenticationProviderKey": "OcelotKey", "AllowedScopes": [ "demoAPi"] }
3.修改配置文件appsettings.json
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"Setting": { "Port": "5000", "AuthScheme": "OcelotKey", //需要和ReRoutes中的AuthenticationProviderKey一致 "AuthUrl": "http://192.168.66.241:7500", // 验证服务地址 注意 必须带有http "AuthApiName": "demoAPi" //和 需要被验证服务的服务名称一致 }
注:
AuthUrl 中的 http:// 必填 不然会出现500异常
AuthApiName 需要被验证服务的服务名称一致 即 需要和scopename 一致
注释部分 错误会造成网关转发跳转出错
测试demoAPI无需改动
测试步骤:
1.token获取
post
请求url: http://192.168.66.241:5000/auth/login
参数 :
grant_type:client_credentials
client_id:OcelotDemo
client_secret:123456
如图:
2.测试访问
get
url:192.168.66.241:5000/demo1/values
参数 :
Authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjRkMDRhNjk4OTZhMGNhYjZiY2Y4MjBiOTgyOTdlMjk2IiwidHlwIjoiSldUIn0.eyJuYmYiOjE1NDIzMzMwNzQsImV4cCI6MTU0MjMzNjY3NCwiaXNzIjoiaHR0cDovLzE5Mi4xNjguNjYuMjQxOjc1MDAiLCJhdWQiOlsiaHR0cDovLzE5Mi4xNjguNjYuMjQxOjc1MDAvcmVzb3VyY2VzIiwiZGVtb0FQaSJdLCJjbGllbnRfaWQiOiJPY2Vsb3REZW1vIiwic2NvcGUiOlsiZGVtb0FQaSJdfQ.frqi9W3Yt2XpKStaxLWprVwaer1AB0eeXRdXoGxUBa0IAH-6kzjXKKxznTx-DvEiitZXuF9QBetcbe-otHFG0sHWhQstbD-m8GOHjp8C1RqQ1QFDjO6VspgMEjtugeiOuG2CibStySMZiWl4FpftMsijh9Qzi7RJn6DeHNChLXuv0R2XxCvJa0Bx2hUkRt8yH2pxhrFr4XpxKmtjlks2saPWIrN3D3JWYYcILMcQK-1GDRgc7v-q-KwnCL3DWWdF1kLDeaKv2VgLvnofwfUGQZ2fqZv91t0K0meoWUR3mxPo3JpoO5PnWI0-bttBcoKEC__k3ZgcoKUtPhtgUfcIeA
Content-Type:application/json
如图:
再次引用参考链接:
微服务系列教程
https://www.cnblogs.com/edisonchou/p/dotnetcore_microservice_foundation_blogs_index_final.html