/// <summary> /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class specifying optional parameters. /// </summary> /// <param name="issuer">if this value is not null, a { iss, 'issuer' } claim will be added.</param> /// <param name="audience">if this value is not null, a { aud, 'audience' } claim will be added</param> /// <param name="claims">if this value is not null then for each <see cref="Claim"/> a { 'Claim.Type', 'Claim.Value' } is added. If duplicate claims are found then a { 'Claim.Type', List<object> } will be created to contain the duplicate values.</param> /// <param name="expires">if expires.HasValue a { exp, 'value' } claim is added.</param> /// <param name="notBefore">if notbefore.HasValue a { nbf, 'value' } claim is added.</param> /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that will be used to sign the <see cref="JwtSecurityToken"/>. See <see cref="JwtHeader(SigningCredentials)"/> for details pertaining to the Header Parameter(s).</param> /// <exception cref="ArgumentException">if 'expires' <= 'notbefore'.</exception> public JwtSecurityToken(string issuer = null, string audience = null, IEnumerable <Claim> claims = null, DateTime?notBefore = null, DateTime?expires = null, SigningCredentials signingCredentials = null) { if (expires.HasValue && notBefore.HasValue) { if (notBefore >= expires) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10401, expires.Value, notBefore.Value)); } } this.payload = new JwtPayload(issuer: issuer, audience: audience, claims: claims, notBefore: notBefore, expires: expires); this.header = new JwtHeader(signingCredentials); }
/// <summary> /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class where the <see cref="JwtHeader"/> contains the crypto algorithms applied to the encoded <see cref="JwtHeader"/> and <see cref="JwtPayload"/>. The jwtEncodedString is the result of those operations. /// </summary> /// <param name="header">Contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT</param> /// <param name="payload">Contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value }</param> /// <exception cref="ArgumentNullException">'header' is null.</exception> /// <exception cref="ArgumentNullException">'payload' is null.</exception> public JwtSecurityToken(JwtHeader header, JwtPayload payload) { if (header == null) { throw new ArgumentNullException("header"); } if (payload == null) { throw new ArgumentNullException("payload"); } this.header = header; this.payload = payload; }
/// <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]; }