/// <summary>Creates an access token.</summary> /// <param name="clientId">Identifier for the client.</param> /// <param name="redirectUri">URI of the redirect.</param> /// <param name="userPrincipal">The user principal.</param> /// <param name="scope">The scope.</param> /// <param name="expireTime">The expire time.</param> /// <returns>The new access token.</returns> public async Task <TokenCreationResult <IAccessToken> > CreateAccessToken( string clientId, string redirectUri, ISentinelPrincipal userPrincipal, IEnumerable <string> scope, DateTimeOffset expireTime) { string token; var hashedToken = this.cryptoProvider.CreateHash(out token, 512); // Add expire claim userPrincipal.Identity.AddClaim(new SentinelClaim(ClaimType.Expiration, expireTime.ToUnixTime().ToString())); var accessToken = new AccessToken() { ClientId = clientId, RedirectUri = redirectUri, Subject = userPrincipal.Identity.Name, Scope = scope, Token = hashedToken, Ticket = this.principalProvider.Encrypt(userPrincipal, token), ValidTo = expireTime }; return(new TokenCreationResult <IAccessToken>(token, accessToken)); }
/// <summary>Creates an authorization code.</summary> /// <param name="clientId">Identifier for the client.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="userPrincipal">The user principal.</param> /// <param name="scope">The scope.</param> /// <param name="expireTime">The expire time.</param> /// <returns>An object containing the new access token entity and the hashed token.</returns> public async Task <TokenCreationResult <IAuthorizationCode> > CreateAuthorizationCode( string clientId, string redirectUri, ISentinelPrincipal userPrincipal, IEnumerable <string> scope, DateTimeOffset expireTime) { string code; var hashedCode = this.cryptoProvider.CreateHash(out code, 256); // Add expire claim userPrincipal.Identity.AddClaim(new SentinelClaim(ClaimType.Expiration, expireTime.ToUnixTime().ToString())); var authorizationCode = new AuthorizationCode() { ClientId = clientId, RedirectUri = redirectUri, Subject = userPrincipal.Identity.Name, Scope = scope, Code = hashedCode, Ticket = this.principalProvider.Encrypt(userPrincipal, code), ValidTo = expireTime }; return(new TokenCreationResult <IAuthorizationCode>(code, authorizationCode)); }
/// <summary>Creates an access token.</summary> /// <param name="clientId">Identifier for the client.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="userPrincipal">The user principal.</param> /// <param name="scope">The scope.</param> /// <param name="expireTime">The expire time.</param> /// <returns>An object containing the new access token entity and the hashed token.</returns> public async Task <TokenCreationResult <IAccessToken> > CreateAccessToken( string clientId, string redirectUri, ISentinelPrincipal userPrincipal, IEnumerable <string> scope, DateTimeOffset expireTime) { // Create token string token; var hashedToken = this.configuration.CryptoProvider.CreateHash(out token, 512); // Create access token hash var tokenHash = Convert.FromBase64String(this.configuration.CryptoProvider.CreateHash(token, false)); // Add extra claims userPrincipal.Identity.RemoveClaim(x => x.Type == JwtClaimType.Subject); userPrincipal.Identity.RemoveClaim(x => x.Type == JwtClaimType.AccessTokenHash); userPrincipal.Identity.AddClaim(JwtClaimType.Subject, userPrincipal.Identity.Name); userPrincipal.Identity.AddClaim(JwtClaimType.AccessTokenHash, Convert.ToBase64String(tokenHash.Take(16).ToArray())); var jwt = new JwtSecurityToken( this.configuration.Issuer.AbsoluteUri, clientId, userPrincipal.Identity.Claims.ToClaims(), DateTime.UtcNow, expireTime.UtcDateTime, this.configuration.SigningCredentials); var idToken = this.tokenHandler.WriteToken(jwt); var accessToken = new AccessToken() { ClientId = clientId, RedirectUri = redirectUri, Subject = userPrincipal.Identity.Name, Scope = scope, Token = hashedToken, Ticket = idToken, ValidTo = expireTime }; return(new TokenCreationResult <IAccessToken>(token, accessToken)); }
/// <summary>Creates an authorization code.</summary> /// <param name="clientId">Identifier for the client.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="userPrincipal">The user principal.</param> /// <param name="scope">The scope.</param> /// <param name="expireTime">The expire time.</param> /// <returns>An object containing the new access token entity and the hashed token.</returns> public async Task <TokenCreationResult <IAuthorizationCode> > CreateAuthorizationCode( string clientId, string redirectUri, ISentinelPrincipal userPrincipal, IEnumerable <string> scope, DateTimeOffset expireTime) { string code; var hashedCode = this.configuration.CryptoProvider.CreateHash(out code, 256); // Create a separate authorization code hash var codeHash = Convert.FromBase64String(this.configuration.CryptoProvider.CreateHash(code, false)); // Add extra claims userPrincipal.Identity.RemoveClaim(x => x.Type == JwtClaimType.Subject); userPrincipal.Identity.RemoveClaim(x => x.Type == JwtClaimType.AuthorizationCodeHash); userPrincipal.Identity.AddClaim(JwtClaimType.Subject, userPrincipal.Identity.Name); userPrincipal.Identity.AddClaim(JwtClaimType.AuthorizationCodeHash, Convert.ToBase64String(codeHash.Take(16).ToArray())); var jwt = new JwtSecurityToken( this.configuration.Issuer.AbsoluteUri, clientId, userPrincipal.Identity.Claims.ToClaims(), DateTime.UtcNow, expireTime.UtcDateTime, this.configuration.SigningCredentials); var ticket = this.tokenHandler.WriteToken(jwt); var authorizationCode = new AuthorizationCode() { ClientId = clientId, RedirectUri = redirectUri, Subject = userPrincipal.Identity.Name, Scope = scope, Code = hashedCode, Ticket = ticket, ValidTo = expireTime }; return(new TokenCreationResult <IAuthorizationCode>(code, authorizationCode)); }
/// <summary>Creates a refresh token.</summary> /// <param name="clientId">Identifier for the client.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="userPrincipal">The user principal.</param> /// <param name="scope">The scope.</param> /// <param name="expireTime">The expire time.</param> /// <returns>An object containing the new access token entity and the hashed token.</returns> public async Task <TokenCreationResult <IRefreshToken> > CreateRefreshToken( string clientId, string redirectUri, ISentinelPrincipal userPrincipal, IEnumerable <string> scope, DateTimeOffset expireTime) { string token; var hashedToken = this.configuration.CryptoProvider.CreateHash(out token, 2048); var refreshToken = new RefreshToken() { ClientId = clientId, RedirectUri = redirectUri, Subject = userPrincipal.Identity.Name, Scope = scope, Token = hashedToken, ValidTo = expireTime }; return(new TokenCreationResult <IRefreshToken>(token, refreshToken)); }
/// <summary>Creates a refresh token.</summary> /// <param name="userPrincipal">The principal.</param> /// <param name="expire">The expire time.</param> /// <param name="clientId">The client identifier.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>A refresh token.</returns> public override async Task<string> CreateRefreshTokenAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string clientId, string redirectUri, IEnumerable<string> scope) { if (!userPrincipal.Identity.IsAuthenticated) { this.logger.ErrorFormat("The specified principal is not authenticated"); return string.Empty; } // Delete all expired refresh tokens await this.TokenRepository.DeleteRefreshTokens(DateTime.UtcNow); // Remove unnecessary claims from principal userPrincipal.Identity.RemoveClaim(x => x.Type == ClaimType.AccessToken || x.Type == ClaimType.RefreshToken); // Add scope claims if (scope != null) { userPrincipal.Identity.AddClaim(scope.Select(x => new SentinelClaim(ClaimType.Scope, x)).ToArray()); } this.logger.DebugFormat("Creating refresh token for client '{0}', redirect uri '{1}' and user '{2}'", clientId, redirectUri, userPrincipal.Identity.Name); // Create new refresh token string token; var hashedToken = this.CryptoProvider.CreateHash(out token, 2048); var refreshToken = this.TokenFactory.CreateRefreshToken(clientId, redirectUri, userPrincipal.Identity.Name, scope, hashedToken, DateTime.UtcNow.Add(expire)); // Add refresh token to database var result = await this.TokenRepository.InsertRefreshToken(refreshToken); if (result != null) { this.logger.DebugFormat("Successfully created and stored refresh token"); return token; } this.logger.ErrorFormat("Unable to create and/or store refresh token"); return string.Empty; }
/// <summary>Generates an authorization code for the specified client.</summary> /// <exception cref="ArgumentException"> /// Thrown when one or more arguments have unsupported or illegal values. /// </exception> /// <param name="userPrincipal">The user principal.</param> /// <param name="expire">The expire time.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>An authorization code.</returns> public override async Task<string> CreateAuthorizationCodeAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string redirectUri, IEnumerable<string> scope) { if (!userPrincipal.Identity.IsAuthenticated) { this.logger.ErrorFormat("The specified user is not authenticated"); return string.Empty; } var client = userPrincipal.Identity.Claims.FirstOrDefault(x => x.Type == ClaimType.Client); if (client == null || string.IsNullOrEmpty(client.Value)) { throw new ArgumentException("The specified principal does not have a valid client identifier", "userPrincipal"); } // Delete all expired authorization codes await this.TokenRepository.DeleteAuthorizationCodes(DateTime.UtcNow); // Remove unnecessary claims from principal userPrincipal.Identity.RemoveClaim(x => x.Type == ClaimType.AccessToken || x.Type == ClaimType.RefreshToken); // Add scope claims if (scope != null) { userPrincipal.Identity.AddClaim(scope.Select(x => new SentinelClaim(ClaimType.Scope, x)).ToArray()); } // Create and store authorization code for future use this.logger.DebugFormat("Creating authorization code for client '{0}', redirect uri '{1}' and user '{2}'", client, redirectUri, userPrincipal.Identity.Name); string code; var hashedCode = this.CryptoProvider.CreateHash(out code, 256); var authorizationCode = this.TokenFactory.CreateAuthorizationCode( client.Value, redirectUri, userPrincipal.Identity.Name, scope, hashedCode, this.PrincipalProvider.Encrypt(userPrincipal, code), DateTime.UtcNow.Add(expire)); // Add authorization code to database var result = await this.TokenRepository.InsertAuthorizationCode(authorizationCode); if (result != null) { this.logger.DebugFormat("Successfully created and stored authorization code"); return code; } this.logger.ErrorFormat("Unable to create and/or store authorization code"); return string.Empty; }
/// <summary>Initializes a new instance of the <see cref="TokenValidationResult{T}" /> class.</summary> /// <param name="principal">The principal.</param> /// <param name="entity">The entity.</param> public TokenValidationResult(ISentinelPrincipal principal, T entity) { this.Principal = principal; this.Entity = entity; }
/// <summary> /// Encrypts the specified principal. /// </summary> /// <param name="principal">The principal.</param> /// <param name="key">The key.</param> /// <returns>The encrypted principal.</returns> public string Encrypt(ISentinelPrincipal principal, string key) { var s = JsonConvert.SerializeObject(principal); return(this.cryptoProvider.Encrypt(s, key)); }
/// <summary> /// Encrypts the specified principal. /// </summary> /// <param name="principal">The principal.</param> /// <param name="key">The key.</param> /// <returns>The encrypted principal.</returns> public string Encrypt(ISentinelPrincipal principal, string key) { var s = JsonConvert.SerializeObject(principal); return this.cryptoProvider.Encrypt(s, key); }
/// <summary>Creates a refresh token.</summary> /// <param name="userPrincipal">The principal.</param> /// <param name="expire">The expire time.</param> /// <param name="clientId">The client id.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>The token creation result.</returns> public abstract Task <TokenCreationResult <IRefreshToken> > CreateRefreshTokenAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string clientId, string redirectUri, IEnumerable <string> scope);
/// <summary>Generates an authorization code for the specified client.</summary> /// <param name="userPrincipal">The user principal.</param> /// <param name="expire">The expire time.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>The token creation result.</returns> public abstract Task <TokenCreationResult <IAuthorizationCode> > CreateAuthorizationCodeAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string redirectUri, IEnumerable <string> scope);
/// <summary>Creates a refresh token.</summary> /// <param name="userPrincipal">The principal.</param> /// <param name="expire">The expire time.</param> /// <param name="clientId">The client id.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>A refresh token.</returns> public abstract Task<string> CreateRefreshTokenAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string clientId, string redirectUri, IEnumerable<string> scope);
/// <summary>Generates an authorization code for the specified client.</summary> /// <param name="userPrincipal">The user principal.</param> /// <param name="expire">The expire time.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>An authorization code.</returns> public abstract Task<string> CreateAuthorizationCodeAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string redirectUri, IEnumerable<string> scope);
/// <summary>Creates a refresh token.</summary> /// <param name="userPrincipal">The principal.</param> /// <param name="expire">The expire time.</param> /// <param name="clientId">The client identifier.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>A refresh token.</returns> public override async Task <TokenCreationResult <IRefreshToken> > CreateRefreshTokenAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string clientId, string redirectUri, IEnumerable <string> scope) { if (!userPrincipal.Identity.IsAuthenticated) { this.logger.Error("The specified principal is not authenticated"); return(null); } // Delete all expired refresh tokens await this.TokenRepository.DeleteRefreshTokens(DateTimeOffset.UtcNow); // Add scope claims if (scope != null) { userPrincipal.Identity.AddClaim(scope.Where(x => !userPrincipal.Identity.HasClaim(ClaimType.Scope, x)).Select(x => new SentinelClaim(ClaimType.Scope, x)).ToArray()); } this.logger.DebugFormat("Creating refresh token for client '{0}', redirect uri '{1}' and user '{2}'", clientId, redirectUri, userPrincipal.Identity.Name); var createResult = await this.TokenProvider.CreateRefreshToken( clientId, redirectUri, userPrincipal, scope, DateTimeOffset.UtcNow.Add(expire)); // Add refresh token to database var insertResult = await this.TokenRepository.InsertRefreshToken(createResult.Entity); if (insertResult != null) { this.logger.Debug("Successfully created and stored refresh token"); return(new TokenCreationResult <IRefreshToken>(createResult.Token, insertResult)); } this.logger.Error("Unable to create and/or store refresh token"); return(null); }
/// <summary>Generates an authorization code for the specified client.</summary> /// <exception cref="ArgumentException"> /// Thrown when one or more arguments have unsupported or illegal values. /// </exception> /// <param name="userPrincipal">The user principal.</param> /// <param name="expire">The expire time.</param> /// <param name="redirectUri">The redirect URI.</param> /// <param name="scope">The scope.</param> /// <returns>An authorization code.</returns> public override async Task <TokenCreationResult <IAuthorizationCode> > CreateAuthorizationCodeAsync(ISentinelPrincipal userPrincipal, TimeSpan expire, string redirectUri, IEnumerable <string> scope) { if (!userPrincipal.Identity.IsAuthenticated) { this.logger.Error("The specified user is not authenticated"); return(null); } var client = userPrincipal.Identity.Claims.FirstOrDefault(x => x.Type == ClaimType.Client); if (client == null || string.IsNullOrEmpty(client.Value)) { throw new ArgumentException("The specified principal does not have a valid client identifier", nameof(userPrincipal)); } // Delete all expired authorization codes await this.TokenRepository.DeleteAuthorizationCodes(DateTimeOffset.UtcNow); // Add scope claims if (scope != null) { userPrincipal.Identity.AddClaim(scope.Select(x => new SentinelClaim(ClaimType.Scope, x)).ToArray()); } // Create and store authorization code for future use this.logger.DebugFormat("Creating authorization code for client '{0}', redirect uri '{1}' and user '{2}'", client, redirectUri, userPrincipal.Identity.Name); var createResult = await this.TokenProvider.CreateAuthorizationCode( client.Value, redirectUri, userPrincipal, scope, DateTimeOffset.UtcNow.Add(expire)); // Add authorization code to database var insertResult = await this.TokenRepository.InsertAuthorizationCode(createResult.Entity); if (insertResult != null) { this.logger.Debug("Successfully created and stored authorization code"); return(new TokenCreationResult <IAuthorizationCode>(createResult.Token, insertResult)); } this.logger.Error("Unable to create and/or store authorization code"); return(null); }