ASP.NET Core3.1 Ocelot认证的实现(2)

在该项目中启用身份认证来保护下游api服务,使用JwtBearer认证,将默认的身份验证方案设置为TestKey。在appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息:

{ "Audience": { "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==", "Iss": "http://www.c-sharpcorner.com/members/catcher-wong", "Aud": "Catcher Wong" } }

Startup添加身份认证代码如下:

public void ConfigureServices(IServiceCollection services) { //获取appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息 var audienceConfig = Configuration.GetSection("Audience"); //获取安全秘钥 var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(audienceConfig["Secret"])); //token要验证的参数集合 var tokenValidationParameters = new TokenValidationParameters { //必须验证安全秘钥 ValidateIssuerSigningKey = true, //赋值安全秘钥 IssuerSigningKey = signingKey, //必须验证签发人 ValidateIssuer = true, //赋值签发人 ValidIssuer = audienceConfig["Iss"], //必须验证受众 ValidateAudience = true, //赋值受众 ValidAudience = audienceConfig["Aud"], //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, //允许的服务器时间偏移量 ClockSkew = TimeSpan.Zero, //是否要求Token的Claims中必须包含Expires RequireExpirationTime = true, }; //添加服务验证,方案为TestKey services.AddAuthentication(o => { o.DefaultAuthenticateScheme = "TestKey"; }) .AddJwtBearer("TestKey", x => { x.RequireHttpsMetadata = false; //在JwtBearerOptions配置中,IssuerSigningKey(签名秘钥)、ValidIssuer(Token颁发机构)、ValidAudience(颁发给谁)三个参数是必须的。 x.TokenValidationParameters = tokenValidationParameters; }); //添加Ocelot网关服务时,包括Secret秘钥、Iss签发人、Aud受众 services.AddOcelot(Configuration); } public async void Configure(IApplicationBuilder app, IHostingEnvironment env) { //使用认证服务 app.UseAuthentication(); //使用Ocelot中间件 await app.UseOcelot(); }

3.1.1Identity Server承载JWT Token

在第二小节介绍JWT Token认证时候,我们都知道一般发送用户名和密码获取Token那是由Identity4来完成的,包括验证用户,生成JWT Token。也就是说Identity Server承载了JWT Token认证功能。为了使用IdentityServer承载Token,请像往常一样在ConfigureServices中使用方案(密钥)注册IdentityServer服务。如果您不知道如何执行此操作,请查阅IdentityServer文档。

public void ConfigureServices(IServiceCollection services) { var authenticationProviderKey = "TestKey"; Action<IdentityServerAuthenticationOptions> options = o => { o.Authority = "https://whereyouridentityserverlives.com"; o.ApiName = "api"; o.SupportedTokens = SupportedTokens.Both; o.ApiSecret = "secret"; }; services.AddAuthentication() .AddIdentityServerAuthentication(authenticationProviderKey, options); services.AddOcelot(); }

在Identity4中是由Authority参数指定OIDC服务地址,OIDC可以自动发现Issuer, IssuerSigningKey等配置,而o.Audience与x.TokenValidationParameters = new TokenValidationParameters { ValidAudience = "api" }是等效的。

3.2AuthServer项目

此服务主要用于客户端请求受保护的资源服务器时,认证后产生客户端需要的JWT Token,生成JWT Token关键代码如下:

[Route("api/[controller]")] public class AuthController : Controller { private IOptions<Audience> _settings; public AuthController(IOptions<Audience> settings) { this._settings = settings; } /// <summary> ///用户使用 用户名密码 来请求服务器 ///服务器进行验证用户的信息 ///服务器通过验证发送给用户一个token ///客户端存储token,并在每次请求时附送上这个token值, headers: {'Authorization': 'Bearer ' + token} ///服务端验证token值,并返回数据 /// </summary> /// <param></param> /// <param></param> /// <returns></returns> [HttpGet] public IActionResult Get(string name, string pwd) { //验证登录用户名和密码 if (name == "catcher" && pwd == "123") { var now = DateTime.UtcNow; //添加用户的信息,转成一组声明,还可以写入更多用户信息声明 var claims = new Claim[] { //声明主题 new Claim(JwtRegisteredClaimNames.Sub, name), //JWT ID 唯一标识符 new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), //发布时间戳 issued timestamp new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64) }; //下面使用 Microsoft.IdentityModel.Tokens帮助库下的类来创建JwtToken //安全秘钥 var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_settings.Value.Secret)); //声明jwt验证参数 var tokenValidationParameters = new TokenValidationParameters { //必须验证安全秘钥 ValidateIssuerSigningKey = true, //赋值安全秘钥 IssuerSigningKey = signingKey, //必须验证签发人 ValidateIssuer = true, //赋值签发人 ValidIssuer = _settings.Value.Iss, //必须验证受众 ValidateAudience = true, //赋值受众 ValidAudience = _settings.Value.Aud, //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true, //允许的服务器时间偏移量 ClockSkew = TimeSpan.Zero, //是否要求Token的Claims中必须包含Expires RequireExpirationTime = true, }; var jwt = new JwtSecurityToken( //jwt签发人 issuer: _settings.Value.Iss, //jwt受众 audience: _settings.Value.Aud, //jwt一组声明 claims: claims, notBefore: now, //jwt令牌过期时间 expires: now.Add(TimeSpan.FromMinutes(2)), //签名凭证: 安全密钥、签名算法 signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256) ); //生成jwt令牌(json web token) var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); var responseJson = new { access_token = encodedJwt, expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds }; return Json(responseJson); } else { return Json(""); } } } public class Audience { public string Secret { get; set; } public string Iss { get; set; } public string Aud { get; set; } }

appsettings.json文件中配置认证中密钥(Secret)跟受众(Aud)信息:

{ "Audience": { "Secret": "Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA==", "Iss": "http://www.c-sharpcorner.com/members/catcher-wong", "Aud": "Catcher Wong" } }

3.3CustomerAPIServices项目

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/da5a5bff0844e0e8e3baee463828e0d6.html