.net core webapi jwt 更为清爽的认证详解

2025-05-29 0 75

我的方式非主流,控制却可以更加灵活,喜欢的朋友,不妨花一点时间学习一下

jwt认证分为两部分,第一部分是加密解密,第二部分是灵活的应用于中间件,我的处理方式是将获取token放到api的一个具体的controller中,将发放token与验证分离,token的失效时间,发证者,使用者等信息存放到config中。

1.配置:

在appsettings.json中增加配置

?

1

2

3

4

5

6

7

8

9

10
"Jwt": {

"Issuer": "issuer",//随意定义

"Audience": "Audience",//随意定义

"SecretKey": "abc",//随意定义

"Lifetime": 20, //单位分钟

"ValidateLifetime": true,//验证过期时间

"HeadField": "useless", //头字段

"Prefix": "prefix", //前缀

"IgnoreUrls": [ "/Auth/GetToken" ]//忽略验证的url

}

2:定义配置类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30
internal class JwtConfig

{

public string Issuer { get; set; }

public string Audience { get; set; }

/// <summary>

/// 加密key

/// </summary>

public string SecretKey { get; set; }

/// <summary>

/// 生命周期

/// </summary>

public int Lifetime { get; set; }

/// <summary>

/// 是否验证生命周期

/// </summary>

public bool ValidateLifetime { get; set; }

/// <summary>

/// 验证头字段

/// </summary>

public string HeadField { get; set; }

/// <summary>

/// jwt验证前缀

/// </summary>

public string Prefix { get; set; }

/// <summary>

/// 忽略验证的url

/// </summary>

public List<string> IgnoreUrls { get; set; }

}

3.加密解密接口:

?

1

2

3

4

5
public interface IJwt

{

string GetToken(Dictionary<string, string> Clims);

bool ValidateToken(string Token,out Dictionary<string ,string> Clims);

}

4.加密解密的实现类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98
install -package System.IdentityModel.Tokens.Jwt

public class Jwt : IJwt

{

private IConfiguration _configuration;

private string _base64Secret;

private JwtConfig _jwtConfig = new JwtConfig();

public Jwt(IConfiguration configration)

{

this._configuration = configration;

configration.GetSection("Jwt").Bind(_jwtConfig);

GetSecret();

}

/// <summary>

/// 获取到加密串

/// </summary>

private void GetSecret()

{

var encoding = new System.Text.ASCIIEncoding();

byte[] keyByte = encoding.GetBytes("salt");

byte[] messageBytes = encoding.GetBytes(this._jwtConfig.SecretKey);

using (var hmacsha256 = new HMACSHA256(keyByte))

{

byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);

this._base64Secret= Convert.ToBase64String(hashmessage);

}

}

/// <summary>

/// 生成Token

/// </summary>

/// <param name="Claims"></param>

/// <returns></returns>

public string GetToken(Dictionary<string, string> Claims)

{

List<Claim> claimsAll = new List<Claim>();

foreach (var item in Claims)

{

claimsAll.Add(new Claim(item.Key, item.Value));

}

var symmetricKey = Convert.FromBase64String(this._base64Secret);

var tokenHandler = new JwtSecurityTokenHandler();

var tokenDescriptor = new SecurityTokenDescriptor

{

Issuer = _jwtConfig.Issuer,

Audience = _jwtConfig.Audience,

Subject = new ClaimsIdentity(claimsAll),

NotBefore = DateTime.Now,

Expires = DateTime.Now.AddMinutes(this._jwtConfig.Lifetime),

SigningCredentials =new SigningCredentials(new SymmetricSecurityKey(symmetricKey),

SecurityAlgorithms.HmacSha256Signature)

};

var securityToken = tokenHandler.CreateToken(tokenDescriptor);

return tokenHandler.WriteToken(securityToken);

}

public bool ValidateToken(string Token, out Dictionary<string, string> Clims)

{

Clims = new Dictionary<string, string>();

ClaimsPrincipal principal = null;

if (string.IsNullOrWhiteSpace(Token))

{

return false;

}

var handler = new JwtSecurityTokenHandler();

try

{

var jwt = handler.ReadJwtToken(Token);

if (jwt == null)

{

return false;

}

var secretBytes = Convert.FromBase64String(this._base64Secret);

var validationParameters = new TokenValidationParameters

{

RequireExpirationTime = true,

IssuerSigningKey = new SymmetricSecurityKey(secretBytes),

ClockSkew = TimeSpan.Zero,

ValidateIssuer = true,//是否验证Issuer

ValidateAudience = true,//是否验证Audience

ValidateLifetime = this._jwtConfig.ValidateLifetime,//是否验证失效时间

ValidateIssuerSigningKey = true,//是否验证SecurityKey

ValidAudience = this._jwtConfig.Audience,

ValidIssuer = this._jwtConfig.Issuer

};

SecurityToken securityToken;

principal = handler.ValidateToken(Token, validationParameters, out securityToken);

foreach (var item in principal.Claims)

{

Clims.Add(item.Type, item.Value);

}

return true;

}

catch (Exception ex)

{

return false;

}

}

}

5.定义获取Token的Controller:

在Startup.ConfigureServices中注入 IJwt

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26
services.AddTransient<IJwt, Jwt>(); // Jwt注入

[Route("[controller]/[action]")]

[ApiController]

public class AuthController : ControllerBase

{

private IJwt _jwt;

public AuthController(IJwt jwt)

{

this._jwt = jwt;

}

/// <summary>

/// getToken

/// </summary>

/// <returns></returns>

[HttpPost]

public IActionResult GetToken()

{

if (true)

{

Dictionary<string, string> clims = new Dictionary<string, string>();

clims.Add("userName", userName);

return new JsonResult(this._jwt.GetToken(clims));

}

}

}

6.创建中间件:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50
public class UseJwtMiddleware

{

private readonly RequestDelegate _next;

private JwtConfig _jwtConfig =new JwtConfig();

private IJwt _jwt;

public UseJwtMiddleware(RequestDelegate next, IConfiguration configration,IJwt jwt)

{

_next = next;

this._jwt = jwt;

configration.GetSection("Jwt").Bind(_jwtConfig);

}

public Task InvokeAsync(HttpContext context)

{

if (_jwtConfig.IgnoreUrls.Contains(context.Request.Path))

{

return this._next(context);

}

else

{

if (context.Request.Headers.TryGetValue(this._jwtConfig.HeadField, out Microsoft.Extensions.Primitives.StringValues authValue))

{

var authstr = authValue.ToString();

if (this._jwtConfig.Prefix.Length > 0)

{

authstr = authValue.ToString().Substring(this._jwtConfig.Prefix.Length+1, authValue.ToString().Length -(this._jwtConfig.Prefix.Length+1));

}

if (this._jwt.ValidateToken(authstr, out Dictionary<string, string> Clims))

{

foreach (var item in Clims)

{

context.Items.Add(item.Key, item.Value);

}

return this._next(context);

}

else

{

context.Response.StatusCode = 401;

context.Response.ContentType = "application/json";

return context.Response.WriteAsync("{\\"status\\":401,\\"statusMsg\\":\\"auth vaild fail\\"}");

}

}

else

{

context.Response.StatusCode = 401;

context.Response.ContentType = "application/json";

return context.Response.WriteAsync("{\\"status\\":401,\\"statusMsg\\":\\"auth vaild fail\\"}");

}

}

}

}

7.中间件暴露出去

?

1

2

3

4

5

6

7

8

9

10

11

12
public static class UseUseJwtMiddlewareExtensions

{

/// <summary>

/// 权限检查

/// </summary>

/// <param name="builder"></param>

/// <returns></returns>

public static IApplicationBuilder UseJwt(this IApplicationBuilder builder)

{

return builder.UseMiddleware<UseJwtMiddleware>();

}

}

8.在Startup.Configure中使用中间件:

?

1
app.UseJwt();

以1的配置为例:

除了请求 /auth/getToken 不需要加头信息外,其他的请求一律要求头信息中必须带着

?

1
userless:prefix (从Auth/GetToken中获取到的token)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:https://www.cnblogs.com/zzfstudy/p/10922384.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 .net core webapi jwt 更为清爽的认证详解 https://www.kuaiidc.com/98614.html

相关文章

发表评论
暂无评论