在program.cs里面加上如下代码
c##region swagger jwt认证授权框
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
});
#endregion
复制代码
安装以下nuget包
如果下载不成功可以尝试换一下程序包源:
新建一个JwtHelper类
c# public class JwtHelper
{
/// <summary>
/// 创建Jwt字符串
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static string CreateJwt(TokenModelJwt model)
{
var claims = new List<Claim>
{
/*
* 特别重要:
1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了!
2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。
*/
new Claim("UserId",model.UserId.ToString()),
new Claim("UserName",model.UserName),
//new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法
};
// 可以将一个用户的多个角色全部赋予;
// 作者:DX 提供技术支持;
if (!string.IsNullOrWhiteSpace(model.Role))
{
claims.AddRange(model.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
claims.Add(new Claim("Role", model.Role));
}
//秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(model.Secret));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: model.Issuer,
audience: model.Audience,
expires: DateTime.Now.AddSeconds(model.Expires),
signingCredentials: creds,
claims: claims
);
var jwtHandler = new JwtSecurityTokenHandler();
var token = jwtHandler.WriteToken(jwt);
return token;
}
/// <summary>
/// 解析
/// </summary>
/// <param name="jwtStr">如果为null将报错</param>
/// <returns></returns>
public static TokenModelJwt SerializeJwt(string jwtStr)
{
//截取字符串 把bearer 去掉不然解析失败
string str = "";
if (jwtStr.Contains("Bearer "))
{
str = jwtStr.Substring("Bearer ".Length, jwtStr.Length - "Bearer ".Length);
}
else
{
str = jwtStr;
}
//尝试解析token
try
{
var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(str);
var tokenJwt = JsonConvert.DeserializeObject<TokenModelJwt>(jwtToken.Payload.SerializeToJson());
return tokenJwt;
}
catch (Exception)
{
return null;
}
}
}
/// <summary>
/// 令牌
/// </summary>
public class TokenModelJwt
{
public int UserId { get; set; }
public string UserName { get; set; }
public string Issuer { get; set; }
public string Audience { get; set; }
public string Secret { get; set; }
public int Expires { get; set; }
public string Role { get; set; }
}
复制代码
在appsetting.json里面配置加密字符串
json"Jwt": {
"Secret": "skumallliulingshsoxijs", //不要太短,有可能会报异常
"Issuer": "LL",
"Audience": "LL"
}
复制代码
program.cs里面加上以下代码:
c##region Jwt
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
var tokenModel = builder.Configuration.GetSection("Jwt").Get<TokenModelJwt>();
var secretByte = Encoding.UTF8.GetBytes(tokenModel.Secret);
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuer = tokenModel.Issuer,
ValidateAudience = true,
ValidAudience = tokenModel.Audience,
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(secretByte)
};
options.Events = new JwtBearerEvents
{
OnChallenge = context =>
{
//此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦,必须
//context.HandleResponse();
//自定义自己想要返回的数据结果,我这里要返回的是Json对象,通过引用Newtonsoft.Json库进行转换
//自定义返回的数据类型
//context.Response.ContentType = "text/plain";
////自定义返回状态码,默认为401 我这里改成 200
////context.Response.StatusCode = StatusCodes.Status200OK;
//context.Response.StatusCode = StatusCodes.Status401Unauthorized;
////输出Json数据结果
//context.Response.WriteAsync("expired");
return Task.FromResult(0);
},
//403
OnForbidden = context =>
{
//context.Response.ContentType = "text/plain";
////自定义返回状态码,默认为401 我这里改成 200
////context.Response.StatusCode = StatusCodes.Status200OK;
//context.Response.StatusCode = StatusCodes.Status401Unauthorized;
////输出Json数据结果
//context.Response.WriteAsync("expired");
return Task.FromResult(0);
}
};
});
#endregion
复制代码
在控制器接口上添加认证 Authorize
运行项目try一下,应该会返回401未授权状态码。
在控制器中加入以下方法测试:
c# /// <summary>
/// 测试是否能返回token
/// </summary>
/// <param name="account"></param>
/// <param name="password"></param>
/// <returns></returns>
[HttpPost(Name = "Login")]
public string Login(string account , string password)
{
//仅为模拟用户输入登录的情况
if(account == "123456" && password == "123456")
{
//这一段为获取appsettings.json定义的数据 , 可以忽视,后面用依赖注入的方法会更加方便
IConfiguration configuration = new
ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).Add(new JsonConfigurationSource
{
Path = "appsettings.json",
ReloadOnChange = true
}).Build();;
TokenModelJwt tokenModel = configuration.GetSection("Jwt").Get<TokenModelJwt>();
tokenModel.UserId = 1;
tokenModel.Role = "Admin";
tokenModel.UserName = "用户名";
return JwtHelper.CreateJwt(tokenModel);
}
return "账号密码错误";
}
复制代码
运行调用接口获取到token
复制得到的token,在swagger中认证然后测试获取数据
成功获取。
本文作者:烈焰大火龙
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 © 烈焰大火龙 许可协议。转载请注明出处!