public void GetCipher_WhenGivenValidCipher_ReturnsCipher(string clientId, string redirectUri, string password) { var digest = new BasicAuthenticationDigest( "azzlack", new BasicAuthenticationCipher(clientId, redirectUri, password)); var cipher = digest.GetCipher(); Assert.AreEqual(clientId, cipher.ClientId); Assert.AreEqual(redirectUri, cipher.RedirectUri); Assert.AreEqual(password, cipher.Password); }
public void GetCipher_WhenGivenValidEncodedCipher_ReturnsCipher(string clientId, string redirectUri, string password) { var digest = new BasicAuthenticationDigest( "azzlack", $"client_id={WebUtility.UrlEncode(clientId)}&redirect_uri={WebUtility.UrlEncode(redirectUri)}&password={WebUtility.UrlEncode(password)}"); var cipher = digest.GetCipher(); Assert.AreEqual(clientId, cipher.ClientId); Assert.AreEqual(redirectUri, cipher.RedirectUri); Assert.AreEqual(password, cipher.Password); }
public override async Task <ISentinelPrincipal> AuthenticateClientCredentialsAsync(BasicAuthenticationDigest digest) { BasicAuthenticationCipher cipher; try { cipher = digest.GetCipher(); } catch (ArgumentException) { return(SentinelPrincipal.Anonymous); } var client = await this.ClientRepository.GetClient(digest.UserId); if (client != null && client.Enabled && client.RedirectUri == cipher.RedirectUri) { if (this.PasswordCryptoProvider.ValidateHash(cipher.Password, client.ClientSecret)) { var principal = new SentinelPrincipal( new SentinelIdentity( AuthenticationType.Basic, new SentinelClaim(JwtClaimType.Name, client.ClientId), new SentinelClaim(ClaimTypes.NameIdentifier, client.ClientId), new SentinelClaim(ClaimType.Client, client.ClientId), new SentinelClaim(ClaimType.RedirectUri, client.RedirectUri), new SentinelClaim(ClaimType.AuthenticationSource, "local"), new SentinelClaim(ClaimTypes.AuthenticationMethod, AuthenticationMethod.Basic))); if (principal.Identity.IsAuthenticated) { client.LastUsed = DateTimeOffset.UtcNow; await this.ClientRepository.Update(client.GetIdentifier(), client); return(principal); } } } return(SentinelPrincipal.Anonymous); }
/// <summary>Authenticate the user using an API key.</summary> /// <param name="digest">The digest.</param> /// <returns>The user principal.</returns> public override async Task <ISentinelPrincipal> AuthenticateUserWithApiKeyAsync(BasicAuthenticationDigest digest) { BasicAuthenticationCipher cipher; string data; string signature; try { // Extract data from digest password cipher = digest.GetCipher(); if (string.IsNullOrEmpty(cipher.ClientId) || string.IsNullOrEmpty(cipher.RedirectUri) || string.IsNullOrEmpty(cipher.Password)) { return(SentinelPrincipal.Anonymous); } data = this.PasswordCryptoProvider.CreateHash(256); signature = this.AsymmetricCryptoProvider.Sign(data, cipher.Password); } catch (ArgumentException) { return(SentinelPrincipal.Anonymous); } catch (FormatException) { return(SentinelPrincipal.Anonymous); } // Validate client var client = await this.ClientRepository.GetClient(cipher.ClientId); if (client == null || !client.Enabled || client.RedirectUri != cipher.RedirectUri) { return(SentinelPrincipal.Anonymous); } // Validate password var userKeys = await this.UserApiKeyRepository.GetForUser(digest.UserId); var matchingKey = this.ValidateApiKey(userKeys, data, signature); if (matchingKey != null) { var user = await this.UserRepository.GetUser(matchingKey.UserId); if (user != null && user.Enabled) { var principal = new SentinelPrincipal( new SentinelIdentity( AuthenticationType.Signature, new SentinelClaim(JwtClaimType.Name, user.UserId), new SentinelClaim(ClaimTypes.NameIdentifier, user.UserId), new SentinelClaim(ClaimTypes.AuthenticationMethod, AuthenticationMethod.Basic), new SentinelClaim(ClaimType.AuthenticationSource, "local"), new SentinelClaim(JwtClaimType.GivenName, user.FirstName), new SentinelClaim(JwtClaimType.FamilyName, user.LastName))); user.LastLogin = DateTimeOffset.UtcNow; await this.UserRepository.Update(user.GetIdentifier(), user); matchingKey.LastUsed = DateTimeOffset.UtcNow; await this.UserApiKeyRepository.Update(matchingKey.GetIdentifier(), matchingKey); return(principal); } } return(SentinelPrincipal.Anonymous); }