首页 >后端开发 >C++ >如何在 IIS 上托管的 ASP.NET Web API 中实现 JWT 不记名令牌身份验证?

如何在 IIS 上托管的 ASP.NET Web API 中实现 JWT 不记名令牌身份验证?

DDD
DDD原创
2025-01-20 22:47:09548浏览

How to Implement JWT Bearer Token Authentication in ASP.NET Web API Hosted on IIS?

在IIS上托管的ASP.NET Web API中实现JWT Bearer令牌身份验证

在IIS上托管的ASP.NET Web API中实现JWT bearer令牌身份验证,与.NET Core或OWIN应用程序相比,需要采用不同的方法。本文提供了一个全面的指南,介绍如何实现这种身份验证机制,并解答关键问题:

如何生成JWT令牌?

要生成JWT令牌,可以使用System.IdentityModel.Tokens.Jwt NuGet包。以下是用HMACSHA256和对称密钥的示例:

<code class="language-csharp">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(Convert.ToInt32(expireMinutes)),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature)
    };

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

    return token;
}</code>

如何提供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);
    }

    public bool CheckUser(string username, string password)
    {
        // 应该在数据库中检查
        return true;
    }
}</code>

如何验证JWT令牌?

另一种方法是创建一个从IAuthenticationFilter继承的JWTAuthenticationAttribute:

<code class="language-csharp">private static bool ValidateToken(string token, out string username)
{
    username = null;

    var simplePrinciple = JwtManager.GetPrincipal(token);
    var identity = simplePrinciple.Identity as ClaimsIdentity;

    if (identity == null || !identity.IsAuthenticated)
        return false;

    var usernameClaim = identity.FindFirst(ClaimTypes.Name);
    username = usernameClaim?.Value;

    if (string.IsNullOrEmpty(username))
        return false;

    // 更多验证以检查系统中用户名是否存在

    return true;
}

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>

此属性可以应用于特定操作:

<code class="language-csharp">public class ValueController : ApiController
{
    [JwtAuthentication]
    public string Get()
    {
        return "value";
    }
}</code>

通过中间件或DelegateHandler验证JWT令牌?

OWIN中间件或DelegateHandler也可以用于验证Web API的所有传入请求。

验证JWT令牌

以下代码验证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>

授权

请记住全局添加config.Filters.Add(new AuthorizeAttribute()); 以防止匿名请求。

以上是如何在 IIS 上托管的 ASP.NET Web API 中实现 JWT 不记名令牌身份验证?的详细内容。更多信息请关注PHP中文网其他相关文章!

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