public bool Equals(OAuthTokenCredential other) { return(other != null && string.Equals(DisplayId, other.DisplayId) && string.Equals(AccessToken, other.AccessToken) && AccessTokenExpiration.Equals(other.AccessTokenExpiration) && string.Equals(RefreshToken, other.RefreshToken) && string.Equals(MailAddress, other.MailAddress)); }
private static void StoreToken(string instanceUrl, [NotNull] OAuthTokenCredential result) { if (result == null) { throw new ArgumentNullException(nameof(result)); } var newCache = new Dictionary <string, OAuthTokenCredential>(_AccessTokenCache); newCache[instanceUrl] = result; _AccessTokenCache = newCache; SerializeTokenCache(); }
private static async Task <OAuthTokenCredential> TryGetOAuthTokenFromRefreshTokenAsync(TokenClient tokenClient, string authority, string refreshToken) { // when a refresh token is present try to use it to acquire a new access token if (!string.IsNullOrEmpty(refreshToken)) { var tokenResponse = await tokenClient.RequestRefreshTokenAsync(refreshToken).ConfigureAwait(false); if (!tokenResponse.IsError) { // TODO: discover userinfo endpoint via ".well-known/openid-configuration" var infoClient = new UserInfoClient(new Uri(authority + "/connect/userinfo"), tokenResponse.AccessToken); var userInfo = await infoClient.GetAsync().ConfigureAwait(false); return(OAuthTokenCredential.CreateWithClaims(userInfo.Claims, tokenResponse.AccessToken, DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn), tokenResponse.RefreshToken)); } } return(null); }
private static async Task <OAuthTokenCredential> TryGetOAuthTokenFromAuthorizeResponseAsync(TokenClient tokenClient, CryptoNumbers cryptoNumbers, AuthorizeResponse response) { if (response != null) { // claims des IdentityToken decodieren var claims = DecodeSecurityToken(response.IdentityToken).Claims.ToArray(); // die folgenden validierungen sind notwendig, um diversen CSRF / man in the middle / etc. Angriffsszenarien zu begegnen // state validieren if (!string.Equals(cryptoNumbers.State, response.State, StringComparison.Ordinal)) { throw new InvalidOperationException("invalid state value in openid service responce."); } // nonce validieren if (!ValidateNonce(cryptoNumbers.Nonce, claims)) { throw new InvalidOperationException("invalid nonce value in identity token."); } // c_hash validieren if (!ValidateCodeHash(response.Code, claims)) { throw new InvalidOperationException("invalid c_hash value in identity token."); } // code eintauschen gegen access token und refresh token, dabei den code verifier mitschicken, um man-in-the-middle Angriff auf authorization code zu begegnen (PKCE) var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync( code : response.Code, redirectUri : RedirectUri, codeVerifier : cryptoNumbers.Verifier).ConfigureAwait(false); if (tokenResponse.IsError) { throw new InvalidOperationException("error during request of access token using authorization code: " + tokenResponse.Error); } return(OAuthTokenCredential.CreateWithIdentityToken(tokenResponse.IdentityToken, tokenResponse.AccessToken, DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn), tokenResponse.RefreshToken)); } return(null); }