Is there any JSON Web Token (JWT) example in C#?

前端 未结 9 2494
悲哀的现实
悲哀的现实 2020-11-28 01:10

I feel like I\'m taking crazy pills here. Usually there\'s always a million library and samples floating around the web for any given task. I\'m trying to implement authenti

9条回答
  •  忘掉有多难
    2020-11-28 01:46

    This is my implementation of (Google) JWT Validation in .NET. It is based on other implementations on Stack Overflow and GitHub gists.

    using Microsoft.IdentityModel.Tokens;
    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Net.Http;
    using System.Security.Claims;
    using System.Security.Cryptography.X509Certificates;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace QuapiNet.Service
    {
        public class JwtTokenValidation
        {
            public async Task> FetchGoogleCertificates()
            {
                using (var http = new HttpClient())
                {
                    var response = await http.GetAsync("https://www.googleapis.com/oauth2/v1/certs");
    
                    var dictionary = await response.Content.ReadAsAsync>();
                    return dictionary.ToDictionary(x => x.Key, x => new X509Certificate2(Encoding.UTF8.GetBytes(x.Value)));
                }
            }
    
            private string CLIENT_ID = "xxx.apps.googleusercontent.com";
    
            public async Task ValidateToken(string idToken)
            {
                var certificates = await this.FetchGoogleCertificates();
    
                TokenValidationParameters tvp = new TokenValidationParameters()
                {
                    ValidateActor = false, // check the profile ID
    
                    ValidateAudience = true, // check the client ID
                    ValidAudience = CLIENT_ID,
    
                    ValidateIssuer = true, // check token came from Google
                    ValidIssuers = new List { "accounts.google.com", "https://accounts.google.com" },
    
                    ValidateIssuerSigningKey = true,
                    RequireSignedTokens = true,
                    IssuerSigningKeys = certificates.Values.Select(x => new X509SecurityKey(x)),
                    IssuerSigningKeyResolver = (token, securityToken, kid, validationParameters) =>
                    {
                        return certificates
                        .Where(x => x.Key.ToUpper() == kid.ToUpper())
                        .Select(x => new X509SecurityKey(x.Value));
                    },
                    ValidateLifetime = true,
                    RequireExpirationTime = true,
                    ClockSkew = TimeSpan.FromHours(13)
                };
    
                JwtSecurityTokenHandler jsth = new JwtSecurityTokenHandler();
                SecurityToken validatedToken;
                ClaimsPrincipal cp = jsth.ValidateToken(idToken, tvp, out validatedToken);
    
                return cp;
            }
        }
    }
    

    Note that, in order to use it, you need to add a reference to the NuGet package System.Net.Http.Formatting.Extension. Without this, the compiler will not recognize the ReadAsAsync<> method.

提交回复
热议问题