public void JwtPalyoad_Claims()
        {
            List<string> errors = new List<string>();
            var jwtPayload = new JwtPayload();

            // multiple audiences
            foreach (string aud in IdentityUtilities.DefaultAudiences)
            {
                jwtPayload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, aud));
            }

            string encodedPayload = jwtPayload.Base64UrlEncode();
            var deserializedPayload = JwtPayload.Base64UrlDeserialize(encodedPayload);

            if (!IdentityComparer.AreEqual(jwtPayload, deserializedPayload))
            {
                errors.Add("!IdentityComparer.AreEqual(jwtPayload, deserializedPayload)");
            }

            if (!IdentityComparer.AreEqual<IEnumerable<string>>(jwtPayload.Aud, IdentityUtilities.DefaultAudiences))
            {
                errors.Add("!IdentityComparer.AreEqual<IEnumerable<string>>(jwtPayload.Aud, IdentityUtilities.DefaultAudiences)");
            }

            TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors);
        }
        private async Task <string> CreateJwtToken(Identity identity)
        {
            var now = DateTime.UtcNow;

            var claims = new List <Claim>
            {
                SubjectClaim(identity),
                await NonceClaim(),
                IssuedTimestampClaim(now),
                NameClaim(identity)
            };

            var notBefore       = now.AddSeconds(-1);
            var tokenExpiration = now.Add(options.Expiration);

            var payload = new JwtPayload(options.Issuer, options.Audience, claims, notBefore, tokenExpiration);

            identity.Roles.ToList().ForEach(r =>
                                            payload.AddClaim(new Claim(ClaimTypes.Role, r))
                                            );

            if (identity.NeedsPasswordChange)
            {
                payload.AddClaim(new Claim(CustomClaimTypes.NeedsPasswordChange, "true"));
            }

            var jwtToken        = new JwtSecurityToken(new JwtHeader(options.SigningCredentials), payload);
            var jwtTokenHandler = new JwtSecurityTokenHandler();

            return(jwtTokenHandler.WriteToken(jwtToken));
        }
        public static void SetClaimValue <T>(this JwtPayload payload, string type, T value)
        {
            if (payload.ContainsKey(type))
            {
                payload.Remove(type);
            }

            if (typeof(T) == typeof(string))
            {
                var stringValue = value?.ToString();
                if (!string.IsNullOrWhiteSpace(stringValue))
                {
                    payload.AddClaim(new Claim(type, stringValue, ClaimValueTypes.String));
                }
            }
            else if (typeof(T) == typeof(int))
            {
                payload.AddClaim(new Claim(type, value.ToString(), ClaimValueTypes.Integer));
            }
            else if (typeof(T).IsArray)
            {
                payload.AddClaim(new Claim(type, JsonConvert.SerializeObject(value, Settings), JsonClaimValueTypes.JsonArray));
            }
            else
            {
                var json = JsonConvert.SerializeObject(value, Settings);
                payload.AddClaim(new Claim(type, json, JsonClaimValueTypes.Json));
            }
        }
        public void JwtPayload_Claims()
        {
            List <string> errors     = new List <string>();
            var           jwtPayload = new JwtPayload();

            // multiple audiences
            foreach (string aud in IdentityUtilities.DefaultAudiences)
            {
                jwtPayload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, aud));
            }

            string encodedPayload      = jwtPayload.Base64UrlEncode();
            var    deserializedPayload = JwtPayload.Base64UrlDeserialize(encodedPayload);

            if (!IdentityComparer.AreEqual(jwtPayload, deserializedPayload))
            {
                errors.Add("!IdentityComparer.AreEqual(jwtPayload, deserializedPayload)");
            }

            if (!IdentityComparer.AreEqual <IEnumerable <string> >(jwtPayload.Aud, IdentityUtilities.DefaultAudiences))
            {
                errors.Add("!IdentityComparer.AreEqual<IEnumerable<string>>(jwtPayload.Aud, IdentityUtilities.DefaultAudiences)");
            }

            TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors);
        }
Example #5
0
        public string Generate(Roles roles = Roles.Admin, string?name = default, TimeSpan?expiry = default)
        {
            var expirySeconds = (int)DateTime.UtcNow
                                .Add(expiry ?? _defaultExpiry)
                                .Subtract(DateTime.UnixEpoch)
                                .TotalSeconds;

            var payload = new JwtPayload
            {
                ["exp"] = expirySeconds,
                ["iss"] = _issuer,
                ["aud"] = _audience,
            };

            payload.AddClaims(from r in roles.Expand()
                              let s                 = r.ToString("G")
                                              let c = new Claim(ClaimTypes.Role, s)
                                                      select c);

            if (!string.IsNullOrWhiteSpace(name))
            {
                var claim = new Claim(ClaimTypes.NameIdentifier, name);
                payload.AddClaim(claim);
            }

            var secToken = new JwtSecurityToken(_header, payload);
            var handler  = new JwtSecurityTokenHandler();

            return(handler.WriteToken(secToken));
        }
Example #6
0
        public JWT Create(IDictionary <string, string> claims)
        {
            var nowUtc       = DateTime.UtcNow;
            var expires      = nowUtc.AddDays(_settings.ExpiryDays);
            var centuryBegin = new DateTime(1970, 1, 1);
            var exp          = (long)(new TimeSpan(expires.Ticks - centuryBegin.Ticks).TotalSeconds);
            var now          = (long)(new TimeSpan(nowUtc.Ticks - centuryBegin.Ticks).TotalSeconds);
            var issuer       = _settings.Issuer ?? string.Empty;
            var payload      = new JwtPayload();

            foreach (var claimDict in claims)
            {
                payload.AddClaim(new Claim(claimDict.Key, claimDict.Value));
            }

            var jwt   = new JwtSecurityToken(_jwtHeader, payload);
            var token = _jwtSecurityTokenHandler.WriteToken(jwt);



            return(new JWT
            {
                Token = token,
                Expires = exp
            });
        }
        public async Task <TokenResponse> GetAccessTokenAsync(string clientId, string accessTokenEndpoint, string scope, string keyVaultKeyString)
        {
            TokenResponse errorResponse = ValidateParameters((nameof(clientId), clientId), (nameof(accessTokenEndpoint), accessTokenEndpoint), (nameof(scope), scope), (nameof(keyVaultKeyString), keyVaultKeyString));

            if (errorResponse != null)
            {
                return(errorResponse);
            }

            // Use a signed JWT as client credentials.
            var payload = new JwtPayload();

            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, clientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, clientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, accessTokenEndpoint));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString(), ClaimValueTypes.Integer64));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString(), ClaimValueTypes.Integer64));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString(), ClaimValueTypes.Integer64));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Jti, CryptoRandom.CreateUniqueId()));

            var handler     = new JwtSecurityTokenHandler();
            var credentials = GetSigningCredentialsFromKeyVault(keyVaultKeyString);
            var jwt         = handler.WriteToken(new JwtSecurityToken(new JwtHeader(credentials), payload));

            var request = new JwtClientCredentialsTokenRequest {
                Address = accessTokenEndpoint, ClientId = clientId, Jwt = jwt, Scope = scope
            };

            return(await _httpClientFactory
                   .CreateClient(EdnaExternalHttpHandler.Name)
                   .RequestClientCredentialsTokenWithJwtAsync(request));
        }
        /// <summary>
        /// Get an access token from the issuer.
        /// </summary>
        /// <param name="issuer">The issuer.</param>
        /// <param name="scope">The scope to request.</param>
        /// <returns>The token response.</returns>
        public async Task <TokenResponse> GetAccessTokenAsync(string issuer, string scope)
        {
            // Use a signed JWT as client credentials.
            var payload = new JwtPayload();

            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, _oidcModel.ClientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, _oidcModel.ClientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, _oidcModel.Audience));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString()));
            var bytes = CryptoRandom.CreateRandomKey(32);
            var jti   = Base64Url.Encode(bytes);

            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Jti, jti));

            var handler = new JwtSecurityTokenHandler();
            var rsaKey  = _rsaKeyService.GetKey();
            var jwt     = handler.WriteToken(new JwtSecurityToken(new JwtHeader(new SigningCredentials(rsaKey, SecurityAlgorithms.RsaSha512)), payload));

            var httpClient = _httpClientFactory.CreateClient();

            return(await httpClient.RequestClientCredentialsTokenWithJwtAsync(
                       new JwtClientCredentialsTokenRequest
            {
                Address = _oidcModel.AccessTokenUrl,
                ClientId = _oidcModel.ClientId,
                Jwt = jwt,
                Scope = scope
            }));
        }
Example #9
0
        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="userName">登录用户名</param>
        /// <param name="tokenInfos"></param>
        /// <param name="expDays">有效天数</param>
        /// <returns></returns>
        public static string GenerateToken(String userName, List <TokenInfo> tokenInfos, int expDays = 30)
        {
            var credentials = new SigningCredentials
                                  (securityKey, SecurityAlgorithms.HmacSha384);


            var header = new JwtHeader(credentials);


            var payload = new JwtPayload();
            var now     = WIPCommon.GetUnixTimeStampWithGLWZForSeconds().ToString();
            // 30天过期
            var exp = long.Parse(now) + (expDays * 24 * 60 * 60);//单位:秒

            //注释下面的代码 [EditBy shaocx,2019-01-07]

            /*
             * if (userName.Contains("integrated"))
             * {
             *  exp = long.Parse(now) + 31536000;
             * }
             * //*/
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, now));            //发布时间
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, exp.ToString())); //到期时间
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, WIP));            //发行人
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, userName));       //主题
            // 追加自定义字段 数据库字段
            payload.AddClaim(new Claim("username", userName));                        //自定义对象之用户名称
            // 自动获取payload
            if (tokenInfos != null)
            {
                payload.Add("usergroup", tokenInfos);//自定义对象之用户角色集合
            }
            else
            {
                payload.Add("usergroup", getTokenInfos(userName));//自定义对象之用户角色集合
            }
            var secToken = new JwtSecurityToken(header, payload);
            var handler  = new JwtSecurityTokenHandler();

            String tokenString = handler.WriteToken(secToken);

            return(tokenString);
        }
Example #10
0
        /// <summary>
        /// Get an access token from the issuer.
        /// </summary>
        /// <param name="issuer">The issuer.</param>
        /// <param name="scope">The scope to request.</param>
        /// <returns>The token response.</returns>
        public async Task <TokenResponse> GetAccessTokenAsync(string signingIssuer, string issuer, string scope)
        {
            if (issuer.IsMissing())
            {
                return(TokenResponse.FromException <TokenResponse>(new ArgumentNullException(nameof(issuer))));
            }

            if (scope.IsMissing())
            {
                return(TokenResponse.FromException <TokenResponse>(new ArgumentNullException(nameof(scope))));
            }

            var platform = await _context.GetPlatformByIssuerAsync(issuer);

            if (platform == null)
            {
                return(TokenResponse.FromException <TokenResponse>(new Exception("Cannot find platform registration.")));
            }

            // Use a signed JWT as client credentials.
            var payload = new JwtPayload();

            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, signingIssuer));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, platform.ClientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, platform.AccessTokenUrl));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Jti, CryptoRandom.CreateUniqueId(32)));

            var handler     = new JwtSecurityTokenHandler();
            var credentials = PemHelper.SigningCredentialsFromPemString(platform.PrivateKey);
            var jwt         = handler.WriteToken(new JwtSecurityToken(new JwtHeader(credentials), payload));


            var jwtClientCredentials = new JwtClientCredentialsTokenRequest
            {
                Address         = platform.AccessTokenUrl,
                ClientId        = platform.ClientId,
                Jwt             = jwt,
                Scope           = scope,
                ClientAssertion = new ClientAssertion()
                {
                    Type = OidcConstants.ClientAssertionTypes.JwtBearer, Value = jwt
                },
                Parameters = !string.IsNullOrWhiteSpace(scope) ? new Dictionary <string, string>()
                {
                    { OidcConstants.TokenRequest.Scope, scope }
                } : null,
                GrantType = OidcConstants.GrantTypes.ClientCredentials
            };

            var httpClient = _httpClientFactory.CreateClient();

            return(await httpClient.RequestTokenAsync(jwtClientCredentials, default)); //RequestClientCredentialsTokenWithJwtAsync(jwtClientCredentials);
        }
Example #11
0
        /// <summary>
        /// Get an access token from the issuer.
        /// </summary>
        /// <param name="issuer">The issuer.</param>
        /// <param name="scopes">The scopes to request.</param>
        /// <param name="clientId">The tool's client identifier.</param>
        /// <param name="accessTokenUrl">The platform's access token url.</param>
        /// <param name="privateKey">The tool's private key.</param>
        /// <returns>The token response.</returns>
        public static async Task <TokenResponse> GetAccessTokenAsync(string issuer, string[] scopes, string clientId, string accessTokenUrl, string privateKey)
        {
            if (issuer.IsMissing())
            {
                return(new TokenResponse(new ArgumentNullException(nameof(issuer))));
            }

            if (scopes == null)
            {
                return(new TokenResponse(new ArgumentNullException(nameof(scopes))));
            }

            if (clientId.IsMissing())
            {
                return(new TokenResponse(new ArgumentNullException(nameof(clientId))));
            }

            if (accessTokenUrl.IsMissing())
            {
                return(new TokenResponse(new ArgumentNullException(nameof(accessTokenUrl))));
            }

            if (privateKey.IsMissing())
            {
                return(new TokenResponse(new ArgumentNullException(nameof(privateKey))));
            }

            // Use a signed JWT as client credentials.
            var payload = new JwtPayload();

            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, clientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, clientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, accessTokenUrl));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf,
                                       EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString(), ClaimValueTypes.Integer64));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp,
                                       EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString(), ClaimValueTypes.Integer64));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Jti, CryptoRandom.CreateRandomKeyString(32)));

            var handler     = new JwtSecurityTokenHandler();
            var credentials = PemHelper.SigningCredentialsFromPemString(privateKey);
            var jwt         = handler.WriteToken(new JwtSecurityToken(new JwtHeader(credentials), payload));

            return(await HttpClient.RequestClientCredentialsTokenWithJwtAsync(
                       new JwtClientCredentialsTokenRequest
            {
                Address = accessTokenUrl,
                ClientId = clientId,
                Jwt = jwt,
                Scope = string.Join(" ", scopes)
            }));
        }
Example #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public Jwt Generate(List <Claim> claims)
        {
            if (claims == null || !claims.Any())
            {
                throw new ArgumentNullException(nameof(claims));
            }

            var now           = DateTime.UtcNow;
            var timespan      = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1));
            var unixTimestamp = (int)timespan.TotalSeconds;

            var tokenGenerationOptions = new TokenGenerationOptions();
            var tokenOptions           = new TokenOptions();

            var jwtHeader = new JwtHeader(tokenGenerationOptions.SigningCredentials);
            var payload   = new JwtPayload(
                issuer: tokenOptions.Issuer,
                audience: tokenOptions.Audience,
                claims: claims,
                notBefore: now,
                expires: now.Add(tokenGenerationOptions.Expiration));

            payload.AddClaim(new Claim("jti", Guid.NewGuid().ToString()));
            payload.AddClaim(new Claim("iat", unixTimestamp.ToString()));

            var jwt        = new JwtSecurityToken(jwtHeader, payload);
            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            var jwtDto = new Jwt
            {
                AccessToken = encodedJwt,
                Schema      = "Bearer"
            };

            return(jwtDto);
        }
Example #13
0
        private JwtPayload CreateJwtPayload(User user)
        {
            var payload = new JwtPayload();

            payload.AddClaim(new Claim("email", user.Email, ClaimValueTypes.Email));
            payload.AddClaim(new Claim("userId", user.Id.ToString()));
            payload.AddClaim(new Claim("firstName", user.FirstName));
            payload.AddClaim(new Claim("secondName", user.LastName));
            payload.AddClaim(new Claim("isConfirmed", user.IsEmailConfirm.ToString(), ClaimValueTypes.Boolean));
            payload.AddClaim(new Claim("photoUrl", user.PhotoUrl ?? ""));
            payload.AddClaim(new Claim("inviteLink", user.InviteLink ?? ""));

            payload.AddClaims(user.UserRoles.Select(i => new Claim("roles", i.Role.ToString())));

            return(payload);
        }
Example #14
0
        /// <summary>
        /// Create and sign JWT token.
        /// </summary>
        public static JwtSecurityToken CreateToken(MSTokens.SecurityKey securityKey, string issuer, IEnumerable <string> audiences, IEnumerable <Claim> claims, DateTimeOffset?issuedAt = null, int beforeIn = 60, int expiresIn = 3600,
                                                   string algorithm = IdentityConstants.Algorithms.Asymmetric.RS256, string typ = IdentityConstants.JwtHeaders.MediaTypes.Jwt)
        {
            if (securityKey == null)
            {
                throw new ArgumentNullException(nameof(securityKey));
            }
            if (issuer.IsNullOrEmpty())
            {
                throw new ArgumentNullException(nameof(issuer));
            }
            if (audiences?.Count() < 1)
            {
                throw new ArgumentException($"At least one audience is required.", nameof(audiences));
            }
            if (claims?.Count() < 1)
            {
                throw new ArgumentException($"At least one claim is required.", nameof(claims));
            }

            var key    = securityKey is MSTokens.JsonWebKey jsonWebKey ? jsonWebKey.ToSecurityKey() : securityKey;
            var header = new JwtHeader(new MSTokens.SigningCredentials(key, algorithm));

            if (!typ.IsNullOrEmpty())
            {
                header[IdentityConstants.JwtHeaders.Typ] = typ;
            }

            if (!issuedAt.HasValue)
            {
                issuedAt = DateTimeOffset.UtcNow;
            }
            var payload = new JwtPayload(issuer, audiences.First(), claims, issuedAt.Value.AddSeconds(-beforeIn).UtcDateTime, issuedAt.Value.AddSeconds(expiresIn).UtcDateTime, issuedAt.Value.UtcDateTime);

            if (audiences.Count() > 1)
            {
                foreach (var audience in audiences.Skip(1))
                {
                    payload.AddClaim(new Claim(JwtClaimTypes.Audience, audience));
                }
            }
            return(new JwtSecurityToken(header, payload));
        }
        /// <summary>
        /// Get an access token from the issuer.
        /// </summary>
        /// <param name="issuer">The issuer.</param>
        /// <param name="scope">The scope to request.</param>
        /// <returns>The token response.</returns>
        public async Task <TokenResponse> GetAccessTokenAsync(string issuer, string scope)
        {
            if (issuer.IsMissing())
            {
                return(new TokenResponse(new ArgumentNullException(nameof(issuer))));
            }

            if (scope.IsMissing())
            {
                return(new TokenResponse(new ArgumentNullException(nameof(scope))));
            }

            var platform = await _context.GetPlatformByIssuerAsync(issuer);

            if (platform == null)
            {
                return(new TokenResponse(new Exception("Cannot find platform registration.")));
            }

            // Use a signed JWT as client credentials.
            var payload = new JwtPayload();

            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, platform.ClientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, platform.ClientId));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, platform.AccessTokenUrl));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString()));
            payload.AddClaim(new Claim(JwtRegisteredClaimNames.Jti, CryptoRandom.CreateRandomKeyString(32)));

            var handler     = new JwtSecurityTokenHandler();
            var credentials = PemHelper.SigningCredentialsFromPemString(platform.PrivateKey);
            var jwt         = handler.WriteToken(new JwtSecurityToken(new JwtHeader(credentials), payload));

            var httpClient = _httpClientFactory.CreateClient();

            return(await httpClient.RequestClientCredentialsTokenWithJwtAsync(
                       new JwtClientCredentialsTokenRequest
            {
                Address = platform.AccessTokenUrl,
                ClientId = platform.ClientId,
                Jwt = jwt,
                Scope = scope
            }));
        }
Example #16
0
        /// <summary>
        /// Create and sign JWT token.
        /// </summary>
        public static JwtSecurityToken CreateToken(SecurityKey securityKey, string issuer, IEnumerable <string> audiences, IEnumerable <Claim> claims, DateTimeOffset?issuedAt = null, int beforeIn = 60, int expiresIn = 3600, string algorithm = IdentityConstants.Algorithms.Asymmetric.RS256, string x509CertificateSHA1Thumbprint = null)
        {
            if (securityKey == null)
            {
                new ArgumentNullException(nameof(securityKey));
            }
            if (issuer.IsNullOrEmpty())
            {
                new ArgumentNullException(nameof(issuer));
            }
            if (audiences?.Count() < 1)
            {
                throw new ArgumentException($"At least one audience is required.", nameof(audiences));
            }
            if (claims?.Count() < 1)
            {
                throw new ArgumentException($"At least one claim is required.", nameof(claims));
            }

            var header = new JwtHeader(new SigningCredentials(securityKey, algorithm));

            x509CertificateSHA1Thumbprint = x509CertificateSHA1Thumbprint ?? GetX509CertificateSHA1Thumbprint(securityKey);
            if (!x509CertificateSHA1Thumbprint.IsNullOrEmpty())
            {
                header.Add(IdentityConstants.JwtHeaders.X509CertificateSHA1Thumbprint, x509CertificateSHA1Thumbprint);
            }

            if (!issuedAt.HasValue)
            {
                issuedAt = DateTimeOffset.UtcNow;
            }
            var payload = new JwtPayload(issuer, audiences.First(), claims, issuedAt.Value.AddSeconds(-beforeIn).UtcDateTime, issuedAt.Value.AddSeconds(expiresIn).UtcDateTime, issuedAt.Value.UtcDateTime);

            if (audiences.Count() > 1)
            {
                foreach (var audience in audiences.Skip(1))
                {
                    payload.AddClaim(new Claim(JwtClaimTypes.Audience, audience));
                }
            }
            return(new JwtSecurityToken(header, payload));
        }
Example #17
0
        public string GetSignedAndEncodedToken(LoggedInApplication loggedInApp)
        {
            // Get application
            var consumerApplication = _applications.FirstOrDefault(i => i.ID == loggedInApp.ID);

            // Get applciation token
            var applicationToken = _applicationTokens.FirstOrDefault(i => i.Token == loggedInApp.TokenUsedToAuthorize);

            // Get schemas from approved
            var providerLicenseIds = _consumerRegistrationRequests.Where(i => i.ConsumerApplicationID == consumerApplication.ID)
                                     .Where(i => i.Status == (int)ConsumerProviderRegistrationStatus.Approved)
                                     .Select(i => i.OrganizationLicenseID);

            var schemasFromProviderLicenses = new List <int>();

            foreach (var providerLicenseId in providerLicenseIds)
            {
                var providerLicense = _organisationLicenses.GetById(providerLicenseId);
                schemasFromProviderLicenses.Add(providerLicense.DataSchemaID);
            }

            // Get schemas for each agreements
            var schemasFromAgreements = schemasFromProviderLicenses.Distinct().ToList();

            // Filter schemas
            var schemaIds = schemasFromAgreements.Distinct();

            // Setup software statement schemas
            var schemas = new List <SoftwareStatementSchema>();

            foreach (var schemaId in schemaIds)
            {
                var schema        = _dataSchemas.FirstOrDefault(i => i.ID == schemaId);
                var schemaDetails = schema.ToStmtSchema();
                schemas.Add(schemaDetails);
            }

            // Software statement will expire in 5 years for now.
            var time        = GetDate.AddYears(5) - new DateTime(1970, 1, 1);
            var expireEpoch = (int)time.TotalSeconds;

            var signingCredentials = new SigningCredentials(GetSigningKey(),
                                                            SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest);

            // Create Software Statement.
            var header  = new JwtHeader(signingCredentials);
            var payload = new JwtPayload();

            payload.AddClaim(new Claim("software_id", consumerApplication.PublicID.ToString()));
            payload.AddClaim(new Claim("client_name", consumerApplication.Name));
            payload.AddClaim(new Claim("client_uri", applicationToken.OriginHost));
            payload.AddClaim(new Claim("iss", "42e01f09-0dea-42b2-b5e1-0f1e87547329"));
            payload.AddClaim(new Claim("sub", "10e5766e-aff1-4b2e-b926-1a1b4ccf566c"));
            payload.AddClaim(new Claim("aud", "urn:oauth:scim:reg:generic"));
            payload.AddClaim(new Claim("exp", expireEpoch.ToString()));
            payload.AddClaim(new Claim("schemas", JsonConvert.SerializeObject(schemas)));
            payload.Base64UrlEncode();
            var jwt = new JwtSecurityToken(header, payload);

            // Sign Software Statement.
            var tokenHandler          = new JwtSecurityTokenHandler();
            var signedAndEncodedToken = tokenHandler.WriteToken(jwt);

            return(signedAndEncodedToken);
        }
        private JwtPayload doBuildPayload(PrivateClaims privateClaims, JWTOptions options)
        {
            JwtPayload payload = new JwtPayload();
            // ****START BUILD PAYLOAD****//
            // Adding private claims
            List <Claim> privateC = privateClaims.getAllClaims();

            foreach (Claim privateClaim in privateC)
            {
                if (privateClaim.getNestedClaims() != null)
                {
                    payload.Add(privateClaim.getKey(), privateClaim.getNestedClaims().getNestedMap());
                }
                else
                {
                    System.Security.Claims.Claim netPrivateClaim = null;
                    object obj = privateClaim.getValue();
                    if (obj.GetType() == typeof(string))
                    {
                        netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), (string)privateClaim.getValue());
                    }
                    else if (obj.GetType() == typeof(int))
                    {
                        int value = (int)obj;
                        netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(), System.Security.Claims.ClaimValueTypes.Integer32);
                    }
                    else if (obj.GetType() == typeof(long))
                    {
                        long value = (long)obj;
                        netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(), System.Security.Claims.ClaimValueTypes.Integer64);
                    }
                    else if (obj.GetType() == typeof(double))
                    {
                        double value = (double)obj;
                        netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(), System.Security.Claims.ClaimValueTypes.Double);
                    }
                    else if (obj.GetType() == typeof(bool))
                    {
                        bool value = (bool)obj;
                        netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), value.ToString(), System.Security.Claims.ClaimValueTypes.Boolean);
                    }
                    else
                    {
                        this.error.setError("JW012", "Unrecognized data type");
                    }

                    //System.Security.Claims.Claim netPrivateClaim = new System.Security.Claims.Claim(privateClaim.getKey(), privateClaim.getValue());

                    payload.AddClaim(netPrivateClaim);
                }
            }
            // Adding public claims
            if (options.hasPublicClaims())
            {
                PublicClaims publicClaims = options.getAllPublicClaims();
                List <Claim> publicC      = publicClaims.getAllClaims();
                foreach (Claim publicClaim in publicC)
                {
                    System.Security.Claims.Claim netPublicClaim = new System.Security.Claims.Claim(publicClaim.getKey(), (string)publicClaim.getValue());
                    payload.AddClaim(netPublicClaim);
                }
            }
            // Adding registered claims
            if (options.hasRegisteredClaims())
            {
                RegisteredClaims registeredClaims = options.getAllRegisteredClaims();
                List <Claim>     registeredC      = registeredClaims.getAllClaims();
                foreach (Claim registeredClaim in registeredC)
                {
                    System.Security.Claims.Claim netRegisteredClaim;

                    if (RegisteredClaimUtils.isTimeValidatingClaim(registeredClaim.getKey()))
                    {
                        netRegisteredClaim = new System.Security.Claims.Claim(registeredClaim.getKey(), (string)registeredClaim.getValue(), System.Security.Claims.ClaimValueTypes.Integer32);
                    }
                    else
                    {
                        netRegisteredClaim = new System.Security.Claims.Claim(registeredClaim.getKey(), (string)registeredClaim.getValue());
                    }

                    payload.AddClaim(netRegisteredClaim);
                }
            }
            // ****END BUILD PAYLOAD****//
            return(payload);
        }
        /// <summary>
        /// Creates the JWT payload
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>The JWT payload</returns>
        protected virtual Task <JwtPayload> CreatePayloadAsync(Token token)
        {
            var payload = new JwtPayload(
                token.Issuer,
                null,
                null,
                IdentityServerDateTime.UtcNow,
                IdentityServerDateTime.UtcNow.AddSeconds(token.Lifetime));

            foreach (var aud in token.Audiences)
            {
                payload.AddClaim(new Claim(JwtClaimTypes.Audience, aud));
            }

            var amrClaims   = token.Claims.Where(x => x.Type == JwtClaimTypes.AuthenticationMethod);
            var scopeClaims = token.Claims.Where(x => x.Type == JwtClaimTypes.Scope);
            var jsonClaims  = token.Claims.Where(x => x.ValueType == IdentityServerConstants.ClaimValueTypes.Json);

            var normalClaims = token.Claims
                               .Except(amrClaims)
                               .Except(jsonClaims)
                               .Except(scopeClaims);

            payload.AddClaims(normalClaims);

            // scope claims
            if (!scopeClaims.IsNullOrEmpty())
            {
                var scopeValues = scopeClaims.Select(x => x.Value).ToArray();
                payload.Add(JwtClaimTypes.Scope, scopeValues);
            }

            // amr claims
            if (!amrClaims.IsNullOrEmpty())
            {
                var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray();
                payload.Add(JwtClaimTypes.AuthenticationMethod, amrValues);
            }

            // deal with json types
            // calling ToArray() to trigger JSON parsing once and so later
            // collection identity comparisons work for the anonymous type
            var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray();

            var jsonObjects      = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Object).ToArray();
            var jsonObjectGroups = jsonObjects.GroupBy(x => x.Type).ToArray();

            foreach (var group in jsonObjectGroups)
            {
                if (payload.ContainsKey(group.Key))
                {
                    throw new Exception(String.Format("Can't add two claims where one is a JSON object and the other is not a JSON object ({0})", group.Key));
                }

                if (group.Skip(1).Any())
                {
                    // add as array
                    payload.Add(group.Key, group.Select(x => x.JsonValue).ToArray());
                }
                else
                {
                    // add just one
                    payload.Add(group.Key, group.First().JsonValue);
                }
            }

            var jsonArrays      = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Array).ToArray();
            var jsonArrayGroups = jsonArrays.GroupBy(x => x.Type).ToArray();

            foreach (var group in jsonArrayGroups)
            {
                if (payload.ContainsKey(group.Key))
                {
                    throw new Exception(String.Format("Can't add two claims where one is a JSON array and the other is not a JSON array ({0})", group.Key));
                }

                List <JToken> newArr = new List <JToken>();
                foreach (var arrays in group)
                {
                    var arr = (JArray)arrays.JsonValue;
                    newArr.AddRange(arr);
                }

                // add just one array for the group/key/claim type
                payload.Add(group.Key, newArr.ToArray());
            }

            var unsupportedJsonTokens     = jsonTokens.Except(jsonObjects).Except(jsonArrays);
            var unsupportedJsonClaimTypes = unsupportedJsonTokens.Select(x => x.Type).Distinct();

            if (unsupportedJsonClaimTypes.Any())
            {
                throw new Exception(String.Format("Unsupported JSON type for claim types: {0}", unsupportedJsonClaimTypes.Aggregate((x, y) => x + ", " + y)));
            }

            return(Task.FromResult(payload));
        }
        /// <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);
        }
Example #21
0
        /// <summary>
        /// Creates the default JWT payload.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="clock">The clock.</param>
        /// <param name="options">The options</param>
        /// <param name="logger">The logger.</param>
        /// <returns></returns>
        /// <exception cref="Exception">
        /// </exception>
        public static JwtPayload CreateJwtPayload(this Token token, ISystemClock clock, IdentityServerOptions options, ILogger logger)
        {
            var payload = new JwtPayload(
                token.Issuer,
                null,
                null,
                clock.UtcNow.UtcDateTime,
                clock.UtcNow.UtcDateTime.AddSeconds(token.Lifetime));

            foreach (var aud in token.Audiences)
            {
                payload.AddClaim(new Claim(JwtClaimTypes.Audience, aud));
            }

            var amrClaims   = token.Claims.Where(x => x.Type == JwtClaimTypes.AuthenticationMethod).ToArray();
            var scopeClaims = token.Claims.Where(x => x.Type == JwtClaimTypes.Scope).ToArray();
            var jsonClaims  = token.Claims.Where(x => x.ValueType == IdentityServerConstants.ClaimValueTypes.Json).ToList();

            // add confirmation claim if present (it's JSON valued)
            if (token.Confirmation.IsPresent())
            {
                jsonClaims.Add(new Claim(JwtClaimTypes.Confirmation, token.Confirmation, IdentityServerConstants.ClaimValueTypes.Json));
            }

            var normalClaims = token.Claims
                               .Except(amrClaims)
                               .Except(jsonClaims)
                               .Except(scopeClaims);

            payload.AddClaims(normalClaims);

            // scope claims
            if (!scopeClaims.IsNullOrEmpty())
            {
                var scopeValues = scopeClaims.Select(x => x.Value).ToArray();

                if (options.EmitScopesAsSpaceDelimitedStringInJwt)
                {
                    payload.Add(JwtClaimTypes.Scope, string.Join(" ", scopeValues));
                }
                else
                {
                    payload.Add(JwtClaimTypes.Scope, scopeValues);
                }
            }

            // amr claims
            if (!amrClaims.IsNullOrEmpty())
            {
                var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray();
                payload.Add(JwtClaimTypes.AuthenticationMethod, amrValues);
            }

            // deal with json types
            // calling ToArray() to trigger JSON parsing once and so later
            // collection identity comparisons work for the anonymous type
            try
            {
                var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray();

                var jsonObjects      = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Object).ToArray();
                var jsonObjectGroups = jsonObjects.GroupBy(x => x.Type).ToArray();
                foreach (var group in jsonObjectGroups)
                {
                    if (payload.ContainsKey(group.Key))
                    {
                        throw new Exception($"Can't add two claims where one is a JSON object and the other is not a JSON object ({group.Key})");
                    }

                    if (group.Skip(1).Any())
                    {
                        // add as array
                        payload.Add(group.Key, group.Select(x => x.JsonValue).ToArray());
                    }
                    else
                    {
                        // add just one
                        payload.Add(group.Key, group.First().JsonValue);
                    }
                }

                var jsonArrays      = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Array).ToArray();
                var jsonArrayGroups = jsonArrays.GroupBy(x => x.Type).ToArray();
                foreach (var group in jsonArrayGroups)
                {
                    if (payload.ContainsKey(group.Key))
                    {
                        throw new Exception(
                                  $"Can't add two claims where one is a JSON array and the other is not a JSON array ({group.Key})");
                    }

                    var newArr = new List <JToken>();
                    foreach (var arrays in group)
                    {
                        var arr = (JArray)arrays.JsonValue;
                        newArr.AddRange(arr);
                    }

                    // add just one array for the group/key/claim type
                    payload.Add(group.Key, newArr.ToArray());
                }

                var unsupportedJsonTokens     = jsonTokens.Except(jsonObjects).Except(jsonArrays).ToArray();
                var unsupportedJsonClaimTypes = unsupportedJsonTokens.Select(x => x.Type).Distinct().ToArray();
                if (unsupportedJsonClaimTypes.Any())
                {
                    throw new Exception(
                              $"Unsupported JSON type for claim types: {unsupportedJsonClaimTypes.Aggregate((x, y) => x + ", " + y)}");
                }

                return(payload);
            }
            catch (Exception ex)
            {
                logger.LogCritical(ex, "Error creating a JSON valued claim");
                throw;
            }
        }
Example #22
0
        public static JwtPayload CreateJwtPayload(
            this Token token,
            DateTime?creationTime,
            ILogger logger)
        {
            var utcNow  = DateTime.UtcNow;
            var iat     = creationTime ?? utcNow;
            var payload = new JwtPayload(
                token.Issuer,
                null,
                null,
                utcNow,
                utcNow.AddSeconds(token.Lifetime),
                iat);

            foreach (var aud in token.Audiences)
            {
                payload.AddClaim(new Claim(JwtClaimTypes.Audience, aud));
            }

            var amrClaims   = token.Claims.Where(x => x.Type == JwtClaimTypes.AuthenticationMethod);
            var scopeClaims = token.Claims.Where(x => x.Type == JwtClaimTypes.Scope);
            var jsonClaims  = token.Claims.Where(x => x.ValueType == IdentityServerConstants.ClaimValueTypes.Json);

            var normalClaims = token.Claims
                               .Except(amrClaims)
                               .Except(jsonClaims)
                               .Except(scopeClaims);

            payload.AddClaims(normalClaims);

            // scope claims
            if (!scopeClaims.IsNullOrEmpty())
            {
                var scopeValues = scopeClaims.Select(x => x.Value).ToArray();
                payload.Add(JwtClaimTypes.Scope, scopeValues);
            }

            // amr claims
            if (!amrClaims.IsNullOrEmpty())
            {
                var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray();
                payload.Add(JwtClaimTypes.AuthenticationMethod, amrValues);
            }

            // deal with json types
            // calling ToArray() to trigger JSON parsing once and so later
            // collection identity comparisons work for the anonymous type
            try
            {
                foreach (var jClaim in jsonClaims)
                {
                    // dynamic stuff = JObject.Parse(jClaim.Value);
                    var     converter = new ExpandoObjectConverter();
                    dynamic expando   = JsonConvert.DeserializeObject <ExpandoObject>(jClaim.Value, converter);
                    payload.Add(jClaim.Type, expando);
                }

                return(payload);
            }
            catch (Exception ex)
            {
                logger.LogCritical(ex, "Error creating a JSON valued claim");
                throw;
            }
        }
Example #23
0
        public string GenerateToken(string name, string role, int userId, object validationId, string userPath, out string refreshTokenString, bool refreshTokenAsWell = false)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentOutOfRangeException(nameof(name));
            }

            string tokenString = null;

            refreshTokenString = null;

            if (_handler.CanWriteToken)
            {
                var signingCredentials = new SigningCredentials(_securityKey.SecurityKey, _tokenParameters.EncryptionAlgorithm);
                var now               = _tokenParameters.ValidFrom ?? DateTime.UtcNow;
                var numericNow        = GetNumericDate(now);
                var notBefore         = now;
                var numericNotBefore  = GetNumericDate(notBefore);
                var expiration        = now.AddMinutes(_tokenParameters.AccessLifeTimeInMinutes);
                var numericExpiration = GetNumericDate(expiration);
                var header            = new JwtHeader(signingCredentials);
                var payload           = new JwtPayload
                {
                    { "iss", _tokenParameters.Issuer },
                    { "sub", _tokenParameters.Subject },
                    { "aud", _tokenParameters.Audience },
                    { "exp", numericExpiration },
                    { "iat", numericNow },
                    { "nbf", numericNotBefore },
                    { "name", name },
                    { "jti", Guid.NewGuid().ToString("N") },
                    { "uid", userId },
                    { "uvid", validationId },
                    { "upath", userPath }
                };
                if (!string.IsNullOrWhiteSpace(role))
                {
                    payload.AddClaim(new Claim("role", role));
                }

                var accessToken = new JwtSecurityToken(header, payload);
                tokenString = _handler.WriteToken(accessToken);

                if (refreshTokenAsWell)
                {
                    var refreshExpiration = expiration.AddMinutes(_tokenParameters.RefreshLifeTimeInMinutes);
                    numericExpiration = GetNumericDate(refreshExpiration);
                    notBefore         = expiration;
                    numericNotBefore  = GetNumericDate(notBefore);
                    payload           = new JwtPayload
                    {
                        { "iss", _tokenParameters.Issuer },
                        { "sub", _tokenParameters.Subject },
                        { "aud", _tokenParameters.Audience },
                        { "exp", numericExpiration },
                        { "iat", numericNow },
                        { "nbf", numericNotBefore },
                        { "name", name },
                        { "jti", Guid.NewGuid().ToString("N") },
                        { "uid", userId },
                        { "uvid", validationId },
                        { "upath", userPath }
                    };

                    var refreshToken = new JwtSecurityToken(header, payload);
                    refreshTokenString = _handler.WriteToken(refreshToken);
                }
            }

            return(tokenString);
        }
        public async Task <IActionResult> IssueToken()
        {
            var pemFileName = Environment.GetEnvironmentVariable(Defines.PrivateKeyFileEnvironmentVariableName) ??
                              throw new ApplicationException(
                                        $"\"{Defines.PrivateKeyFileEnvironmentVariableName}\" environment variable is not set or empty");

            logger.LogInformation($"Reading private key from file: {pemFileName}");

            var pemDataBytes = await System.IO.File.ReadAllBytesAsync(pemFileName);

            var pemDataString = Encoding.UTF8.GetString(pemDataBytes);

            // Use "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----" headers for PKCS8
            var b64 = pemDataString.Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty)
                      .Replace("-----END RSA PRIVATE KEY-----", string.Empty)
                      .Replace("\n", string.Empty)
                      .Trim();

            var privateKey = Convert.FromBase64String(b64);

            var rsa = System.Security.Cryptography.RSA.Create();

            // Use rsa.ImportPkcs8PrivateKey(privateKey, out var bytesRead) for PKCS8 keys
            rsa.ImportRSAPrivateKey(privateKey, out var bytesRead);

            logger.LogInformation($"RSA private key bytes read: {bytesRead}");

            var securityKey = new RsaSecurityKey(rsa);

            logger.LogInformation($"RSA security key size: {securityKey.KeySize} bits");

            // Use preferred sign algorithm
            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256);

            var jwtHeader = new JwtHeader(signingCredentials);

            const string jti = "TokenIndex";

            var jwtPayload = new JwtPayload
            {
                { JwtRegisteredClaimNames.Jti, jti },
                { JwtRegisteredClaimNames.Sub, "TokenSubject" },
                { JwtRegisteredClaimNames.Aud, "TokenAudience" },
                { "CustomClaim", "SomeData" },
            };

            var i = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            var e = i + Defines.TokenTtl;

            var iat = new Claim(JwtRegisteredClaimNames.Iat, i.ToString(), ClaimValueTypes.Integer64);
            var exp = new Claim(JwtRegisteredClaimNames.Exp, e.ToString(), ClaimValueTypes.Integer64);

            jwtPayload.AddClaim(iat);
            jwtPayload.AddClaim(exp);

            var token        = new JwtSecurityToken(jwtHeader, jwtPayload);
            var tokenHandler = new JwtSecurityTokenHandler();
            var accessToken  = tokenHandler.WriteToken(token);

            return(Ok(new { accessToken }));
        }
        /// <summary>
        /// Turns a token object into JWT payload
        /// </summary>
        /// <param name="token">The token</param>
        /// <returns>Serialized JWT payload</returns>
        public static string CreateJwtPayload(this Token token)
        {
            var payload = new JwtPayload(
                token.Issuer,
                token.Audience,
                null,
                token.CreationTime.UtcDateTime,
                token.CreationTime.AddSeconds(token.Lifetime).UtcDateTime);

            var amrClaims    = token.Claims.Where(x => x.Type == Constants.ClaimTypes.AuthenticationMethod);
            var jsonClaims   = token.Claims.Where(x => x.ValueType == Constants.ClaimValueTypes.Json);
            var normalClaims = token.Claims.Except(amrClaims).Except(jsonClaims);

            payload.AddClaims(normalClaims);

            if (token.WebService != null)
            {
                payload.AddClaim(new System.Security.Claims.Claim(Constants.ClaimTypes.WebService, token.WebService));
            }

            // deal with amr
            var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray();

            if (amrValues.Any())
            {
                payload.Add(Constants.ClaimTypes.AuthenticationMethod, amrValues);
            }

            // deal with json types
            // calling ToArray() to trigger JSON parsing once and so later
            // collection identity comparisons work for the anonymous type
            var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray();

            var jsonObjects      = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Object).ToArray();
            var jsonObjectGroups = jsonObjects.GroupBy(x => x.Type).ToArray();

            foreach (var group in jsonObjectGroups)
            {
                if (payload.ContainsKey(group.Key))
                {
                    throw new Exception(String.Format("Can't add two claims where one is a JSON object and the other is not a JSON object ({0})", group.Key));
                }

                if (group.Skip(1).Any())
                {
                    // add as array
                    payload.Add(group.Key, group.Select(x => x.JsonValue).ToArray());
                }
                else
                {
                    // add just one
                    payload.Add(group.Key, group.First().JsonValue);
                }
            }

            var jsonArrays      = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Array).ToArray();
            var jsonArrayGroups = jsonArrays.GroupBy(x => x.Type).ToArray();

            foreach (var group in jsonArrayGroups)
            {
                if (payload.ContainsKey(group.Key))
                {
                    throw new Exception(String.Format("Can't add two claims where one is a JSON array and the other is not a JSON array ({0})", group.Key));
                }

                List <JToken> newArr = new List <JToken>();
                foreach (var arrays in group)
                {
                    var arr = (JArray)arrays.JsonValue;
                    newArr.AddRange(arr);
                }

                // add just one array for the group/key/claim type
                payload.Add(group.Key, newArr.ToArray());
            }

            var unsupportedJsonTokens     = jsonTokens.Except(jsonObjects).Except(jsonArrays);
            var unsupportedJsonClaimTypes = unsupportedJsonTokens.Select(x => x.Type).Distinct();

            if (unsupportedJsonClaimTypes.Any())
            {
                throw new Exception(String.Format("Unsupported JSON type for claim types: {0}", unsupportedJsonClaimTypes.Aggregate((x, y) => x + ", " + y)));
            }

            return(payload.SerializeToJson());
        }
Example #26
0
        public string Create(IIdentity identity, string audience, List <string> appGroupRegexes)
        {
            var nowUtc       = DateTime.UtcNow;
            var expires      = _settings.TokenExpiryMinutes > 0 ? nowUtc.AddMinutes(_settings.TokenExpiryMinutes) : nowUtc.AddDays(_settings.TokenExpiryDays);
            var centuryBegin = new DateTime(1970, 1, 1);
            var exp          = (long)(new TimeSpan(expires.Ticks - centuryBegin.Ticks).TotalSeconds);
            var now          = (long)(new TimeSpan(nowUtc.Ticks - centuryBegin.Ticks).TotalSeconds);
            var issuer       = _settings.Issuer ?? string.Empty;
            var payload      = new JwtPayload
            {
                { "sub", identity.Name },
                { "unique_name", identity.Name },
                { "iss", issuer },
                { "aud", audience },
                { "iat", now },
                { "nbf", now },
                { "exp", exp },
                { "jti", Guid.NewGuid().ToString("N") }
            };

            var windowsUser = identity as WindowsIdentity;

            // SId
            var claim = windowsUser.Claims.FirstOrDefault(c => c.Type == ClaimTypes.PrimarySid);

            if (claim != null)
            {
                payload.AddClaim(new Claim("sid", claim.Value));
            }

            // Group SId
            if (_settings.IncludeGroupSIdClaims)
            {
                var groupClaims = windowsUser.Claims.Where(c => c.Type == ClaimTypes.GroupSid);
                if (groupClaims != null)
                {
                    foreach (Claim c in groupClaims)
                    {
                        payload.AddClaim(new Claim(c.Type, c.Value));
                    }
                }
            }

            // Group Roles
            if (_settings.IncludeGroupRoleClaims)
            {
                var groupClaims = windowsUser.Claims.Where(c => c.Type == ClaimTypes.GroupSid);
                if (groupClaims != null)
                {
                    foreach (Claim c in groupClaims)
                    {
                        var role = new System.Security.Principal.SecurityIdentifier(c.Value).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
                        foreach (var regex in appGroupRegexes)
                        {
                            if (Regex.IsMatch(role, regex))
                            {
                                payload.AddClaim(new Claim("role", role));
                            }
                        }
                    }
                }
            }

            var jwt = new JwtSecurityToken(_jwtHeader, payload);

            return(_jwtSecurityTokenHandler.WriteToken(jwt));
        }