Swagger UI 加上驗證按鈕,讓 Request Header 傳遞 Authorize Token

 

以下為個人實際在使用 Swagger 這套件的用法流程,感謝神人的文章參考。

一、開一 ASP.NET MVC Core 6.0 新專案
我知道 Webapi 專案本身就有內建 Swagger 了,為了學習故使用 MVC 專案。

二、添加 swagger 套件
請於 Nuget 安裝 Swashbuckle.AspNetCore 套件

三、於 Program.cs 注冊與使用 swagger

1
builder.Services.AddSwaggerGen(); // 註冊 Swagger
1
2
3
4
5
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});


四、於檢視 swagger 畫面
https://localhost:7233/swagger/index.html

五、接下來要添加 swagger authorization button 功能了,
於 Program.cs 添加 swagger authorization button 與打 api 之附加 token 設定

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
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("Bearer",
new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.Http,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization"
});
options.AddSecurityRequirement(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
}); // 註冊 Swagger


六、準備 授權與驗證 token api

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
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace WebApplication1.ApiControllers
{
[Route("Api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpPost("Login")]
public async Task<IActionResult> Login()
{
var (role, accountName, token) = GenerateToken();
return Ok(new { role, accountName, token });
}

private (string, string, string) GenerateToken()
{
string role = "Manager";
string accountName = "John";
var claims = new Claim[]
{
new Claim("AccountId", "123"),
new Claim("AccountName", accountName),
new Claim(ClaimTypes.Role, role)
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("the-secret-length-must-greater-or-equal-32"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

var token = new JwtSecurityToken(
"JwtTokenConfig:Issuer",
"JwtTokenConfig:Audience",
claims,
expires: DateTime.Now.AddDays(30),
signingCredentials: creds
);

return (role, accountName, new JwtSecurityTokenHandler().WriteToken(token));
}

[Authorize(Roles = "Manager")]
[HttpPost("FilterRole")]
public async Task<IActionResult> GetName()
{
return Ok(new { Message = "Hi, Manager" });
}
}
}


七、於 Program.cs 添加 api 守門員

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
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Audience = "JwtTokenConfig:Audience";

jwtOptions.RequireHttpsMetadata = true;
jwtOptions.SaveToken = true;
jwtOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "JwtTokenConfig:Issuer",
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes("the-secret-length-must-greater-or-equal-32")),
ValidAudiences = new List<string> {
"JwtTokenConfig:Audience"
},
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMilliseconds(1)
};
});
builder.Services.AddAuthentication();


八、記得於 Program.cs 啟用驗證與授權功能

1
2
3
app.UseAuthentication();
app.UseAuthorization();

九、最後我們可以於 Authorize 的按紐,點擊輸入我們獲取到的 Jwt Token,在輸入框內不需要特別加上 Bearer 關鍵字,Swagger 會自動為我們加上 Bearer 關鍵字。

十、整個 Program.cs 內容如下參考

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
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("Bearer",
new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.Http,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization"
});
options.AddSecurityRequirement(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
}
});
}); // 註冊 Swagger

builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.Audience = "JwtTokenConfig:Audience";

jwtOptions.RequireHttpsMetadata = true;
jwtOptions.SaveToken = true;
jwtOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "JwtTokenConfig:Issuer",
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes("the-secret-length-must-greater-or-equal-32")),
ValidAudiences = new List<string> {
"JwtTokenConfig:Audience"
},
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMilliseconds(1)
};
});
builder.Services.AddAuthentication();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

參考資料:
菜雞新訓記 (4): 使用 Swagger 來自動產生可互動的 API 文件吧
在 Swagger UI 加上驗證按鈕,讓 Request Header 傳遞 Authorize Token