首页 >后端开发 >C++ >如何在没有 OWIN 中间件的情况下在 ASP.NET Web API 中实现 JWT 身份验证?

如何在没有 OWIN 中间件的情况下在 ASP.NET Web API 中实现 JWT 身份验证?

Barbara Streisand
Barbara Streisand原创
2025-01-20 22:39:12831浏览

How to Implement JWT Authentication in ASP.NET Web API Without OWIN Middleware?

在无OWIN中间件的ASP.NET Web API中实现JWT身份验证

本文介绍如何在旧版ASP.NET Web API中,无需OWIN中间件即可实现JWT身份验证。核心原理是颁发JWT令牌并在收到请求时验证它们。

令牌生成端点

提供一个令牌端点,用户可以在该端点获取JWT令牌,例如使用控制器操作的简单实现:

<code class="language-csharp">public class TokenController : ApiController
{
    [AllowAnonymous]
    public string Get(string username, string password)
    {
        if (CheckUser(username, password))
        {
            return JwtManager.GenerateToken(username);
        }

        throw new HttpResponseException(HttpStatusCode.Unauthorized);
    }

    private bool CheckUser(string username, string password)
    {
        // 应在数据库中进行检查
        return true; //  此处应替换为实际的用户验证逻辑
    }
}</code>

使用System.IdentityModel.Tokens.Jwt生成令牌

使用System.IdentityModel.Tokens.Jwt NuGet包和HMACSHA256对称密钥生成令牌:

<code class="language-csharp">/// <summary>
/// 使用以下代码生成对称密钥
///     var hmac = new HMACSHA256();
///     var key = Convert.ToBase64String(hmac.Key);
/// </summary>
private const string Secret = "db3OIsj+BXE9NZDy0t8W3TcNekrF+2d/1sFnWG4HnV8TZY30iTOdtVWJG8abWvB1GlOgJuQZdcF2Luqm/hccMw==";

public static string GenerateToken(string username, int expireMinutes = 20)
{
    var symmetricKey = Convert.FromBase64String(Secret);
    var tokenHandler = new JwtSecurityTokenHandler();

    var now = DateTime.UtcNow;
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.Name, username)
        }),

        Expires = now.AddMinutes(expireMinutes),

        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(symmetricKey),
            SecurityAlgorithms.HmacSha256Signature)
    };

    var stoken = tokenHandler.CreateToken(tokenDescriptor);
    var token = tokenHandler.WriteToken(stoken);

    return token;
}</code>

使用身份验证过滤器进行JWT验证

为了进行JWT验证,创建一个继承自IAuthenticationFilter的自定义身份验证过滤器:

<code class="language-csharp">public class ValueController : ApiController
{
    [JwtAuthentication] // 自定义过滤器属性
    public string Get()
    {
        return "value";
    }
}</code>

在身份验证过滤器中,实现验证逻辑并返回ClaimsPrincipal

<code class="language-csharp">protected Task<IPrincipal> AuthenticateJwtToken(string token)
{
    string username;

    if (ValidateToken(token, out username))
    {
        // 基于用户名,从数据库获取更多信息以构建本地标识
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username)
            // 根据需要添加更多声明:角色等
        };

        var identity = new ClaimsIdentity(claims, "Jwt");
        IPrincipal user = new ClaimsPrincipal(identity);

        return Task.FromResult(user);
    }

    return Task.FromResult<IPrincipal>(null);
}</code>

使用JWT库进行JWT验证

为了验证JWT令牌并获取ClaimsPrincipal,可以使用JWT库:

<code class="language-csharp">public static ClaimsPrincipal GetPrincipal(string token)
{
    try
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

        if (jwtToken == null)
            return null;

        var symmetricKey = Convert.FromBase64String(Secret);

        var validationParameters = new TokenValidationParameters()
        {
            RequireExpirationTime = true,
            ValidateIssuer = false,
            ValidateAudience = false,
            IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
        };

        SecurityToken securityToken;
        var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);

        return principal;
    }
    catch (Exception)
    {
        // 应写入日志
        return null;
    }
}</code>

授权

为了防止匿名请求,添加以下全局配置:

<code class="language-csharp">config.Filters.Add(new AuthorizeAttribute());</code>

Postman测试

使用Postman请求令牌:

<code>GET http://localhost:{port}/api/token?username=cuong&password=1</code>

在授权请求的标头中使用获取的JWT令牌:

<code>GET http://localhost:{port}/api/value

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImN1b25nIiwibmJmIjoxNDc3NTY1MjU4LCJleHAiOjE0Nzc1NjY0NTgsImlhdCI6MTQ3NzU2NTI1OH0.dSwwufd4-gztkLpttZsZ1255oEzpWCJkayR_4yvNL1s</code>

请注意,代码中的CheckUser方法和错误处理部分需要根据实际应用进行完善。 Secret 密钥也应该存储在更安全的地方,而不是直接硬编码在代码中。 这只是一个简化的示例,实际应用中需要考虑更全面的安全性和错误处理机制。

以上是如何在没有 OWIN 中间件的情况下在 ASP.NET Web API 中实现 JWT 身份验证?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn