65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 上的 JWT Token 安全面试题及答案

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.06/5 (5投票s)

2023年12月21日

CPOL

7分钟阅读

viewsIcon

17644

在本文中,我们将探讨 ASP.NET MVC 中有关安全部分的一些最常被问到的面试问题。

目录

观看 25 个 ASP.NET MVC Core 面试题及实际答案解释。

基于 Token 的身份验证是如何工作的?

基于 Token 的身份验证是一个两步过程。

  1. 客户端向服务器发送凭据。
  2. 服务器响应并返回一个 Token。
  3. 之后,要访问资源,只需要这个 Token。

为什么它被称为 JWT Token?

JWT 是 (JSON Web Token) 的缩写。JSON 是 JavaScript 对象表示法。JSON 是一种具有名称和值的数​​据格式,如下图所示。因为我们以 JSON 格式接收 Token,所以称其为 JWT Token。

解释 JWT Token 的三个部分?

  1. Header (头部):此部分包含算法和 Token 类型。
  2. Payload (载荷):此部分包含身份和声明信息。
  3. Signature (签名):此部分使用前两部分(头部、载荷)和密钥创建。

什么是身份(Identity)和声明(Claims)?

身份唯一地标识用户或实体。声明则描述用户相对于系统的角色/权限。

区分身份验证(Authentication)与授权(Authorization)?

身份验证确保用户存在于系统中。授权则涉及用户的角色和权限。身份验证是关于“用户是谁”,而授权是关于“用户可以使用你的系统做什么”。

声明(Claims)与角色(Roles)?

角色

声明(Claims)

角色(Role)对用户类型进行分类(管理员、用户、超级用户),并为这些用户类型分配角色。 声明(Claims)可以包含权限,但它更多地是关于主题(Subject)的。

声明(Claims)可以包含角色,但并非所有声明(Claims)都是角色。一些不能是角色的声明包括:
浏览器 = Chrome,老年人 = true,已知语言 = English。

角色分配给用户类型。 声明分配给实际用户。

主体(Principal)与身份(Identity)

身份(Identity)代表用户 + 角色 + 声明。主体(Principal)封装了身份对象,并可以分配给代码/线程上下文。

我们可以在 JWT Token 中放入敏感信息吗?

不可以。它只是经过 BASE64 编码,很容易被解码。

如何在 MVC 中创建 JWT Token?

步骤 1:从 Nuget 导入“Microsoft.AspNetCore.Authentication.JwtBearer”包。

步骤 2:使用该包生成 Token。

下面是生成 Token 的示例代码。请记住,这是一次面试,很难详细解释代码,尤其是在口头交流中。因此,最好的方法是将代码与 Token 结构的三个部分进行映射并进行解释。

这将使面试官更容易理解你所说的话。

  • 第一步是选择算法。面试官可能会问你算法的名称。记住 HMACSHA256 并无坏处。
  • 下一步是创建声明集合。请记住,存在标准声明,你也可以添加自己的声明。
  • 最后一步是使用算法、声明来生成 Token。

在 ASP.NET MVC 中,Token 在哪里被检查?

Token 的真实性在管道中被检查。在启动时,我们需要将这个“JwtBearer”检查添加到管道中。

下面是如何在管道中添加它。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Questpond",
ValidAudience = "BrowserClients",
ClockSkew = TimeSpan.Zero,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("victoriasecret@123456"))
};
});

你还需要按照“先身份验证,后授权”的顺序调用“UseAuthentication”和“UseAuthorization”,如下图所示。

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

Authorize 属性有什么用?

JWT Token 身份验证仅应用于那些带有 Authorize 属性的控制器。

[Authorize]
public class ValuesController : ControllerBase
{}

你是如何实现 JWT Token 安全的?

面试官可能会让你总体上谈谈这些步骤。总结一下我们之前三个问题的讨论内容:

  1. 导入“Microsoft.AspNetCore.Authentication.JwtBearer”JWT 包。
  2. 创建 Token 的三个部分。
  3. 在管道中添加 Bearer 检查。
  4. [Authorize] 属性应用于需要保护的控制器。

对于未经授权的访问,你发送什么 HTTP 状态码?

HTTP 401 是表示未经授权访问的状态码。许多开发人员会回答 500,请注意 500 表示内部服务器错误,它代表验证或技术问题。是的,200 表示一切正常。

我们如何从客户端发送 Tokens?

Token 以 W3C 定义的标准格式发送在 REQUEST HEADER 中,如下所示:

Authorization: Bearer XXTokenXX

从 JavaScript、JQuery、Angular 等,Token 是如何传递的?

无论你使用哪种技术,最重要的是需要遵循 W3C 结构,即:

Authorization: Bearer XXTokenXX

下面是使用简单 FETCH API 的代码。

fetch('https://:8080/resourceserver/protected-no-scope', {
method: 'GET',
headers: new Headers({ 'Authorization': 'Bearer <token>',
'Content-Type': 'application/x-www-form-urlencoded'
})
});

JQuery 代码同样需要遵循这个结构。

$.ajax({
url: 'https://:8080/resourceserver/protected-no-scope',
type: 'GET',
contentType: 'application/json'
headers: { 'Authorization': 'Bearer <token>'
},
success: function (result) {
// CallBack(result);
},
error: function (error) {
}
});

Angular 代码大致如下:

var headers_object = new HttpHeaders();
headers_object.append('Content-Type', 'application/json');
headers_object.append("Authorization", "Bearer " + tokenvar);
const httpOptions = {headers: headers_object};
this.http.post(
'https://:8000/api/role/Post', httpOptions
).subscribe(resp => {
this.roles = console.log(resp)
}
);

所以,无论你在使用哪个框架,都可以谈论相关的代码,但要确保你遵循 JWT Token 的结构。

提高移动应用的用户体验,避免重复登录?

使用刷新 Token(Refresh Token)。

什么是刷新 Token(Refresh Token)?

刷新 Token 是一个单独的 Token,你可以用它来获取新的 JWT Token。

区分访问 Token(Access Tokens)和刷新 Token(Refresh Tokens)?

访问 Token(JWT Token)是用于访问受保护资源的 Token,而刷新 Token 用于获取新的 JWT Token。

刷新 Token 是如何工作的?

步骤 1:发送凭据,生成访问 Token + 刷新 Token。

步骤 2:使用访问 Token,客户端现在可以访问资源。

步骤 3:访问 Token 过期。

步骤 4:客户端使用刷新 Token,生成新的访问 Token 和刷新 Token,然后继续步骤 2。

访问 Token 还是刷新 Token 的过期时间更长?

刷新 Token 的过期时间比访问 Token 长。访问 Token 的过期时间应该更短,这样即使有人获得了访问 Token,他们也只有很短的时间窗口来进行攻击。

解释刷新 Token 的吊销(Revocation)?

刷新 Token 的吊销意味着使 Token 失效,无法再创建任何 JWT Token。用户需要重新进行身份验证才能获取新的刷新 Token。

如何从 Token 中提取主体(Principal)?

你可以使用“TokenHandler”类来提取“Principal”和“Token”。

在客户端存储 Token 的最佳实践是什么?

内存存储:在应用程序运行时,可以使用应用程序变量来存储 Token。

Cookie:如果你仍然想存储,Cookie 是一个不错的选择。

IndexedDB、Session storage 和 local storage 容易受到 XSS 攻击。

如果我们将 JWT 存储在 Cookie 中,如何防止 XX 攻击?

创建 HTTP Only Cookie。通过这样做,JavaScript 无法通过“document.cookie”读取此 Cookie。换句话说,Cookie 可以防止 XSS 攻击。

OAUTH vs OpenID vs OpenIdConnect vs JWTToken?

OpenIdOAuthOpenIdConnect 是协议,而 JWTToken 只是一个 Token。

  1. OpenId 专注于身份验证。
  2. OAuth 专注于授权。
  3. OpenId Connect 则同时包含两者。

什么时候应该使用什么?

  • OpenId (谁?):你只想知道用户是否存在于系统中。例如,购物网站、移动应用程序、单点登录等。
  • OAuth (什么?):当第三方应用程序尝试访问资源时。
  • OpenIDConnect:当你既需要身份验证也需要授权时,例如在内网网站中。

什么是身份服务器(Identity Server)?

Identity Server 是一个免费的开源服务器,有助于实现 OpenID Connect 和 OAuth。

如何实现单点登录(Single Sign on)?

对于单点登录,身份验证/授权服务器应该是独立的。希望属于同一个联合体的网站与这个集中的身份验证/授权服务器建立信任关系。

许多开发人员使用 IdentityServer 来实现单点登录。

在身份服务器(IdentityServer)中,什么是作用域(Scope)?

作用域(Scope)就是角色。

如需进一步阅读,请观看下面的面试准备视频和逐步视频系列。

© . All rights reserved.