public static JwtSecurityToken GenerateToken(string username)
        {
            var header = new JwtHeader {
                ["alg"] = "HS256"
            };
            var payload = new JwtPayload(new[] { new Claim("username", username) });
            var hmac    = new HMACSHA256(Secret);
            var hash    = hmac.ComputeHash(Encoding.UTF8.GetBytes(string.Join(".", header.Base64UrlEncode(), payload.Base64UrlEncode())));

            return(new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), System.IdentityModel.Tokens.Base64UrlEncoder.Encode(hash)));
        }
Example #2
0
        public static JwtSecurityToken CreateJwtSecurityToken(string issuer, string audience, IEnumerable <Claim> claims, DateTime?nbf, DateTime?exp, DateTime?iat, SigningCredentials signingCredentials)
        {
            JwtPayload payload = new JwtPayload(issuer, audience, claims, nbf, exp, iat);
            JwtHeader  header  = (signingCredentials != null) ? new JwtHeader(signingCredentials) : new JwtHeader();

            return(new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), ""));
        }
        public async Task <string> BuildSerializedIdTokenAsync(string issuer, string audience, int duration, string userEmail)
        {
            // Parameters that are transmited in the ID Token assertion are communicated as claims
            var claims = new List <System.Security.Claims.Claim>
            {
                new System.Security.Claims.Claim("email", userEmail, System.Security.Claims.ClaimValueTypes.String, issuer)
            };
            var header  = new JwtHeader(_vaultCryptoValues.Value.SigningCredentials);
            var payload = new JwtPayload(
                issuer,
                audience,
                claims,
                DateTime.Now,
                DateTime.Now.AddMinutes(duration));

            // Use the intended JWT Token's Header and Payload value as the data for the token's Signature
            var unsignedTokenText = $"{header.Base64UrlEncode()}.{payload.Base64UrlEncode()}";
            var byteData          = Encoding.UTF8.GetBytes(unsignedTokenText);

            // Use KV Cryptography Client to compute the signature
            var cryptographyClient = _vaultCryptoValues.Value.CryptographyClient;
            // SignData will create the digest and encode it (whereas Sign requires that the digest is computed here and to be sent in.)
            var signatureResult = await cryptographyClient
                                  .SignDataAsync(_vaultCryptoValues.Value.SigningCredentials.Algorithm, byteData)
                                  .ConfigureAwait(false);

            var encodedSignature = Base64UrlEncoder.Encode(signatureResult.Signature);

            // Assemble the header, payload, and encoded signatures
            var result = $"{unsignedTokenText}.{encodedSignature}";

            return(result);
        }
Example #4
0
        public void EmptyToken()
        {
            var handler  = new JwtSecurityTokenHandler();
            var payload  = new JwtPayload();
            var header   = new JwtHeader();
            var jwtToken = new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), "");
            var jwt      = handler.WriteToken(jwtToken);
            var context  = new CompareContext();

            IdentityComparer.AreJwtSecurityTokensEqual(jwtToken, new JwtSecurityToken(handler.WriteToken(jwtToken)), context);
            TestUtilities.AssertFailIfErrors(context.Diffs);
        }
Example #5
0
        public async Task <string> BuildSerializedIdTokenAsync(string issuer, string audience, int duration, string userEmail)
        {
            // Parameters that are transmited in the ID Token assertion are communicated as claims
            var claims = new List <System.Security.Claims.Claim>
            {
                new System.Security.Claims.Claim("email", userEmail, System.Security.Claims.ClaimValueTypes.String, issuer)
            };
            var header  = new JwtHeader(_vaultCryptoValues.Value.SigningCredentials);
            var payload = new JwtPayload(
                issuer,
                audience,
                claims,
                DateTime.Now,
                DateTime.Now.AddMinutes(duration));

            // Use the intended JWT Token's Header and Payload value as the data for the token's Signature
            var unsignedTokenText = $"{header.Base64UrlEncode()}.{payload.Base64UrlEncode()}";
            var byteData          = Encoding.UTF8.GetBytes(unsignedTokenText);

            // Use KV Cryptography Client to compute the signature
            var cryptographyClient = _vaultCryptoValues.Value.CryptographyClient;
            // SignData will create the digest and encode it (whereas Sign requires that the digest is computed here and to be sent in.)
            var signatureResult = await cryptographyClient
                                  .SignDataAsync(_vaultCryptoValues.Value.SigningCredentials.Algorithm, byteData)
                                  .ConfigureAwait(false);

            var encodedSignature = Base64UrlEncoder.Encode(signatureResult.Signature);

            // Alternatively, download the certificate and sign it locally to minimize the request count to the KeyVault instance
            // TODO - Download once - replace ReadCertificate with DownloadCertificate and (CAREFULLY) hold on to the downloaded Private Key
            ////var downloadCertificateResult = _certificateClient.DownloadCertificate(certificateName);   // Use download instead of "Get" to retrieve the full certificate with Private Key.
            ////var downloadedCert = downloadCertificateResult.Value;
            // TODO - Create a local crypto client instance using the RSA Private Key and use it to sign the data
            ////var localCryptographyClient = new Azure.Security.KeyVault.Keys.Cryptography.CryptographyClient(new Azure.Security.KeyVault.Keys.JsonWebKey(downloadedCert.GetRSAPrivateKey()));
            ////var signatureResult = await localCryptographyClient
            ////    .SignDataAsync(_vaultCryptoValues.Value.SigningCredentials.Algorithm, byteData)
            ////    .ConfigureAwait(false);

            // Assemble the header, payload, and encoded signatures
            var result = $"{unsignedTokenText}.{encodedSignature}";

            return(result);
        }
Example #6
0
        public JwtSecurityToken GenerateToken(List <Claim> parametrs)
        {
            if (parametrs == null)
            {
                throw new Exception("Token payload can not be null");
            }

            var header  = new JwtHeader();
            var payload = new JwtPayload("CHNU", string.Empty, parametrs, DateTime.Now, DateTime.Now.AddDays(7));

            header["alg"] = ALGORITHM;
            var encHeader  = header.Base64UrlEncode();
            var encPayload = payload.Base64UrlEncode();


            var token = new JwtSecurityToken(header, payload, encHeader, encPayload,
                                             CryptoProvider.GenerateSHMACHash($"{encHeader}.{encPayload}"));

            return(token);
        }
Example #7
0
        public void EmptyToken()
        {
            var handler  = new JwtSecurityTokenHandler();
            var payload  = new JwtPayload();
            var header   = new JwtHeader();
            var jwtToken = new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), "");
            var jwt      = handler.WriteToken(jwtToken);
            var context  = new CompareContext();

            context.PropertiesToIgnoreWhenComparing = new Dictionary <Type, List <string> >
            {
                { typeof(JwtHeader), new List <string> {
                      "Item"
                  } },
                { typeof(JwtPayload), new List <string> {
                      "Item"
                  } }
            };
            IdentityComparer.AreJwtSecurityTokensEqual(jwtToken, new JwtSecurityToken(handler.WriteToken(jwtToken)), context);
            TestUtilities.AssertFailIfErrors(context.Diffs);
        }
Example #8
0
        public void JwtHeader_SigningKeyIdentifier()
        {
            var           cert                 = KeyingMaterial.DefaultAsymmetricCert_2048;
            var           header               = new JwtHeader(new X509SigningCredentials(cert));
            var           payload              = new JwtPayload(new Claim[] { new Claim("iss", "issuer") });
            var           jwt                  = new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), "");
            var           handler              = new JwtSecurityTokenHandler();
            var           signedJwt            = handler.WriteToken(jwt);
            SecurityToken token                = null;
            var           validationParameters =
                new TokenValidationParameters
            {
                IssuerSigningToken = new X509SecurityToken(cert),
                ValidateAudience   = false,
                ValidateIssuer     = false,
                ValidateLifetime   = false,
            };

            handler.ValidateToken(signedJwt, validationParameters, out token);

            validationParameters =
                new TokenValidationParameters
            {
                IssuerSigningKey = new X509SecurityKey(cert),
                ValidateAudience = false,
                ValidateIssuer   = false,
                ValidateLifetime = false,
            };

            handler.ValidateToken(signedJwt, validationParameters, out token);
        }
        /// <summary>
        /// Uses the <see cref="JwtSecurityToken(JwtHeader, JwtPayload, string, string, string)"/> constructor, first creating the <see cref="JwtHeader"/> and <see cref="JwtPayload"/>.
        /// <para>If <see cref="SigningCredentials"/> is not null, <see cref="JwtSecurityToken.RawData"/> will be signed.</para>
        /// </summary>
        /// <param name="issuer">the issuer of the token.</param>
        /// <param name="audience">the audience for this token.</param>
        /// <param name="subject">the source of the <see cref="Claim"/>(s) for this token.</param>
        /// <param name="notBefore">the notbefore time for this token.</param> 
        /// <param name="expires">the expiration time for this token.</param>
        /// <param name="signingCredentials">contains cryptographic material for generating a signature.</param>
        /// <param name="signatureProvider">optional <see cref="SignatureProvider"/>.</param>
        /// <remarks>If <see cref="ClaimsIdentity.Actor"/> is not null, then a claim { actort, 'value' } will be added to the payload. <see cref="CreateActorValue"/> for details on how the value is created.
        /// <para>See <seealso cref="JwtHeader"/> for details on how the HeaderParameters are added to the header.</para>
        /// <para>See <seealso cref="JwtPayload"/> for details on how the values are added to the payload.</para></remarks>
        /// <para>If signautureProvider is not null, then it will be used to create the signature and <see cref="System.IdentityModel.Tokens.SignatureProviderFactory.CreateForSigning( SecurityKey, string )"/> will not be called.</para>
        /// <returns>A <see cref="JwtSecurityToken"/>.</returns>
        /// <exception cref="ArgumentException">if 'expires' &lt;= 'notBefore'.</exception>
        public virtual JwtSecurityToken CreateToken(string issuer = null, string audience = null, ClaimsIdentity subject = null, DateTime? notBefore = null, DateTime? expires = null, SigningCredentials signingCredentials = null, SignatureProvider signatureProvider = null)
        {
            if (expires.HasValue && notBefore.HasValue)
            {
                if (notBefore >= expires)
                {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10401, expires.Value,  notBefore.Value));
                }
            }

            // if not set, use defaults
            if (!expires.HasValue && !notBefore.HasValue)
            {
                DateTime now = DateTime.UtcNow;
                expires = now + TimeSpan.FromMinutes(TokenLifetimeInMinutes);
                notBefore = now;
            }

            JwtPayload payload = new JwtPayload(issuer, audience, subject == null ? null : subject.Claims, notBefore, expires);
            JwtHeader header = new JwtHeader(signingCredentials);

            if (subject != null && subject.Actor != null)
            {
                payload.AddClaim(new Claim(JwtRegisteredClaimNames.Actort, this.CreateActorValue(subject.Actor)));
            }

            string rawHeader = header.Base64UrlEncode();
            string rawPayload = payload.Base64UrlEncode();
            string rawSignature = string.Empty;
            string signingInput = string.Concat(rawHeader, ".", rawPayload);

            if (signatureProvider != null)
            {
                rawSignature = Base64UrlEncoder.Encode(this.CreateSignature(signingInput, null, null, signatureProvider));
            }
            else if (signingCredentials != null)
            {
                rawSignature = Base64UrlEncoder.Encode(this.CreateSignature(signingInput, signingCredentials.SigningKey, signingCredentials.SignatureAlgorithm, signatureProvider));
            }

            return new JwtSecurityToken(header, payload, rawHeader, rawPayload, rawSignature);
        }
        public void JwtHeader_SigningKeyIdentifier()
        {
            var cert = KeyingMaterial.DefaultAsymmetricCert_2048;
            var header = new JwtHeader(new X509SigningCredentials(cert));
            var payload = new JwtPayload( new Claim[]{new Claim("iss", "issuer")});
            var jwt = new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), "");
            var handler = new JwtSecurityTokenHandler();
            var signedJwt = handler.WriteToken(jwt);
            SecurityToken token = null;
            var validationParameters =
                new TokenValidationParameters
                {
                    IssuerSigningToken = new X509SecurityToken(cert),
                    ValidateAudience = false,
                    ValidateIssuer = false,
                    ValidateLifetime = false,
                };

            handler.ValidateToken(signedJwt, validationParameters, out token);

            validationParameters =
                new TokenValidationParameters
                {
                    IssuerSigningKey = new X509SecurityKey(cert),
                    ValidateAudience = false,
                    ValidateIssuer = false,
                    ValidateLifetime = false,
                };

            handler.ValidateToken(signedJwt, validationParameters, out token);
        }
Example #11
0
 public void JwtEncoding(string testId, JwtHeader header, string encodedData)
 {
     TestUtilities.WriteHeader($"JwtEncoding - {testId}", true);
     Assert.True(encodedData.Equals(header.Base64UrlEncode(), StringComparison.Ordinal), "encodedData.Equals(header.Base64UrlEncode(), StringComparison.Ordinal)");
 }
#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant
        public void JwtEncoding(string testId, JwtHeader header, string encodedData)
        {
            Assert.True(encodedData.Equals(header.Base64UrlEncode(), StringComparison.Ordinal), "encodedData.Equals(header.Base64UrlEncode(), StringComparison.Ordinal)");
        }