ASP.NET Core Web API用户身份验证

一、JWT介绍

ASP.NET Core Web API用户身份验证的方法有很多,本文只介绍JWT方法。JWT实现了服务端无状态,在分布式服务、会话一致性、单点登录等方面凸显优势,不占用服务端资源。简单来说,JWT的验证过程如下所示:

(1)通过用户名和密码获取一个Token。

(2)访问API时,加上这个Token。

Token包含过期时间、用户角色等信息,可以在多种场合灵活使用。

二、基本认证

2.1 场景描述

在基本认证的场景中,我们假设有一个Controller,代码如下所示:

[ApiController]
[Route("test")]
public class TestController : ControllerBase
{
    [HttpGet]
    public string Get()
    {
        return "success";
    }
}

这个Controller非常简单,就是访问之后返回"success"这个字符串。

现在,我们希望用户登录之后(提供用户名和密码)才能使用此API。

2.2 开发步骤

1、在NuGet中添加Microsoft.AspNetCore.Authentication.JwtBearer。

2、在Program.cs中,对builder.Services添加认证服务:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt =>
    {
        opt.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = false,
            ValidateIssuerSigningKey = false
        };
    });

在上面的参数中,可以根据使用场景进行灵活配置,这个后面会介绍。在此,使用最简单的配置。

3、同样在Program.cs中,添加以下语句:

app.UseAuthentication();

需要注意的是,此句需要在页面路由之前,例如是app.UseHttpsRedirection();之前,如下所示:

app.UseAuthentication();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

4、在需要认证的Controller或某个具体方法上加上[Authorize]标记。例如我们在一开始介绍的API上加上标记:

[Authorize]
[HttpGet]
public string Get()
{
    return "success";
}

此时,如果再去访问此API,就会返回401没有权限的错误。

5、创建登录的Controller,也就是通过用户名和密码获取Token。

[Route("api/auth")]
[ApiController]
public class AuthController : ControllerBase
{
    [HttpPost]
    public string Gettoken(string username, string password)
    {
        if (username == "admin" && password == "123456")
        {
            var claims = new[]{
                new Claim(ClaimTypes.Name, username)
            };
            var jwttoken = new JwtSecurityToken(
                claims: claims
            );
            var token = new JwtSecurityTokenHandler().WriteToken(jwttoken);
            return token;
        }
        return "用户不存在或密码错误";
    }
}

上面的用户认证简单的做了字符串比对,实际上可以通过查数据库的方法验证用户是否合法。

至此,用户验证的后端就开发完成了。

三、前端访问API

3.1 通过Swagger测试

很多时候,我们使用Swagger来测试API,但默认的Swagger配置没有用户验证,需要进行添加。

打开Program.cs,把builder.Services.AddSwaggerGen();这一句修改为:

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

此时,打开Swagger,就会看到右上角有一个Authorize的按钮,如下图所示:

点击按钮,会要求输入一个Token。我们从上面写的登录Controller(AuthController)获取。如下图所示:

 最下面的响应字符串就是我们要的Token。把这个Token填入到上面弹出的对话框中,注意需要在字符串前加上“Bearer ”。如下图所示:

此时,再去访问TestController,就会返回成功结果。

3.2 前端访问方法

 在无用户验证要求的时候,前端访问TestController的代码如下所示:

fetch("https://localhost:28911/test", {
    method: "GET"
}).then(resp => {
    return resp.text();
}).then(data => {
    console.log(data);
}).catch(err => {
    console.log(err)
});

API前加上[Authorize]之后,上述调用也会返回401错误。上述调用需要把Token加入到Header中。

fetch("https://localhost:28911/test", {
    method: "GET",
    headers: {
        "Authorization": "Bearer eyJhbGciOiJ...太长,Token后面省略"
    }
}).then(resp => {
    return resp.text();
}).then(data => {
    console.log(data);
}).catch(err => {
    console.log(err)
});

此时,即可再次成功获取结果。

四、常见用户身份验证场景

4.1 Token有效期

一般情况下,通过用户名和密码得到了Token之后,我们不希望这个Token是永久有效的。也就是说,过了一段时间之后,Token失效,用户需要重新登录。

需要增加有效期,有几处地方需要修改。

首先是Program.cs中,原来的配置如下所示:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt =>
    {
        opt.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = false,
            ValidateIssuerSigningKey = false
        };
    });

需要把ValidateLifetime改为true:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt =>
    {
        opt.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.FromSeconds(30),
        };
    });

然后在AuthController的Gettoken方法里,加上有效期:

var claims = new[]{
    new Claim(JwtRegisteredClaimNames.Nbf,new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()) ,
    new Claim(JwtRegisteredClaimNames.Exp,new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds().ToString()),
    new Claim(ClaimTypes.Name, username)
};

上面配置的有效期是30分钟。

至此,当获得一个新的Token之后,经过30分钟,这个Token就无法使用了。

4.2 第三方验证

很多网站上提供QQ登录、微信登录、微博登录等功能,我们以微信登录进行说明。如果我们需要使用微信登录,需要到微信开发者平台注册,拿到一个叫AppKey的东西。这个AppKey相当于一个私钥,是不能让别人看到的。因为我们要使用微信的登录验证服务,这个服务不能向任何人提供,而且需要区分是哪个第三方在使用服务。

为了实现上述功能,认证时加入了一个IssUser的概念,也就是哪些APP可以调用服务。

在Program.cs中,修改配置:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(opt =>
    {
        opt.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidateAudience = false,
            ValidateLifetime = false,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "App名称",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("App私钥"))
        };
    });

然后,在Gettoken时,进行修改:

var claims = new[]{
    new Claim(ClaimTypes.Name, username)
};
var m5dkey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("App私钥"));
var creds = new SigningCredentials(m5dkey, SecurityAlgorithms.HmacSha256);
var jwttoken = new JwtSecurityToken(
    issuer: "App名称",
    claims: claims,
    expires: DateTime.Now.AddMinutes(30),
    signingCredentials: creds
);
var token = new JwtSecurityTokenHandler().WriteToken(jwttoken);
return token;

4.3 角色或权限

很多时候,用户登录之后,并不是可以访问所有的API。用户可以分出不同的角色,不同的角色可以访问不同的资源。

要做到这一点,首先在Gettoken时,把用户的角色加入到Token中。

var claims = new[]{
    new Claim(ClaimTypes.Name, username),
    new Claim("Role", "admin")
};

然后,在API前,指明此资源需要什么角色。

[Authorize(Roles = "admin")]
[HttpGet]
public string Get()
{
    return "success";
}

这样,按角色分配资源的功能就完成了。

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: ASP.NET Core Web API 是一种用于构建 Web API 的框架。它是微软开发的一个开源框架,旨在提供高性能、可扩展性和可靠性,支持跨平台开发,并且易于使用。 ASP.NET Core Web API 基于 .NET Core 平台,可以运行在 Windows、Linux 和 macOS 等多个操作系统上。它支持使用 C# 或者其他 .NET 支持的语言进行开发,并且提供了许多开箱即用的功能,如模型绑定、身份验证、授权、路由等等。 使用 ASP.NET Core Web API,你可以构建 RESTful API,支持多种数据格式,如 JSON、XML 等等。你还可以轻松地集成其他框架和工具,如 Swagger、Entity Framework Core、SignalR 等等。 总之,ASP.NET Core Web API 是一个功能强大、灵活、易于使用的框架,非常适合构建 Web API。 ### 回答2: ASP.NET Core Web API 是微软推出的一种服务器端的轻量级框架,用于构建基于 RESTful 的 Web API。该框架建立在 .NET Core 上,并具有很好的可扩展性和灵活性,可适用于跨平台开发。 ASP.NET Core Web API 的主要特点包括: 1. 开箱即用的依赖注入:该框架提供了一个内置的依赖注入容器,使得 DI 可以轻松地集成到 Web API 的开发中。 2. 轻量级:由于底层是使用 .NET Core 构建的,因此 ASP.NET Core Web API 框架非常灵活、快速、轻量级,并且能够满足高并发访问的需求。 3. 跨平台支持:ASP.NET Core Web API 是跨平台的,可以运行在 Windows、Linux 和 macOS 等操作系统上。 4. 开放式标准:该框架遵循开放式的标准,并支持多种数据格式、服务器框架和插件。 5. 网络安全:ASP.NET Core Web API 提供了多种安全功能,包括认证、授权和加密等,以保护 Web 应用程序免受网络攻击。 总之,ASP.NET Core Web API 框架是一个方便、快捷、灵活和高性能的框架,适用于构建任何规模的 Web API 应用程序。与此同时,该框架还提供了良好的文档和社区支持,愿意学习的开发者可以通过微软的官方文档和各种社区论坛,快速上手并掌握该框架的使用。 ### 回答3: ASP.NET Core Web API是一个开放源代码跨平台的Web框架,用于开发基于HTTP协议的RESTful服务,并支持各种客户端,包括Web界面及流行语言开发的客户端应用程序。其已经成为目前.NET生态系统中最重要的发展方向之一。 相比于传统的.NET框架,ASP.NET Core Web API具有以下几个优点: 1. 跨平台:在Linux、Mac、Windows等平台上都可以运行,且不必担心所使用的系统版本问题; 2. 高性能:ASP.NET Core Web API在响应请求方面有极佳的性能,对于高并发访问的场景有着不错的表现; 3. 轻量级:ASP.NET Core Web API具有比传统的.NET框架更轻量级的特点,其运行时占用的硬盘空间和内存资源更少; 4. 便于部署:用Docker等虚拟化容器将应用打包后部署非常简单,不需要过多的配置,适用于现代化的云端应用场景。 在开发方面,ASP.NET Core Web API提供了丰富的工具和库,使Web API的开发效率更高,且可用于多种类型的Web应用程序,例如单页应用程序、移动客户端、大型企业软件等。通过使用ASP.NET Core Web API,开发人员可以轻松创建高效稳定的Web服务和RESTful APIs。 总之,ASP.NET Core Web API是一个反应迅速、易于扩展的开发框架,不仅能够加速Web应用程序的开发工作,更能够提供高性能的Web服务,从而大大提升用户体验。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值