• 1.Cookie-based认证与授权
  • 2.Cookie-based认证实现
  • 3.Jwt认证与授权介绍
  • 4.Jwt认证与授权实现
  • 5.Jwt认证与授权
  • 6.Role based授权
  • 7.Claims-based授权

任务32:Cookie-based认证介绍

ASP.NET Core快速入门(第5章:认证与授权)_Linq

任务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

ASP.NET Core快速入门(第5章:认证与授权)_System_02

实际情况不应该直接让用户访问到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

ASP.NET Core快速入门(第5章:认证与授权)_System_03

在Controllers文件夹新增AccountController.cs

  1.  
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 认证授权介绍

ASP.NET Core快速入门(第5章:认证与授权)_sed_04

可在官网解密:https://jwt.io

ASP.NET Core快速入门(第5章:认证与授权)_Linq_05

任务36:应用Jwtbearer Authentication

  1.  
    dotnet new webapi --name JwtAuthSample
  2.  
    dotnet watch run

打开postman调用
http://localhost:5000/api/values

ASP.NET Core快速入门(第5章:认证与授权)_Linq_06

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,未授权

ASP.NET Core快速入门(第5章:认证与授权)_Linq_07

任务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

ASP.NET Core快速入门(第5章:认证与授权)_Linq_08

加上token调用
http://localhost:5000/api/values

ASP.NET Core快速入门(第5章:认证与授权)_System_09

ASP.NET Core快速入门(第5章:认证与授权)_Linq_10

token可在官网解密:https://jwt.io

输入正确的SecretKey:Hello-key.jessetalk

ASP.NET Core快速入门(第5章:认证与授权)_Linq_11

任务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,禁止访问

ASP.NET Core快速入门(第5章:认证与授权)_System_12

输入一个正确的mytoken,返回200 OK

ASP.NET Core快速入门(第5章:认证与授权)_System_13

任务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