经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
.NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)
来源:cnblogs  作者:千金不如一默  时间:2019/4/29 9:09:54  对本文有异议

上接:.NetCore WebApi——Swagger简单配置

 

任何项目都有权限这一关键部分。比如我们有许多接口。有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问;以保证重要数据不会泄露。

 

关于JWT

维基百科上是这样定义的:

JWT(读作 [/d??t/]),即JSON Web Tokens,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。它是一种用于双方之间传递安全信息的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的、自包含的方法,从而使通信双方实现以JSON对象的形式安全的传递信息。

 

认证的工作流程:

1. 客户端携带用户名、密码向授权服务申请 "令牌(token)"

2.授权服务器验证用户名、密码后根据它的身份生成一张专属的 "令牌" 并JWT的格式规范返回给客户端

3.客户端将获取到的令牌放入到http的请求头中,然后向资源服务器发起请求。服务器根据客户端发送过来的令牌来进行下一步处理(根据身份来响应客户端是否具有当前接口的权限)

如下图所示:

 正文:

主要参考园友  在7楼  的这篇文章 https://www.cnblogs.com/RayWang/p/9536524.html 

 1. 启用Swagger的验证功能

在startup类中新添加红色部分代码。启动项目观察效果。

  1. // 注册Swagger服务
  2. services.AddSwaggerGen(c =>
  3. {
  4. // 添加文档信息
  5. c.SwaggerDoc("v1", new Info
  6. {
  7. Title = "CoreWebApi",
  8. Version = "v1",
  9. Description = "ASP.NET CORE WebApi",
  10. Contact = new Contact
  11. {
  12. Name = "Jee",
  13. Email = "xiaomaprincess@gmail.com",
  14. Url = "https://www.cnblogs.com/jixiaosa/"
  15. }
  16. });
  17. #region 读取xml信息
  18.  
  19. // 使用反射获取xml文件。并构造出文件的路径
  20. var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  21. var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  22. // 启用xml注释. 该方法第二个参数启用控制器的注释,默认为false.
  23. c.IncludeXmlComments(xmlPath, true);
  24. #endregion
  25.  
  26. #region 启用swagger验证功能
  27. //添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称一致即可,CoreAPI。
  28. var security = new Dictionary<string, IEnumerable<string>> { { "CoreAPI", new string[] { } }, };
  29. c.AddSecurityRequirement(security);
  30. c.AddSecurityDefinition("CoreAPI", new ApiKeyScheme
  31. {
  32. Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",
  33. Name = "Authorization",//jwt默认的参数名称
  34. In = "header",//jwt默认存放Authorization信息的位置(请求头中)
  35. Type = "apiKey"
  36. });
  37. #endregion
  38. });

 

没启动Swagger验证之前是这样的:

 

 

启用验证之后再看:多了个小按钮

 

 

 

点开之后是如下界面:文本框里要如输入从服务器获取的Token。格式为:Bearer + 空格+token。 Bearer可以看作是一个默认的规则。

 

2.生成token

.net core 内置了许多帮助类,巧妙的使用这些类组合,就可以生成我们想要的 token

新建一个tokenl类,编写一个方法来获取JWT字符串

  1. /// <summary>
  2. /// 生成JWT字符串
  3. /// </summary>
  4. public class Token
  5. {
  6. // 密钥,注意不能太短
  7. public static string secretKey { get; set; } = "xiaomaPrincess@gmail.com";
  8. /// <summary>
  9. /// 生成JWT字符串
  10. /// </summary>
  11. /// <param name="tokenModel"></param>
  12. /// <returns></returns>
  13. public static string GetJWT(TokenModel tokenModel)
  14. {
  15. //DateTime utc = DateTime.UtcNow;
  16. var claims = new List<Claim>
  17. {
  18. new Claim(JwtRegisteredClaimNames.Jti,tokenModel.ID.ToString()),
  19. // 令牌颁发时间
  20. new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
  21. new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
  22. // 过期时间 100秒
  23. new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),
  24. new Claim(JwtRegisteredClaimNames.Iss,"API"), // 签发者
  25. new Claim(JwtRegisteredClaimNames.Aud,"User") // 接收者
  26. };
  27. // 密钥
  28. var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
  29. var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  30. var tokenHandler = new JwtSecurityTokenHandler();
  31. JwtSecurityToken jwt = new JwtSecurityToken(
  32. claims: claims,// 声明的集合
  33. //expires: .AddSeconds(36), // token的有效时间
  34. signingCredentials: creds
  35. );
  36. var handler = new JwtSecurityTokenHandler();
  37. // 生成 jwt字符串
  38. var strJWT = handler.WriteToken(jwt);
  39. return strJWT;
  40. }
  41. }

 

基本信息类

  1. public class TokenModel
  2. {
  3. /// <summary>
  4. /// ID
  5. /// </summary>
  6. public int ID { get; set; }
  7. /// <summary>
  8. /// 名称
  9. /// </summary>
  10. public string Name { get; set; }
  11. /// <summary>
  12. /// 手机
  13. /// </summary>
  14. public string Phone { get; set; }
  15. /// <summary>
  16. /// 邮箱
  17. /// </summary>
  18. public string Email { get; set; }
  19. /// <summary>
  20. /// 身份
  21. /// </summary>
  22. public string Sub { get; set; }
  23. }

 

添加一个方法来获取token

  1. /// <summary>
  2. /// 获取令牌
  3. /// </summary>
  4. /// <param name="ID">ID</param>
  5. /// <param name="name">账号</param>
  6. /// <returns></returns>
  7. [HttpPost]
  8. public string GetJwt(int ID,string name)
  9. {
  10. TokenModel tokenModel = new TokenModel
  11. {
  12. ID = ID,
  13. Name=name
  14. };
  15. return Token.GetJWT(tokenModel);
  16. }

 

在Startup类中配置身份认证服务

(1)在ConfigureServices方法中注册服务

  1. #region 添加验证服务
  2.  
  3. // 添加验证服务
  4. services.AddAuthentication(x =>
  5. {
  6. x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  7. x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  8. }).AddJwtBearer(o =>
  9. {
  10. o.TokenValidationParameters = new TokenValidationParameters
  11. {
  12. // 是否开启签名认证
  13. ValidateIssuerSigningKey = true,
  14. IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Token.secretKey)),
  15. // 发行人验证,这里要和token类中Claim类型的发行人保持一致
  16. ValidateIssuer = true,
  17. ValidIssuer = "API",//发行人
  18. // 接收人验证
  19. ValidateAudience = true,
  20. ValidAudience = "User",//订阅人
  21. ValidateLifetime = true,
  22. ClockSkew = TimeSpan.Zero,
  23. };
  24. });
  25. #endregion

(2)在Configure方法中启用验证中间件

  1. // 启用Swagger中间件
  2. app.UseSwagger();
  3. // 配置SwaggerUI
  4. app.UseSwaggerUI(c =>
  5. {
  6. c.SwaggerEndpoint("/swagger/v1/swagger.json", "CoreAPI");
  7. c.RoutePrefix = string.Empty;
  8. });
  9. // 启用认证中间件
  10. app.UseAuthentication();
  11. app.UseMvc();

 

3. 添加一个测试测控制器来检测是否成功

注意要添加 [Authorize]标签

 

  1. /// <summary>
  2. /// 需要身份认证的控制器
  3. /// </summary>
  4. [Route("api/[controller]/[action]")]
  5. [Produces("application/json")]
  6. [ApiController]
  7. [Authorize]// 添加授权特性
  8. public class TestController : ControllerBase
  9. {
  10. /// <summary>
  11. /// 认证通过之后可访问
  12. /// </summary>
  13. /// <returns></returns>
  14. [HttpPost]
  15. public ActionResult<TokenModel> Get(TokenModel tokenModel)
  16. {
  17. return new TokenModel{ ID=1 };
  18. }
  19. }

 

启动项目

测试一: 在没有获取token时访问此方法

 

 返回401 身份验证未通过

 

测试二:先访问GetJWT接口获取token,在访问Test接口

 

 

最后将获取的token输入到Swagger的文本框中:Bearer +空格+Token

 

 再次访问Test接口:成功返回数据

 

至此,一个简单身份认证加授权就完成了。

推荐一篇大神的文章 :讲述Claim的

理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文

原文链接:http://www.cnblogs.com/jixiaosa/p/10783855.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号