Example #1
0
        public static Token CreateAccessTokenLong(Client client, string subjectId, int lifetime, int count, params string[] scopes)
        {
            var claims = new List<Claim>
            {
                new Claim("client_id", client.ClientId),
                new Claim("sub", subjectId)
            };

            for (int i = 0; i < count; i++)
            {
                claims.Add(new Claim("junk", "x".Repeat(100)));
            }

            scopes.ToList().ForEach(s => claims.Add(new Claim("scope", s)));

            var token = new Token(Constants.TokenTypes.AccessToken)
            {
                Audience = "https://idsrv3.com/resources",
                Issuer = "https://idsrv3.com",
                Lifetime = lifetime,
                Claims = claims,
                Client = client
            };

            return token;
        }
        /// <summary>
        /// Creates the json web token.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="credentials">The credentials.</param>
        /// <returns></returns>
        protected virtual string CreateJsonWebToken(Token token, SigningCredentials credentials)
        {
            var jwt = new JwtSecurityToken(
                token.Issuer,
                token.Audience,
                token.Claims,
                DateTimeHelper.UtcNow,
                DateTimeHelper.UtcNow.AddSeconds(token.Lifetime),
                credentials);

            // amr is an array - if there is only a single value turn it into an array
            if (jwt.Payload.ContainsKey("amr"))
            {
                var amrValue = jwt.Payload["amr"] as string;
                if (amrValue != null)
                {
                    jwt.Payload["amr"] = new string[] { amrValue };
                }
            }

            var x509credential = credentials as X509SigningCredentials;
            if (x509credential != null)
            {
                jwt.Header.Add("kid", Base64Url.Encode(x509credential.Certificate.GetCertHash()));
            }

            var handler = new JwtSecurityTokenHandler();
            return handler.WriteToken(jwt);
        }
        /// <summary>
        /// Creates the json web token.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="credentials">The credentials.</param>
        /// <returns>The signed JWT</returns>
        protected virtual async Task<string> CreateJsonWebToken(Token token, SigningCredentials credentials)
        {
            var header = CreateHeader(token, credentials);
            var payload = CreatePayload(token);

            return await SignAsync(new JwtSecurityToken(header, payload));
        }
        /// <summary>
        /// Creates the refresh token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="accessToken">The access token.</param>
        /// <param name="client">The client.</param>
        /// <returns>
        /// The refresh token handle
        /// </returns>
        public virtual async Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client)
        {
            Logger.Debug("Creating refresh token");

            int lifetime;
            if (client.RefreshTokenExpiration == TokenExpiration.Absolute)
            {
                Logger.Debug("Setting an absolute lifetime: " + client.AbsoluteRefreshTokenLifetime);
                lifetime = client.AbsoluteRefreshTokenLifetime;
            }
            else
            {
                Logger.Debug("Setting a sliding lifetime: " + client.SlidingRefreshTokenLifetime);
                lifetime = client.SlidingRefreshTokenLifetime;
            }

            var handle = CryptoRandom.CreateUniqueId();
            var refreshToken = new RefreshToken
            {
                CreationTime = DateTimeOffsetHelper.UtcNow,
                LifeTime = lifetime,
                AccessToken = accessToken,
                Subject = subject
            };

            await _store.StoreAsync(handle, refreshToken);

            await RaiseRefreshTokenIssuedEventAsync(handle, refreshToken);
            return handle;
        }
 public async Task StoreAsync(string key, Token value)
 {
     var result = await Collection.ReplaceOneAsync(
         Filter.ById(key),
         _serializer.Serialize(key, value),
         PerformUpsert).ConfigureAwait(false);
     Log.Debug(result.ToString);
 }
        protected override Token ToToken(string key, IdentityServer3.Core.Models.Token value)
        {
            var token = new Token
            {
                Key       = key,
                SubjectId = value.SubjectId,
                ClientId  = value.ClientId,
                Model     = ConvertToJson(value),
                Expiry    = DateTimeOffset.UtcNow.AddSeconds(value.Lifetime),
                TokenType = this.StoredTokenType
            };

            return(token);
        }
 internal static StoredToken ToDbFormat(Token token)
 {
     return new StoredToken
     {
         ClientId = token.ClientId,
         Client = token.Client.ClientId,
         Audience = token.Audience,
         CreationTime = token.CreationTime,
         Lifetime = token.Lifetime,
         Expires = token.CreationTime.AddSeconds(token.Lifetime),
         Type = token.Type,
         Issuer = token.Issuer,
         SubjectId = token.SubjectId,
         Version = token.Version,
         Claims = (from c in token.Claims select StoredClientClaim.ToDbFormat(c)).ToList()
     };
 }
        /// <summary>
        /// Creates the json web token.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="credentials">The credentials.</param>
        /// <returns></returns>
        protected virtual string CreateJsonWebToken(Token token, SigningCredentials credentials)
        {
            var jwt = new JwtSecurityToken(
                token.Issuer,
                token.Audience,
                token.Claims,
                DateTimeHelper.UtcNow,
                DateTimeHelper.UtcNow.AddSeconds(token.Lifetime),
                credentials);

            var x509credential = credentials as X509SigningCredentials;
            if (x509credential != null)
            {
                jwt.Header.Add("kid", Base64Url.Encode(x509credential.Certificate.GetCertHash()));
            }

            var handler = new JwtSecurityTokenHandler();
            return handler.WriteToken(jwt);
        }
        public static Token CreateIdentityToken(string clientId, string subjectId)
        {
            var clients = Factory.CreateClientStore();

            var claims = new List<Claim> 
            {
                new Claim("sub", subjectId)
            };

            var token = new Token(Constants.TokenTypes.IdentityToken)
            {
                Audience = clientId,
                Client = clients.FindClientByIdAsync(clientId).Result,
                Issuer = "https://idsrv3.com",
                Lifetime = 600,
                Claims = claims
            };

            return token;
        }
        /// <summary>
        /// Creates the JWT header
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="credential">The credentials.</param>
        /// <returns>The JWT header</returns>
        protected virtual JwtHeader CreateHeader(Token token, SigningCredentials credential)
        {
            var header = new JwtHeader(credential);

            var x509credential = credential as X509SigningCredentials;
            if (x509credential != null)
            {
                header.Add("kid", Base64Url.Encode(x509credential.Certificate.GetCertHash()));
            }

            return header;
        }
 /// <summary>
 /// Signs the token.
 /// </summary>
 /// <param name="token">The token.</param>
 /// <returns>
 /// A protected and serialized security token
 /// </returns>
 public virtual async Task<string> SignTokenAsync(Token token)
 {
     var credentials = await GetSigningCredentialsAsync();
     return await CreateJsonWebToken(token, credentials);
 }
        Token CreateAccessToken(Client client, string subjectId, int lifetime, params string[] scopes)
        {
            var claims = new List<Claim> 
            {
                new Claim("client_id", client.ClientId),
                new Claim("sub", subjectId)
            };

            scopes.ToList().ForEach(s => claims.Add(new Claim("scope", s)));

            var token = new Token(Constants.TokenTypes.AccessToken)
            {
                Audience = "https://idsrv3.com/resources",
                Issuer = "https://idsrv3.com",
                Lifetime = lifetime,
                Claims = claims,
                Client = client
            };

            return token;
        }
        /// <summary>
        /// Creates the JWT payload
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>The JWT payload</returns>
        protected virtual JwtPayload CreatePayload(Token token)
        {
            var payload = new JwtPayload(
                token.Issuer,
                token.Audience,
                null,
                DateTimeHelper.UtcNow,
                DateTimeHelper.UtcNow.AddSeconds(token.Lifetime));

            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);

            // 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;
        }
Example #14
0
        public static Token CreateIdentityTokenLong(string clientId, string subjectId, int count)
        {
            var clients = Factory.CreateClientStore();

            var claims = new List<Claim>
            {
                new Claim("sub", subjectId)
            };

            for (int i = 0; i < count; i++)
            {
                claims.Add(new Claim("junk", "x".Repeat(100)));
            }

            var token = new Token(Constants.TokenTypes.IdentityToken)
            {
                Audience = clientId,
                Client = clients.FindClientByIdAsync(clientId).Result,
                Issuer = "https://idsrv3.com",
                Lifetime = 600,
                Claims = claims
            };

            return token;
        }
 /// <summary>
 /// Creates the JWT payload
 /// </summary>
 /// <param name="token">The token.</param>
 /// <returns>The JWT payload</returns>
 protected virtual string CreatePayload(Token token)
 {
     return token.CreateJwtPayload();   
 }
 /// <summary>
 /// Creates the json web token.
 /// </summary>
 /// <param name="token">The token.</param>
 /// <param name="credentials">The credentials.</param>
 /// <returns>The signed JWT</returns>
 protected virtual async Task<string> CreateJsonWebToken(Token token, SigningCredentials credentials)
 {
     var payload = CreatePayload(token);
     return await SignAsync(payload, credentials);
 }
        /// <summary>
        /// Creates the JWT header
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="keyVaultCredentials">The credentials.</param>
        /// <returns>The JWT header</returns>
        protected virtual JwtHeader CreateHeader(Token token, AzureKeyVaultSigningCredentials keyVaultCredentials)
        {
            var header = new JwtHeader(keyVaultCredentials);
            if (keyVaultCredentials != null)
            {
                header.Add("kid", _options.KeyIdentifier);
            }

            return header;
        }
        /// <summary>
        /// Stores the data.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public Task StoreAsync(string key, Token value)
        {
            _repository[key] = value;

            return Task.FromResult<object>(null);
        }
        private async Task<TokenResponse> ProcessRefreshTokenRequestAsync(ValidatedTokenRequest request)
        {
            Logger.Info("Processing refresh token request");

            var oldAccessToken = request.RefreshToken.AccessToken;
            string accessTokenString;
            
            // if pop request, claims must be updated because we need a fresh proof token
            if (request.Client.UpdateAccessTokenClaimsOnRefresh || request.RequestedTokenType == RequestedTokenTypes.PoP)
            {
                var subject = request.RefreshToken.GetOriginalSubject();

                var creationRequest = new TokenCreationRequest
                {
                    Client = request.Client,
                    Subject = subject,
                    ValidatedRequest = request,
                    Scopes = await _scopes.FindScopesAsync(oldAccessToken.Scopes),
                };

                // if pop request, embed proof token
                if (request.RequestedTokenType == RequestedTokenTypes.PoP)
                {
                    creationRequest.ProofKey = GetProofKey(request);
                }

                var newAccessToken = await _tokenService.CreateAccessTokenAsync(creationRequest);
                accessTokenString = await _tokenService.CreateSecurityTokenAsync(newAccessToken);
            }
            else
            {
                var copy = new Token(oldAccessToken);
                copy.CreationTime = DateTimeOffsetHelper.UtcNow;
                copy.Lifetime = request.Client.AccessTokenLifetime;

                accessTokenString = await _tokenService.CreateSecurityTokenAsync(copy);
            }

            var handle = await _refreshTokenService.UpdateRefreshTokenAsync(request.RefreshTokenHandle, request.RefreshToken, request.Client);

            var response = new TokenResponse
            {
                AccessToken = accessTokenString,
                AccessTokenLifetime = request.Client.AccessTokenLifetime,
                RefreshToken = handle
            };

            if (request.RequestedTokenType == RequestedTokenTypes.PoP)
            {
                response.TokenType = Constants.ResponseTokenTypes.PoP;
                response.Algorithm = request.ProofKeyAlgorithm;
            }

            return response;
        }
        /// <summary>
        /// Creates an access token.
        /// </summary>
        /// <param name="request">The token creation request.</param>
        /// <returns>
        /// An access token
        /// </returns>
        public virtual async Task<Token> CreateAccessTokenAsync(TokenCreationRequest request)
        {
            Logger.Debug("Creating access token");
            request.Validate();

            var claims = new List<Claim>();
            claims.AddRange(await _claimsProvider.GetAccessTokenClaimsAsync(
                request.Subject,
                request.Client,
                request.Scopes,
                request.ValidatedRequest));

            if (request.Client.IncludeJwtId)
            {
                claims.Add(new Claim(Constants.ClaimTypes.JwtId, CryptoRandom.CreateUniqueId()));
            }

            var token = new Token(Constants.TokenTypes.AccessToken)
            {
                Audience = string.Format(Constants.AccessTokenAudience, IssuerUri.EnsureTrailingSlash()),
                Issuer = IssuerUri,
                Lifetime = request.Client.AccessTokenLifetime,
                Claims = claims.Distinct(new ClaimComparer()).ToList(),
                Client = request.Client
            };

            return token;
        }
        /// <summary>
        /// Creates an identity token.
        /// </summary>
        /// <param name="request">The token creation request.</param>
        /// <returns>
        /// An identity token
        /// </returns>
        public virtual async Task<Token> CreateIdentityTokenAsync(TokenCreationRequest request)
        {
            Logger.Debug("Creating identity token");
            request.Validate();

            // host provided claims
            var claims = new List<Claim>();

            // if nonce was sent, must be mirrored in id token
            if (request.Nonce.IsPresent())
            {
                claims.Add(new Claim(Constants.ClaimTypes.Nonce, request.Nonce));
            }

            // add iat claim
            claims.Add(new Claim(Constants.ClaimTypes.IssuedAt, DateTimeOffsetHelper.UtcNow.ToEpochTime().ToString(), ClaimValueTypes.Integer));

            // add at_hash claim
            if (request.AccessTokenToHash.IsPresent())
            {
                claims.Add(new Claim(Constants.ClaimTypes.AccessTokenHash, HashAdditionalData(request.AccessTokenToHash)));
            }

            // add c_hash claim
            if (request.AuthorizationCodeToHash.IsPresent())
            {
                claims.Add(new Claim(Constants.ClaimTypes.AuthorizationCodeHash, HashAdditionalData(request.AuthorizationCodeToHash)));
            }

            // add sid if present
            if (request.ValidatedRequest.SessionId.IsPresent())
            {
                claims.Add(new Claim(Constants.ClaimTypes.SessionId, request.ValidatedRequest.SessionId));
            }

            claims.AddRange(await _claimsProvider.GetIdentityTokenClaimsAsync(
                request.Subject,
                request.Client,
                request.Scopes,
                request.IncludeAllIdentityClaims,
                request.ValidatedRequest));

            var token = new Token(Constants.TokenTypes.IdentityToken)
            {
                Audience = request.Client.ClientId,
                Issuer = IssuerUri,
                Lifetime = request.Client.IdentityTokenLifetime,
                Claims = claims.Distinct(new ClaimComparer()).ToList(),
                Client = request.Client
            };

            return token;
        }
Example #22
0
 internal Token(Token other)
 {
     Audience = other.Audience;
     Claims = other.Claims.ToList();
     Client = other.Client;
     CreationTime = other.CreationTime;
     Issuer = other.Issuer;
     Lifetime = other.Lifetime;
     Type = other.Type;
     Version = other.Version;
 }
 /// <summary>
 /// Signs the token.
 /// </summary>
 /// <param name="token">The token.</param>
 /// <returns>
 /// A protected and serialized security token
 /// </returns>
 /// <exception cref="System.InvalidOperationException">Invalid token type</exception>
 public virtual Task<string> SignTokenAsync(Token token)
 {
     return Task.FromResult(CreateJsonWebToken(token, new X509SigningCredentials(_options.SigningCertificate)));
 }
        protected virtual IEnumerable<Claim> ReferenceTokenToClaims(Token token)
        {
            var claims = new List<Claim>
            {
                new Claim(Constants.ClaimTypes.Audience, token.Audience),
                new Claim(Constants.ClaimTypes.Issuer, token.Issuer),
                new Claim(Constants.ClaimTypes.NotBefore, token.CreationTime.ToEpochTime().ToString()),
                new Claim(Constants.ClaimTypes.Expiration, token.CreationTime.AddSeconds(token.Lifetime).ToEpochTime().ToString())
            };

            claims.AddRange(token.Claims);

            return claims;
        }
        /// <summary>
        /// Creates a serialized and protected security token.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <returns>
        /// A security token in serialized form
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Invalid token type.</exception>
        public virtual async Task<string> CreateSecurityTokenAsync(Token token)
        {
            string tokenResult;

            if (token.Type == Constants.TokenTypes.AccessToken)
            {
                if (token.Client.AccessTokenType == AccessTokenType.Jwt)
                {
                    Logger.Debug("Creating JWT access token");

                    tokenResult = await _signingService.SignTokenAsync(token);
                }
                else
                {
                    Logger.Debug("Creating reference access token");

                    var handle = CryptoRandom.CreateUniqueId();
                    await _tokenHandles.StoreAsync(handle, token);

                    tokenResult = handle;
                }
            }
            else if (token.Type == Constants.TokenTypes.IdentityToken)
            {
                Logger.Debug("Creating JWT identity token");

                tokenResult = await _signingService.SignTokenAsync(token);
            }
            else
            {
                throw new InvalidOperationException("Invalid token type.");
            }

            await _events.RaiseTokenIssuedEventAsync(token, tokenResult);
            return tokenResult;
        }
        public async Task StoreAsync(string key, IdentityServer3.Core.Models.Token value)
        {
            var token = ToToken(key, value);

            await InsertAsync(token);
        }