首页
学习
活动
专区
圈层
工具
发布

.Net Core2.0Web API使用Identity / JWT并让用户管理器与DI协同工作

.NET Core 2.0 Web API 使用 Identity 和 JWT 认证集成指南

基础概念

ASP.NET Core Identity

ASP.NET Core Identity 是一个成员资格系统,用于处理用户认证和授权。它提供了用户管理功能,包括注册、登录、密码重置等。

JWT (JSON Web Token)

JWT 是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为JSON对象。它通常用于身份验证和信息交换。

实现步骤

1. 安装必要 NuGet 包

代码语言:txt
复制
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt

2. 配置 Identity 和 JWT

Startup.cs 中配置:

代码语言:txt
复制
public void ConfigureServices(IServiceCollection services)
{
    // 添加DbContext
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    // 添加Identity
    services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    // 配置JWT认证
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidAudience = Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
        };
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_0);
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // 其他中间件...

    app.UseAuthentication();
    app.UseMvc();
}

3. 创建 AccountController

代码语言:txt
复制
[Route("api/[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly IConfiguration _configuration;

    public AccountController(
        UserManager<IdentityUser> userManager,
        SignInManager<IdentityUser> signInManager,
        IConfiguration configuration)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _configuration = configuration;
    }

    [HttpPost("register")]
    public async Task<IActionResult> Register([FromBody] RegisterModel model)
    {
        var user = new IdentityUser { UserName = model.Email, Email = model.Email };
        var result = await _userManager.CreateAsync(user, model.Password);

        if (result.Succeeded)
        {
            return Ok(new { Message = "User created successfully" });
        }

        return BadRequest(result.Errors);
    }

    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginModel model)
    {
        var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);

        if (result.Succeeded)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            var token = GenerateJwtToken(user);
            return Ok(new { Token = token });
        }

        return Unauthorized();
    }

    private string GenerateJwtToken(IdentityUser user)
    {
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.Email),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(ClaimTypes.NameIdentifier, user.Id)
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["Jwt:ExpireDays"]));

        var token = new JwtSecurityToken(
            _configuration["Jwt:Issuer"],
            _configuration["Jwt:Audience"],
            claims,
            expires: expires,
            signingCredentials: creds
        );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

public class RegisterModel
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

public class LoginModel
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

4. 保护 API 端点

使用 [Authorize] 属性保护需要认证的端点:

代码语言:txt
复制
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

常见问题及解决方案

1. UserManager 无法通过 DI 注入

原因: 可能没有正确配置 Identity 服务或没有在 Startup.cs 中调用 AddIdentity

解决方案: 确保在 ConfigureServices 方法中正确添加了 Identity 服务:

代码语言:txt
复制
services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

2. JWT 认证无效

原因: 可能 TokenValidationParameters 配置不正确或密钥不匹配。

解决方案: 检查 appsettings.json 中的 JWT 配置:

代码语言:txt
复制
"Jwt": {
  "Key": "YourSecretKeyAtLeast16Characters",
  "Issuer": "YourIssuer",
  "Audience": "YourAudience",
  "ExpireDays": 7
}

3. 跨域问题 (CORS)

解决方案: 在 Startup.cs 中配置 CORS:

代码语言:txt
复制
services.AddCors(options =>
{
    options.AddPolicy("AllowAll",
        builder => builder.AllowAnyOrigin()
                         .AllowAnyMethod()
                         .AllowAnyHeader());
});

// 在 Configure 方法中
app.UseCors("AllowAll");

优势

  1. 安全性: JWT 是无状态的,不需要服务器端存储会话信息
  2. 可扩展性: 适用于分布式系统和微服务架构
  3. 灵活性: 可以包含自定义声明,传递额外用户信息
  4. 标准化: 遵循开放标准,易于与其他系统集成

应用场景

  1. 单页应用程序 (SPA) 认证
  2. 移动应用后端服务
  3. 微服务架构中的服务间认证
  4. 需要无状态认证的分布式系统

最佳实践

  1. 使用 HTTPS 保护 JWT 传输
  2. 设置合理的令牌过期时间
  3. 不要在 JWT 中存储敏感信息
  4. 实现令牌刷新机制
  5. 定期轮换签名密钥
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【壹刊】Azure AD(三)Azure资源的托管标识

下图演示了托管服务标识如何与 Azure 虚拟机 (VM) 协同工作: 3,系统分配托管标识如何与 Azure VM 协同工作 Azure 资源管理器收到请求,要求在 VM 上启用系统分配托管标识。...4,用户分配托管标识如何与 Azure VM 协同工作 Azure 资源管理器收到请求,要求创建用户分配托管标识。...Azure 资源管理器在 Azure AD 中创建与用户分配托管标识相对应的服务主体。 服务主体在此订阅信任的 Azure AD 租户中创建。...Azure 资源管理器收到在 VM 上配置用户分配的托管标识的请求,并使用用户分配的托管标识服务主体客户端 ID 和证书更新 Azure 实例元数据服务标识终结点。...api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -H Metadata:true   可以使用此访问令牌对 Azure

2.5K30
  • .NET 9应用安全实战:构筑金库级防护体系的9大核心策略

    身份验证与授权:构筑安全防线 使用ASP.NET Identity与OAuth 2.0 密码体系暗藏风险,自研身份验证系统更是灾难之源。...坚持使用久经考验的方案:ASP.NET Core Identity和基于OpenID Connect的OAuth 2.0。.NET 9中认证中间件的改进让集成更加丝滑。...最佳实践: • 使用JWT(JSON Web令牌)但需设置较短有效期 • 通过刷新令牌维护会话安全 • 切勿将令牌存入本地存储,改用HttpOnly Cookie 示例:.NET 9中配置JWT认证 services.AddAuthentication...使用AES加密或.NET数据保护API对敏感信息进行加密存储。...示例:使用.NET 9数据保护API加解密 var protector = _dataProtectionProvider.CreateProtector("MyApp.SecretData

    15910

    IdentityServer4 知多少

    质询与应答的工作流程如下:服务器端向客户端返回401(Unauthorized,未授权)状态码,并在WWW-Authenticate头中添加如何进行验证的信息,其中至少包含有一种质询方式。...用户填写凭证信息向客户端授权,认证服务器根据客户端指定的重定向URI,并返回一个【Authorization Code】给客户端。...如果针对控制台客户端应用,三步走就可以访问Api: 使用DiscoverClient发现Token Endpoint 使用TokenClient请求Access Token 使用HttpClient访问...而关于如何与ASP.NET Identity、EF Core集成,本文并未涉及,详参官方文档。...Identity Server 官方文档 dentityServer4 中文文档与实战 ASP.NET Core 认证与授权[4]:JwtBearer认证 Bearer Authentication

    3.4K20

    《ASP.NET Core 微服务实战》-- 读书笔记(第10章)

    ,它规定了身份提供方(IDP)、用户和应用之间的安全通信的规范和标准 使用 OIDC 保障 ASP.NET Core 应用的安全 作为本章第一个代码清单,我们将使用 OIDC 为一个简单的 ASP.NET...ASP.NET Core 使用 Cookie 身份验证和 OpenID Connect 身份验证 添加一个 account 控制器,提供的功能包括登录、注销、以及使用一个视图显示用户身份中的所有特征 using...Core Web 应用,建立了与第三方云友好的身份提供服务的连接 这让云应用能够利用 Bearer 令牌和 OIDC 标准的优势,从手工管理身份验证的负担中解放出来 OIDC 中间件和云原生 我们已经讨论过在使用...首先,只允许通过 SSL 与服务通信 此外,消费服务的代码需要在调用服务时附加凭据 这种凭据通常就是用户名和密码 在一些不存在人工交互的场景中,将其称为客户端标识和客户端密钥更准确 使用 Bearer...令牌保障服务的安全 在服务的 Startup 类型的 Configure 方法中启用并配置 JWT Bearer 身份验证 app.UseJwtBearerAuthentication(new JwtBearerOptions

    2.2K10

    .NET Web 应用程序和 API 的安全最佳实践

    身份验证与授权 保障网络应用程序和 API 的安全,首先要确保只有经过身份验证和授权的用户才能访问敏感资源。.NET 提供了多种方式来实现可靠的身份验证和授权。...ASP.NET Core Identity 如果你需要对用户管理进行更细粒度的控制,ASP.NET Core Identity 是管理用户、角色和声明的首选解决方案。...ASP.NET Core Identity 可与 IdentityServer 结合使用,以应对复杂场景,例如集成外部身份验证提供程序、多因素身份验证(Multi-factor Authentication...安全保障是一项需要持续投入精力的工作,它要求注重细节并使用合适的工具。...通过实施诸如 JWT、OAuth2 和 OpenID Connect 等可靠的身份验证和授权机制,并利用像 IdentityServer 和 ASP.NET Core Identity 这样强大的框架,

    1.2K10

    聊聊统一身份认证服务

    资源(Resources) 使用IdentityServer保护的资源 - 用户的身份数据或服务资源(API)。每个资源都有一个唯一的名称 - 客户端使用此名称来指定他们希望访问哪些资源。...访问令牌包含有关客户端和用户(如果存在)的信息,API使用该信息来授权访问其资源。...质询与应答的工作流程如下:服务器端向客户端返回401(Unauthorized,未授权)状态码,并在WWW-Authenticate头中添加如何进行验证的信息,其中至少包含有一种质询方式。...一种方式是使用Https,另一种方式就是对Token进行加密签名。而JWT就是一种比较流行的Token编码方式。...身份认证服务实践 在ASP.NET Core Wen API应用程序中配置和启用Identity server中间件 ?

    5.8K31

    【One by One系列】IdentityServer4(二)使用Client Credentials保护API资源

    **配置Identity Server Identity资源表示提供给客户端进行用户识别的信息(声明)。声明可能包括用户名称、电子邮件地址等。 API资源表示用户可通过访问令牌访问的受保护数据或功能。...用于签名的凭据(credentials) 用户可能会请求访问的Identity资源和API资源 会请求获取token的客户端 用户信息的存储机制,如ASP.NET Core Identity或者其他机制...Core Identity:结合ASP.NET Core Indentity Empty:空模板 Entity Frame Store:使用ef数据持久化身份认证信息 In-Memory Stores...\webapi\ dotnet run 用vs启动client 获取access-token,我们通过http://jwt.calebb.net/解析 这也是api返回的Claims “身份认证的中间对...JWT进行了身份认证后,会把解析到的Claims组装进HttpContext,以供下一个中间件(如授权中间件)调用 ” 接下来我们就去触发不同的错误去了解IdentityServer是如何工作的,我选择其中几个比较有意义的测试

    2.8K30

    Identity Server 4 - Hybrid Flow - MVC客户端身份验证

    在这里我教它Dave.IdentityProvider.然后选择Empty模板, 并使用ASP.NET Core 2.1:图片点击OK, 项目建立好之后, 为该项目安装Identity Server 4...那么它可以使用Authorization Code Flow或Hybrid Flow.在这里Hybrid Flow是相对高级一些的, 它可以让客户端首先从授权端点获得一个ID Token并通过浏览器(front-channel...当用户需要登陆的时候, 将使用的是OpenId Connect Scheme.然后的AddCookie, 其参数是之前配置的DefaultScheme名称, 这配置了Cookie的处理者, 并让应用程序为我们的...OpenId Connect 协议的处理者.这个处理者会负责创建身份认证请求, Token请求和其它请求, 并负责ID Token的验证工作.它的身份认证scheme就是之前配置的"oidc", 它的意思就是如果该客户端的某部分要求身份认证的时候...URI的长度限制, 所以尽量让token小点, 以免超限.为了获得用户其他的claims, 客户端应用可以使用用户信息端点, 这需要用access token和相关claims对应的scopes.首先在

    2.3K20

    【ASP.NET Core 基础知识】--Web API--Swagger文档生成

    一、ASP.NET Core Web Api中集成Swagger 在ASP.NET Core Web API中集成Swagger是一种有效的方式,通过Swagger能够自动生成、展示并测试API文档。...以下是集成Swagger到ASP.NET Core Web API的基本步骤: 安装Swagger NuGet包: 使用NuGet包管理器或通过命令行工具,在项目中安装Swashbuckle.AspNetCore...使用图表和图形: 使用图表、图形和表格等可视化元素,以更直观地解释API的结构和工作原理。 错误处理说明: 在文档中详细描述错误处理机制,包括可能发生的错误、错误代码、常见问题和解决方案。...这有助于在文档中保护敏感信息,并确保只有经过授权的用户能够查看和使用API。 五、总结 在ASP.NET Core Web API中,通过集成Swagger实现了自动生成API文档的功能。...首先,通过安装Swagger NuGet包,配置Swagger服务和中间件,使其与Web API协同工作。通过XML注释和Swagger注解,提供详尽的API信息,包括操作、响应等。

    1.5K01

    Identity Server 4 - Hybrid Flow - MVC客户端身份验证

    然后选择Empty模板, 并使用ASP.NET Core 2.1: ? 点击OK, 项目建立好之后, 为该项目安装Identity Server 4, 我通过Nuget: ?...每个用户下面还有个Claims属性, claims里面都是代表用户的一些信息. 但是如何让这些claims通过Identity Token返回来呢?...在这里Hybrid Flow是相对高级一些的, 它可以让客户端首先从授权端点获得一个ID Token并通过浏览器(front-channel)传递过来, 这样我们就可以验证这个ID Token....然后的AddCookie, 其参数是之前配置的DefaultScheme名称, 这配置了Cookie的处理者, 并让应用程序为我们的DefaultScheme启用了基于Cookie的身份认证....这个处理者会负责创建身份认证请求, Token请求和其它请求, 并负责ID Token的验证工作.

    3K40

    ASP.NET Core 实战:基于 Jwt Token 的权限控制全揭露

    这个项目中,我将使用 Jwt 的方式实现对于用户的权限管控,在本章中,我将演示如何使用 Jwt 实现对于用户的授权、鉴权。   ...在之前系列开篇文章(ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js,搭建前后端分离框架)进行介绍整个项目框架时曾说到, Grapefruit.Application...同时,因为对于 Jwt 的令牌颁发与鉴权,采用的是微软的 JwtBearer 组件,所以我们在使用前需要先通过 Nuget 将引用添加到 Grapefruit.Application 上。...在中间件进行 Jwt 验证的过程中,会验证授权方式是不是 Bearer 以及通过 token 的属性解密之后与生成时用户数据进行比对,从而判断这个 token 是否有效。...三、总结   本章,主要是使用 Jwt 完成对于用户的授权与鉴权,实现了对于用户 token 令牌的创建、刷新、停用以及校验。

    2.6K20

    .NET Core微服务之基于IdentityServer建立授权与验证服务

    另外savaboard的《ASP.NET Core 之 Identity 入门(一)》和《ASP.NET Core 之 Identity 入门(二)》这两篇也可以一看,对Claims和Identity的基本知识讲的比较通俗易懂...三、Started:第一个AuthorizationServer 1.1 建立一个ASP.NET Core空Web项目   建立ASP.NET Core项目,使用Empty空模板。   ...可以使用这个AuthorizationServer   (2)哪些Client可以使用这个AuthorizationServer   (3)哪些User可以被这个AuthrizationServer识别并授权...复制完成后,我们的项目结构如下图所示: 4.2 修改DI方法   (1)使用MVC与静态文件(由于wwwroot下有很多静态资源文件) public void Configure(IApplicationBuilder...Server4的预备知识》 solenovex,《使用Identity Server 4建立Authorization Server (1)》 solenovex,《使用Identity Server

    2K60

    ASP.NET Core JWT+Cookie双重认证实战指南,Swagger集成与Axios全流程解析

    许多.NET开发者在使用ASP.NET Core Identity实现基础认证时常常陷入困境。...这种方案特别适合需要同时满足API认证和Swagger登录的场景,并附赠SPA应用中使用Axios进行Cookie认证的完整示例。...后端实现 项目初始化 创建.NET 9 Web API项目并安装依赖: dotnet new webapi -n AuthenticationExample --framework net9.0 --use-program-main...核心模型定义 在Infrastructure/Models/User.cs中定义用户模型: using Microsoft.AspNetCore.Identity; namespaceAuthenticationExample.Infrastructure.Models...令牌缓存:对高频访问用户实施JWT缓存机制 2. Cookie安全强化:启用HttpOnly和SameSite严格模式 3. 密钥轮换:定期更新JWT签名密钥 4.

    26010

    以太坊区块链 Asp.Net Core的安全API设计 (上)

    在这种情况下,DApp通过用户的以太坊帐户与智能合约进行交互,并通过交换用户凭据而发布的JWT token与API层进行交互。 ? 目标是使用以太坊帐户作为用户凭据来请求JWT Token。...最简单的方法可能是请求用户使用其他随机生成的数据在以太坊上进行交易,然后在发出JWT之前检查交易和随机数据。这种方法有几个副作用: 1.用户必须进行交易并支付gas以进行简单的身份验证。...这种方式不实用,并且有一些用户体验限制,我们需要一种方法让用户证明他拥有与他想要用来登录的帐户相关的私钥,而不是只(当然)要求私钥,而不管他是否进行交易。...3.开发堆栈:Visual Studio 2017和节点包管理器(NPM)。 4.以太坊/Asp.Net核心/前端开发的基础知识,JWT认证流程的基础知识。...一旦实现,他们将完成相同的工作:从签名中恢复以太坊地址,并检查它是否等于客户端提供的以太坊地址。

    1.3K30
    领券