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