簡體   English   中英

C#JWT驗證

[英]C# JWT Vertification

我正在嘗試在網站(c#)上進行firebase身份驗證。 我需要驗證登錄令牌。

我可以正常使用令牌,如果我使用令牌和令牌中的公鑰訪問https://jwt.io/ ,它將返回簽名有效。

我的問題是我不知道如何在c#中驗證令牌。

我有以下代碼,這些代碼是我在令牌和公鑰中發送的(沒有--- BEGIN證書和結束證書-)。

我收到錯誤的錯誤序列大小:3參數名稱:seq

我使用的是充氣城堡。 我不知道我要去哪里錯了。 我嘗試證明這一點的所有方法均無效。

我將不勝感激。

謝謝。

public static string Decode(string token,string key, bool verify = true)
    {
        //  HttpContext.Current.Response.Write(key);
        //   HttpContext.Current.Response.End();
        string[] parts = token.Split('.');
        string header = parts[0];
        string payload = parts[1];
        byte[] crypto = Base64UrlDecode(parts[2]);

        string headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
        JObject headerData = JObject.Parse(headerJson);

        string payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
        JObject payloadData = JObject.Parse(payloadJson);

        if (verify)
        {
            var keyBytes = Convert.FromBase64String(key); // your key here

            AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(keyBytes);
            RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)asymmetricKeyParameter;
            RSAParameters rsaParameters = new RSAParameters();
            rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
            rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.ImportParameters(rsaParameters);

            SHA256 sha256 = SHA256.Create();
            byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(parts[0] + '.' + parts[1]));

            RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
            rsaDeformatter.SetHashAlgorithm("SHA256");
            if (!rsaDeformatter.VerifySignature(hash, FromBase64Url(parts[2])))
                throw new ApplicationException(string.Format("Invalid signature"));
        }

        return payloadData.ToString();
    }

    private static byte[] FromBase64Url(string base64Url)
    {
        string padded = base64Url.Length % 4 == 0
            ? base64Url : base64Url + "====".Substring(base64Url.Length % 4);
        string base64 = padded.Replace("_", "/")
                                .Replace("-", "+");
        return Convert.FromBase64String(base64);
    }

    // from JWT spec
    private static byte[] Base64UrlDecode(string input)
    {
        var output = input;
        output = output.Replace('-', '+'); // 62nd char of encoding
        output = output.Replace('_', '/'); // 63rd char of encoding
        switch (output.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 1: output += "==="; break; // Three pad chars
            case 2: output += "=="; break; // Two pad chars
            case 3: output += "="; break; // One pad char
            default: throw new System.Exception("Illegal base64url string!");
        }
        var converted = Convert.FromBase64String(output); // Standard base64 decoder
        return converted;
    }

.NET中有非常好的預定義庫來支持應用程序中的JWT。 System.IdentityModel.Tokens.Jwt和Microsoft.IdentityModel.Tokens具有相當有用的功能。 我最近在WebAPI應用程序中實現了JWT令牌的創建和身份驗證。 我寫這個來驗證JWT。

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;

public class JwtTokenValidator
    {
        public ClaimsPrincipal ValidateToken(string jwtToken)
        {
            SecurityToken securityToken;
            var validationParameters = new TokenValidationParameters()
            {
                ValidIssuer = "ValidTokenIssuerName",
                ValidAudience = "ValidTokenAudienceName",
                ValidateIssuerSigningKey = true,
                ValidateAudience = true,
                ValidateIssuer = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.Default.GetBytes("ValidTokenSigningKey"))
            };

        var recipientTokenHandler = new JwtSecurityTokenHandler();
        var claimsPrincipal = recipientTokenHandler.ValidateToken(jwtToken, validationParameters, out securityToken);
        return claimsPrincipal;
    }
} 

您需要根據用於創建JWT的應用程序使用有效的詳細信息更新上述字符串詳細信息。 我還將分享我編寫的用於從AuthenticationTicket創建JWT的代碼。 希望對您有所幫助。

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin.Security;

public class JwtTokenFormatter : ISecureDataFormat<AuthenticationTicket>
    {
        private readonly JwtSecurityTokenHandler _tokenHandler;
        public JwtTokenFormatter()
        {
            _tokenHandler = new JwtSecurityTokenHandler();

        }
        public string Protect(AuthenticationTicket data)
        {
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Audience = "ValidTokenAudienceName",
                Issuer = "ValidTokenIssuerName",
                IssuedAt = DateTime.UtcNow,
                NotBefore = DateTime.UtcNow,
                Expires = DateTime.UtcNow.AddHours(24),
                Subject = data.Identity,
                SigningCredentials =
                    new SigningCredentials(
                        new SymmetricSecurityKey(Encoding.Default.GetBytes("ValidTokenSigningKey")),
                        SecurityAlgorithms.HmacSha256Signature)
            };

            return _tokenHandler.CreateEncodedJwt(tokenDescriptor);
        }

        public AuthenticationTicket Unprotect(string protectedText)
        {
            throw new NotImplementedException();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM