예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="JwtHeader"/> class. With the Header Parameters as follows:
        /// <para>{ { typ, JWT }, { alg, Mapped( <see cref="System.IdentityModel.Tokens.SigningCredentials.SignatureAlgorithm"/> } }
        /// See: Algorithm Mapping below.</para>
        /// </summary>
        /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that will be or were used to sign the <see cref="JwtSecurityToken"/>.</param>
        /// <remarks>
        /// <para>For each <see cref="SecurityKeyIdentifierClause"/> in signingCredentials.SigningKeyIdentifier</para>
        /// <para>if the clause  is a <see cref="NamedKeySecurityKeyIdentifierClause"/> Header Parameter { clause.Name, clause.KeyIdentifier } will be added.</para>
        /// <para>For example, if clause.Name == 'kid' and clause.KeyIdentifier == 'SecretKey99'. The JSON object { kid, SecretKey99 } would be added.</para>
        /// <para>In addition, if the <see cref="SigningCredentials"/> is a <see cref="X509SigningCredentials"/> the JSON object { x5t, Base64UrlEncoded( <see cref="X509Certificate.GetCertHashString()"/> } will be added.</para>
        /// <para>This simplifies the common case where a X509Certificate is used.</para>
        /// <para>================= </para>
        /// <para>Algorithm Mapping</para>
        /// <para>================= </para>
        /// <para><see cref="System.IdentityModel.Tokens.SigningCredentials.SignatureAlgorithm"/> describes the algorithm that is discoverable by the CLR runtime.</para>
        /// <para>The  { alg, 'value' } placed in the header reflects the JWT specification.</para>
        /// <see cref="JwtSecurityTokenHandler.OutboundAlgorithmMap"/> contains a signature mapping where the 'value' above will be translated according to this mapping.
        /// <para>Current mapping is:</para>
        /// <para>&#160;&#160;&#160;&#160;'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' => 'RS256'</para>
        /// <para>&#160;&#160;&#160;&#160;'http://www.w3.org/2001/04/xmldsig-more#hmac-sha256' => 'HS256'</para>
        /// </remarks>
        public JwtHeader(SigningCredentials signingCredentials = null)
            : base(StringComparer.Ordinal)
        {
            this.Add(JwtConstants.ReservedHeaderParameters.Type, JwtConstants.HeaderType);

            if (signingCredentials != null)
            {
                this.signingCredentials = signingCredentials;

                string algorithm = signingCredentials.SignatureAlgorithm;
                if (JwtSecurityTokenHandler.OutboundAlgorithmMap.ContainsKey(signingCredentials.SignatureAlgorithm))
                {
                    algorithm = JwtSecurityTokenHandler.OutboundAlgorithmMap[algorithm];
                }

                this.Add(JwtConstants.ReservedHeaderParameters.Algorithm, algorithm);
                if (signingCredentials.SigningKeyIdentifier != null)
                {
                    foreach (SecurityKeyIdentifierClause clause in signingCredentials.SigningKeyIdentifier)
                    {
                        NamedKeySecurityKeyIdentifierClause namedKeyClause = clause as NamedKeySecurityKeyIdentifierClause;
                        if (namedKeyClause != null)
                        {
                            this.Add(namedKeyClause.Name, namedKeyClause.KeyIdentifier);
                        }
                    }
                }

                X509SigningCredentials x509SigningCredentials = signingCredentials as X509SigningCredentials;
                if (x509SigningCredentials != null && x509SigningCredentials.Certificate != null)
                {
                    this.Add(JwtConstants.ReservedHeaderParameters.X509CertificateThumbprint, Base64UrlEncoder.Encode(x509SigningCredentials.Certificate.GetCertHash()));
                }
            }
            else
            {
                this.Add(JwtConstants.ReservedHeaderParameters.Algorithm, JwtConstants.Algorithms.NONE);
            }
        }
예제 #2
0
 /// <summary>
 /// Encodes this instance as a Base64UrlEncoded string.
 /// </summary>
 /// <remarks>Returns the current state. If this instance has changed since the last call, the value will be different.</remarks>
 /// <returns>a string BaseUrlEncoded representing the contents of this header.</returns>
 public string Encode()
 {
     return(Base64UrlEncoder.Encode(this.SerializeToJson()));
 }
 /// <summary>
 /// Deserializes Base64UrlEncoded JSON into a <see cref="JwtPayload"/> instance.
 /// </summary>
 /// <param name="base64UrlEncodedJsonString">base64url encoded JSON to deserialize.</param>
 /// <returns>an instance of <see cref="JwtPayload"/>.</returns>
 /// <remarks>use <see cref="JsonExtensions.Deserializer"/> to customize JSON serialization.</remarks>
 public static JwtPayload Base64UrlDeserialize(string base64UrlEncodedJsonString)
 {
     return(JsonExtensions.DeserializeJwtPayload(Base64UrlEncoder.Decode(base64UrlEncodedJsonString)));
 }
        /// <summary>
        /// Decodes the string into the header, payload and signature
        /// </summary>
        /// <param name="jwtEncodedString">Base64Url encoded string.</param>
        internal void Decode(string jwtEncodedString)
        {
            string[] tokenParts = jwtEncodedString.Split(new char[] { '.' }, 4);
            if (tokenParts.Length != 3)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10709, "jwtEncodedString", jwtEncodedString));
            }

            try
            {
                this.header = JwtHeader.Base64UrlDeserialize(tokenParts[0]);

                // if present, "typ" should be set to "JWT" or "http://openid.net/specs/jwt/1.0"
                string type = this.header.Typ;
                if (type != null)
                {
                    if (!(StringComparer.Ordinal.Equals(type, JwtConstants.HeaderType) || StringComparer.Ordinal.Equals(type, JwtConstants.HeaderTypeAlt)))
                    {
                        throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10702, JwtConstants.HeaderType, JwtConstants.HeaderTypeAlt, type));
                    }
                }
            }
            catch (Exception ex)
            {
                if (DiagnosticUtility.IsFatal(ex))
                {
                    throw;
                }

                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "header", tokenParts[0], jwtEncodedString), ex);
            }

            try
            {
                this.payload = JwtPayload.Base64UrlDeserialize(tokenParts[1]);
            }
            catch (Exception ex)
            {
                if (DiagnosticUtility.IsFatal(ex))
                {
                    throw;
                }

                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "payload", tokenParts[1], jwtEncodedString), ex);
            }

            // ensure signature is well-formed, GitIssue 103
            if (!string.IsNullOrEmpty(tokenParts[2]))
            {
                try
                {
                    Base64UrlEncoder.Decode(tokenParts[2]);
                }
                catch (Exception ex)
                {
                    if (DiagnosticUtility.IsFatal(ex))
                    {
                        throw;
                    }

                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "signature", tokenParts[1], jwtEncodedString), ex);
                }
            }

            this.rawData      = jwtEncodedString;
            this.rawHeader    = tokenParts[0];
            this.rawPayload   = tokenParts[1];
            this.rawSignature = tokenParts[2];
        }
 /// <summary>
 /// Encodes this instance as Base64UrlEncoded JSON.
 /// </summary>
 /// <returns>Base64UrlEncoded JSON.</returns>
 /// <remarks>use <see cref="JsonExtensions.Serializer"/> to customize JSON serialization.</remarks>
 public virtual string Base64UrlEncode()
 {
     return(Base64UrlEncoder.Encode(SerializeToJson()));
 }