- 1.Cookie-based认证与授权
- 2.Cookie-based认证实现
- 3.Jwt认证与授权介绍
- 4.Jwt认证与授权实现
- 5.Jwt认证与授权
- 6.Role based授权
- 7.Claims-based授权
任务32:Cookie-based认证介绍
任务34:Cookie-based认证实现
dotnet new mvc --name MvcCookieAuthSample
在Controllers文件夹新增AdminController.cs
1.
using System;2.
using System.Collections.Generic;
3.
using System.Diagnostics;
4.
using System.Linq;
5.
using System.Threading.Tasks;6.
using Microsoft.AspNetCore.Mvc;
7.
using MvcCookieAuthSample.Models;
8.
9.
namespace MvcCookieAuthSample.Controllers
10.
{
11.
public class AdminController : Controller
12.
{
13.
public IActionResult Index()
14.
{
15.
return View();
16.
}
17.
}
18.
}
在Views文件夹新增Admin文件夹,在Admin文件夹新增Index.cshtml
1.
2.
ViewData["Title"] = "Admin";
3.
}
4.
<h2>@ViewData["Title"]</h2>
5.
6.
<p>Admin Page</p>
启动项目,浏览器访问https://localhost:5001/Admin
实际情况不应该直接让用户访问到Admin页面,所以应当跳转到登陆界面
1.
using System;
2.
using System.Collections.Generic;
3.
using System.Diagnostics;
4.
using System.Linq;
5.
using System.Threading.Tasks;
6.
using Microsoft.AspNetCore.Mvc;
7.
using MvcCookieAuthSample.Models;
8.
// 添加引用
9.
using Microsoft.AspNetCore.Authorization;
10.
11.
namespace MvcCookieAuthSample.Controllers
12.
{
13.
public class AdminController : Controller
14.
{
15.
[Authorize]
16.
public IActionResult Index()
17.
{
18.
return View();
19.
}
20.
}
21.
}
startup.cs
1.
using System;
2.
using System.Collections.Generic;
3.
using System.Linq;
4.
using System.Threading.Tasks;
5.
using Microsoft.AspNetCore.Builder;
6.
using Microsoft.AspNetCore.Hosting;
7.
using Microsoft.AspNetCore.Http;
8.
using Microsoft.AspNetCore.HttpsPolicy;
9.
using Microsoft.AspNetCore.Mvc;
10.
using Microsoft.Extensions.Configuration;
11.
using Microsoft.Extensions.DependencyInjection;
12.
// 添加引用
13.
using Microsoft.AspNetCore.Authorization;
14.
using Microsoft.AspNetCore.Authentication.Cookies;
15.
16.
namespace MvcCookieAuthSample
17.
{
18.
public class Startup
19.
{
20.
public Startup(IConfiguration configuration)
21.
{
22.
Configuration = configuration;
23.
}
24.
25.
public IConfiguration Configuration { get; }
26.
27.
// This method gets called by the runtime. Use this method to add services to the container.
28.
public void ConfigureServices(IServiceCollection services)
29.
{
30.
services.Configure<CookiePolicyOptions>(options =>
31.
{
32.
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
33.
options.CheckConsentNeeded = context => true;
34.
options.MinimumSameSitePolicy = SameSiteMode.None;
35.
});
36.
37.
// Addmvc之前AddAuthentication,AddCookie
38.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
39.
.AddCookie();
40.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
41.
}
42.
43.
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
44.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
45.
{
46.
if (env.IsDevelopment())
47.
{
48.
app.UseDeveloperExceptionPage();
49.
}
50.
else
51.
{
52.
app.UseExceptionHandler("/Home/Error");
53.
app.UseHsts();
54.
}
55.
56.
app.UseHttpsRedirection();
57.
app.UseStaticFiles();
58.
app.UseCookiePolicy();
59.
60.
// UseMvc之前UseAuthentication,添加Middleware
61.
app.UseAuthentication();
62.
app.UseMvc(routes =>
63.
{
64.
routes.MapRoute(
65.
name: "default",
66.
template: "{controller=Home}/{action=Index}/{id?}");
67.
});
68.
}
69.
}
70.
}
再次访问https://localhost:5001/Admin,跳转到登陆界面https://localhost:5001/Account/Login?ReturnUrl=%2FAdmin
在Controllers文件夹新增AccountController.cs
1.
using System.Collections.Generic;
2.
using System.Diagnostics;
3.
using System.Linq;
4.
using System.Threading.Tasks;
5.
using Microsoft.AspNetCore.Mvc;
6.
using MvcCookieAuthSample.Models;
7.
// 添加引用
8.
using Microsoft.AspNetCore.Authorization;
9.
using Microsoft.AspNetCore.Authentication;
10.
using Microsoft.AspNetCore.Authentication.Cookies;
11.
using System.Security.Claims;
12.
13.
namespace MvcCookieAuthSample.Controllers
14.
{
15.
[Authorize]
16.
public class AccountController : Controller
17.
{
18.
public IActionResult MakeLogin()
19.
{
20.
var claims = new List<Claim>()
21.
{
22.
new Claim(ClaimTypes.Name,"Mingson"),
23.
new Claim(ClaimTypes.Role,"admin")
24.
};
25.
26.
var claimIdentity = new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);
27.
28.
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));
29.
30.
return Ok();
31.
}
32.
33.
public IActionResult Logout()
34.
{
35.
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
36.
37.
return Ok();
38.
}
39.
}
40.
}
启动项目
登出:localhost:5000/account/logout
访问admin:localhost:5000/admin,跳转到account/login
登陆:localhost:5000/account/makelogin
再次访问admin:localhost:5000/admin,登陆成功访问admin
任务35:JWT 认证授权介绍
可在官网解密:https://jwt.io
任务36:应用Jwtbearer Authentication
-
dotnet new webapi --name JwtAuthSample -
dotnet watch run
打开postman调用
http://localhost:5000/api/values
ValuesController.cs
1.
2.
using Microsoft.AspNetCore.Authorization;
3.
4.
// 添加特性
5.
Authorize]
6.
Route("api/[controller]")]
7.
ApiController]
8.
public class ValuesController : ControllerBase
新增一个Models文件夹,在文件夹中新增JwtSettings.cs
1.
namespace JwtAuthSample
2.
{
3.
public class JwtSettings
4.
{
5.
// token颁发者
6.
public string Issure{get;set;}
7.
// token使用的客户端
8.
public string Audience{get;set;}
9.
// 加密Key
10.
public string SecretKey="hellokey";
11.
}
12.
}
appsettings.json
1.
{
2.
"Logging": {
3.
"LogLevel": {
4.
"Default": "Warning"
5.
}
6.
},
7.
"AllowedHosts": "*",
8.
"JwtSettings":{
9.
"Audience":"http://localhost:5000",
10.
"Issuer":"http://localhost:5000",
11.
"SecretKey":"Hello-key"
12.
}
13.
}
Startup.cs
1.
// 添加引用
2.
using Microsoft.AspNetCore.Authentication.JwtBearer;
3.
using Microsoft.IdentityModel.Tokens;
4.
using System.Text;
5.
6.
// 添加在services.AddMvc()之前
7.
services.Configure<JwtSettings>(Configuration);
8.
var JwtSettings = new JwtSettings();
9.
"JwtSettings",JwtSettings);
10.
// 认证MiddleWare配置
11.
services.AddAuthentication(options=>{
12.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
13.
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
14.
})
15.
// Jwt配置
16.
.AddJwtBearer(o=>{
17.
new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
18.
ValidIssuer = JwtSettings.Issure,
19.
ValidAudience = JwtSettings.Audience,
20.
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
21.
};
22.
});
23.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
24.
25.
app.UseHttpsRedirection();
26.
// 添加在app.UseMvc()之前
27.
app.UseAuthentication();
dotnet watch run
postman调用
http://localhost:5000/api/values返回401,未授权
任务37:生成 JWT Token
新建文件夹ViewModels,在文件夹中新建LoginViewModel.cs
1.
2.
3.
namespace JwtAuthSample
4.
{
5.
public class LoginViewModel
6.
{
7.
Required]
8.
public string User{get;set;}
9.
Required]
10.
public string Password{get;set;}
11.
}
12.
}
AuthorizeController.cs
1.
using System;
2.
using System.Collections.Generic;
3.
using System.Linq;
4.
using System.Threading.Tasks;
5.
using Microsoft.AspNetCore.Mvc;
6.
// 添加引用
7.
using System.Security.Claims;
8.
using Microsoft.IdentityModel.Tokens;
9.
using Microsoft.Extensions.Options;
10.
using System.Text;
11.
using System.IdentityModel.Tokens.Jwt;
12.
13.
namespace JwtAuthSample.Controllers
14.
{
15.
Route("api/[controller]")]
16.
ApiController]
17.
public class AuthorizeController : ControllerBase
18.
{
19.
private JwtSettings _jwtSettings;
20.
21.
public AuthorizeController(IOptions<JwtSettings> _jwtSettingsAccesser)
22.
{
23.
_jwtSettings = _jwtSettingsAccesser.Value;
24.
}
25.
26.
public IActionResult Token(LoginViewModel viewModel)
27.
{
28.
if (ModelState.IsValid)
29.
{
30.
if (!(viewModel.User == "mingson" && viewModel.Password == "123456"))
31.
{
32.
return BadRequest();
33.
}
34.
35.
var claims = new Claim[]
36.
{
37.
new Claim(ClaimTypes.Name, "mingson"),
38.
new Claim(ClaimTypes.Role, "admin")
39.
};
40.
41.
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));// 对称加密算法
42.
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
43.
44.
// VSCode安装扩展NuGet Package Manager
45.
// ctrl + shift + p
46.
// NuGet Package Manager:Add Pcakage
47.
// Microsoft.AspNetCore.Authentication.JwtBearer
48.
// 需要FQ才能添加
49.
// 2.0.0
50.
// 安装到csproj
51.
// 安装成功后csproj中出现<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.0" />
52.
// dotnet restore
53.
54.
var token = new JwtSecurityToken(
55.
_jwtSettings.Issure,
56.
_jwtSettings.Audience,
57.
claims,
58.
DateTime.Now,
59.
30),
60.
creds);
61.
62.
return Ok(new {token = new JwtSecurityTokenHandler().WriteToken(token)});
63.
}
64.
65.
return BadRequest();
66.
}
67.
}
68.
}
Startup.cs
1.
2.
//services.Configure<JwtSettings>(Configuration);// 获取不到JwtSettings配置
3.
Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));// 获取appsettings.json中的配置
appsettings.json
1.
{
2.
"Logging": {
3.
"LogLevel": {
4.
"Default": "Warning"
5.
}
6.
},
7.
"AllowedHosts": "*",
8.
"JwtSettings":{
9.
"Audience":"http://localhost:5000",
10.
"Issuer":"http://localhost:5000",
11.
"SecretKey长度必须大于128bit=16字符":"",
12.
"SecretKey":"Hello-key.jessetalk"
13.
}
14.
}
dotnet watch run
postman调用
http://localhost:5000/Authorize/Token返回Token
加上token调用
http://localhost:5000/api/values
token可在官网解密:https://jwt.io
输入正确的SecretKey:Hello-key.jessetalk
任务38:JWT 设计解析及定制
新建文件MyTokenValidator.cs
1.
2.
using System.Collections.Generic;
3.
using System.IO;
4.
using System.Linq;
5.
using System.Threading.Tasks;
6.
using Microsoft.AspNetCore;
7.
using Microsoft.AspNetCore.Hosting;
8.
using Microsoft.Extensions.Configuration;
9.
using Microsoft.Extensions.Logging;
10.
// 添加引用
11.
using Microsoft.AspNetCore.Authentication.JwtBearer;
12.
using System.Security.Claims;
13.
using Microsoft.IdentityModel.Tokens;
14.
15.
namespace JwtAuthSample
16.
{
17.
public class MyTokenValidator : ISecurityTokenValidator
18.
{
19.
bool ISecurityTokenValidator.CanValidateToken => true;
20.
21.
int ISecurityTokenValidator.MaximumTokenSizeInBytes { get;set; }
22.
23.
bool ISecurityTokenValidator.CanReadToken(string securityToken)
24.
{
25.
return true;
26.
}
27.
28.
string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
29.
{
30.
null;
31.
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
32.
33.
if (securityToken == "abcdefg")
34.
{
35.
new Claim("name", "mingson"));
36.
new Claim("SuperAdminOnly", "true"));
37.
new Claim(ClaimsIdentity.DefaultNameClaimType, "user"));
38.
}
39.
40.
var principal = new ClaimsPrincipal(identity);
41.
42.
return principal;
43.
}
44.
}
45.
}
Startup.cs
1.
2.
AddAuthentication(options=>{
3.
DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
4.
DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
5.
})
6.
// Jwt配置
7.
AddJwtBearer(o=>{
8.
// o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
9.
// ValidIssuer = JwtSettings.Issure,
10.
// ValidAudience = JwtSettings.Audience,
11.
// IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
12.
// };
13.
14.
// 修改token来源
15.
SecurityTokenValidators.Clear();// 一个包含验证的数组,先清除
16.
SecurityTokenValidators.Add(new MyTokenValidator());
17.
18.
// 修改token验证方式
19.
Events = new JwtBearerEvents(){
20.
OnMessageReceived = context => {
21.
var token = context.Request.Headers["mytoken"];
22.
Token = token.FirstOrDefault();
23.
return Task.CompletedTask;
24.
}
25.
};
26.
});
27.
28.
AddAuthorization(Options=>{
29.
Options.AddPolicy("SuperAdminOnly", policy => policy.RequireClaim("SuperAdminOnly"));
30.
});
AuthorizeController.cs
1.
// var claims = new Claim[]
2.
// {
3.
// new Claim(ClaimTypes.Name, "mingson"),
4.
// new Claim(ClaimTypes.Role, "admin")
5.
// };
6.
var claims = new Claim[]
7.
{
8.
new Claim(ClaimTypes.Name, "mingson"),
9.
new Claim(ClaimTypes.Role, "user"),
10.
new Claim("SuperAdminOnly", "true")
11.
};
ValuesController.cs
1.
2.
Authorize(Policy="SuperAdminOnly")]
dotnet run
输入一个错误的mytoken,返回403 Forbidden,禁止访问
输入一个正确的mytoken,返回200 OK
任务39:Role以及Claims授权
Role授权
AuthorizeController.cs
1.
2.
{
3.
new Claim(ClaimTypes.Name, "mingson"),
4.
new Claim(ClaimTypes.Role, "admin")
5.
};
ValuesController.cs
[Authorize(Roles="user")]
dotnet run
带着token访问,返回403 Forbidden,禁止访问
AuthorizeController.cs修改为user,可访问
1.
var claims = new Claim[]2.
{
3.
new Claim(ClaimTypes.Name, "mingson"),
4.
new Claim(ClaimTypes.Role, "user")
5.
};
Claims授权
Startup.cs
1.
2.
services.AddAuthentication(options=>{
3.
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
4.
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
5.
})
6.
// Jwt配置
7.
.AddJwtBearer(o=>{
8.
o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
9.
ValidIssuer = JwtSettings.Issure,
10.
ValidAudience = JwtSettings.Audience,
11.
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.SecretKey))// 对称加密
12.
};
13.
});
14.
15.
services.AddAuthorization(Options=>{
16.
Options.AddPolicy("SuperAdminOnly", policy => policy.RequireClaim("SuperAdminOnly"));
17.
});
ValuesController.cs
[Authorize(Policy="SuperAdminOnly")]
AuthorizeController.cs
1.
2.
{
3.
new Claim(ClaimTypes.Name, "mingson"),
4.
new Claim(ClaimTypes.Role, "user"),
5.
new Claim("SuperAdminOnly", "true")
6.
};
dotnet run
带着token访问,返回200 Ok