static async Task <DeviceAuthorizationResponse> RequestAuthorizationAsync() { var disco = await _cache.GetAsync(); if (disco.IsError) { throw new Exception(disco.Error); } var client = new HttpClient(); var response = await client.RequestDeviceAuthorizationAsync(new DeviceAuthorizationRequest { Address = disco.DeviceAuthorizationEndpoint, ClientId = "device", ClientCredentialStyle = ClientCredentialStyle.PostBody }); if (response.IsError) { throw new Exception(response.Error); } Console.WriteLine($"user code : {response.UserCode}"); Console.WriteLine($"device code : {response.DeviceCode}"); Console.WriteLine($"URL : {response.VerificationUri}"); Console.WriteLine($"Complete URL: {response.VerificationUriComplete}"); Console.WriteLine($"\nPress enter to launch browser ({response.VerificationUri})"); Console.ReadLine(); Process.Start(new ProcessStartInfo(response.VerificationUriComplete) { UseShellExecute = true }); return(response); }
public async Task InvokeAsync(HttpContext context) { string oldAccessToken = await context.GetTokenAsync(OpenIdConnectParameterNames.AccessToken); if (!string.IsNullOrEmpty(oldAccessToken)) { JwtSecurityToken tokenInfo = new JwtSecurityToken(oldAccessToken); // Renew access token if pass halfway of its lifetime if (tokenInfo.ValidFrom + (tokenInfo.ValidTo - tokenInfo.ValidFrom) / 2 < DateTime.UtcNow) { var disco = await _discoveryCache.GetAsync(); TokenClient tokenClient = new TokenClient(disco.TokenEndpoint, _clientId, _clientSecret); string oldRefreshToken = await context.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken); TokenResponse tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken); if (!tokenResult.IsError) { string idToken = await context.GetTokenAsync(OpenIdConnectParameterNames.IdToken); string newAccessToken = tokenResult.AccessToken; string newRefreshToken = tokenResult.RefreshToken; var tokens = new List <AuthenticationToken> { new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = idToken }, new AuthenticationToken { Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken }, new AuthenticationToken { Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken } }; AuthenticateResult info = await context.AuthenticateAsync(_cookieSchemeName); info.Properties.StoreTokens(tokens); await context.SignInAsync(_cookieSchemeName, info.Principal, info.Properties); } } } await _next.Invoke(context); }
/// <inheritdoc /> public async Task <TokenRefreshResult> TryRefreshTokenIfRequiredAsync( string refreshToken, string expiresAt, CancellationToken ct) { //检查我们是否有刷新令牌,如果没有,则失败。 if (string.IsNullOrWhiteSpace(refreshToken)) { return(TokenRefreshResult.Failed()); } //检查令牌的到期日期是否低于阈值,如果不是,我们可以NoRefreshNeeded立即返回。 if (!DateTime.TryParse(expiresAt, out var expiresAtDate) || expiresAtDate >= GetRefreshThreshold()) { return(TokenRefreshResult.NoRefreshNeeded()); } //使用提取提供商信息_discoveryCache。 var discovered = await _discoveryCache.GetAsync(); /* * RequestRefreshTokenAsync是IdentityModelNuGet包的扩展方法,可简化刷新令牌请求的创建 */ var tokenResult = await _httpClient.RequestRefreshTokenAsync( new RefreshTokenRequest { Address = discovered.TokenEndpoint, ClientId = "5440496238", ClientSecret = "saQR67zTYy", RefreshToken = refreshToken }, ct); ////如果令牌刷新成功,则返回成功并提供所需的信息,否则返回失败。 if (tokenResult.IsError) { _logger.LogDebug( "Unable to refresh token, reason: {refreshTokenErrorDescription}", tokenResult.ErrorDescription); return(TokenRefreshResult.Failed()); } //如果令牌刷新成功,则返回成功并提供所需的信息 var newAccessToken = tokenResult.AccessToken; var newRefreshToken = tokenResult.RefreshToken; var newExpiresAt = CalculateNewExpiresAt(tokenResult.ExpiresIn); return(TokenRefreshResult.Success(newAccessToken, newRefreshToken, newExpiresAt)); }
private static async Task DeviceAuthorizationRequest() { var discoDoc = await discoCache.GetAsync(); if (discoDoc.IsError) { throw new Exception("Unable to load discovery document"); } var httpClient = new HttpClient(); var response = await httpClient.RequestDeviceAuthorizationAsync(new DeviceAuthorizationRequest { Address = discoDoc.DeviceAuthorizationEndpoint, ClientId = "device_console" }); }
private async Task <ActionResult> RedirectToExternalProvider(string query) { var discoveryResponse = await _discoveryCache.GetAsync(); if (discoveryResponse.IsError) { _discoveryCache.Refresh(); throw new Exception(discoveryResponse.Error); } var externalAuthorizeUrl = $"{discoveryResponse.AuthorizeEndpoint}{query}"; _log.Info( $"Redirect URI substitued, trying to proxy to external provider on {externalAuthorizeUrl}"); return(Redirect(externalAuthorizeUrl)); }
public async Task <IActionResult> Login([FromRoute] string platform, [FromQuery] string returnUrl) { string clientId; string signinCallback; switch (platform) { case "android": clientId = _ironcladSettings.AndroidClient.ClientId; signinCallback = Url.AbsoluteAction("SigninCallbackAndroid", "Callback"); break; case "ios": clientId = _ironcladSettings.IosClient.ClientId; signinCallback = Url.AbsoluteAction("SigninCallbackIos", "Callback"); break; default: return(BadRequest()); } var discoveryResponse = await _discoveryCache.GetAsync(); if (discoveryResponse.IsError) { _discoveryCache.Refresh(); throw new Exception(discoveryResponse.Error); } var authorizeRequest = new Dictionary <string, string> { { OidcConstants.AuthorizeRequest.ClientId, clientId }, { OidcConstants.AuthorizeRequest.RedirectUri, signinCallback }, { OidcConstants.AuthorizeRequest.Scope, "profile openid email lykke offline_access" }, { OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code }, { OidcConstants.AuthorizeRequest.Nonce, "mn4vcynp2tOEj7W9m88l" }, { OidcConstants.AuthorizeRequest.State, "ttoY604BgSsliwgcnIt8" } }; var query = QueryString.Create(authorizeRequest); var externalAuthorizeUrl = $"{discoveryResponse.AuthorizeEndpoint}{query.ToUriComponent()}"; return(Redirect(externalAuthorizeUrl)); }
public async Task <IActionResult> RenewTokens() { var disco = await _discoveryCache.GetAsync(); if (disco.IsError) { throw new Exception(disco.Error); } var rt = await HttpContext.GetTokenAsync("refresh_token"); var tokenClient = _httpClientFactory.CreateClient(); var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest { Address = disco.TokenEndpoint, ClientId = "mvc.code", ClientSecret = "secret", RefreshToken = rt }); if (!tokenResult.IsError) { var oldIdToken = await HttpContext.GetTokenAsync("id_token"); var newAccessToken = tokenResult.AccessToken; var newRefreshToken = tokenResult.RefreshToken; var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn); var info = await HttpContext.AuthenticateAsync("Cookies"); info.Properties.UpdateTokenValue("refresh_token", newRefreshToken); info.Properties.UpdateTokenValue("access_token", newAccessToken); info.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture)); await HttpContext.SignInAsync("Cookies", info.Principal, info.Properties); return(Redirect("~/Home/Secure")); } ViewData["Error"] = tokenResult.Error; return(View("Error")); }
/// <inheritdoc /> public async Task <TokenRefreshResult> TryRefreshTokenIfRequiredAsync( string refreshToken, string expiresAt, CancellationToken ct) { if (string.IsNullOrWhiteSpace(refreshToken)) { return(TokenRefreshResult.Failed()); } if (!DateTime.TryParse(expiresAt, out var expiresAtDate) || expiresAtDate >= GetRefreshThreshold()) { return(TokenRefreshResult.NoRefreshNeeded()); } var discovered = await _discoveryCache.GetAsync(); var tokenResult = await _httpClient.RequestRefreshTokenAsync( new RefreshTokenRequest { Address = discovered.TokenEndpoint, ClientId = "WebFrontend", ClientSecret = "secret", RefreshToken = refreshToken }, ct); if (tokenResult.IsError) { _logger.LogDebug( "Unable to refresh token, reason: {refreshTokenErrorDescription}", tokenResult.ErrorDescription); return(TokenRefreshResult.Failed()); } var newAccessToken = tokenResult.AccessToken; var newRefreshToken = tokenResult.RefreshToken; var newExpiresAt = CalculateNewExpiresAt(tokenResult.ExpiresIn); return(TokenRefreshResult.Success(newAccessToken, newRefreshToken, newExpiresAt)); }
private async Task VerifyAndCacheToken(JwtSecurityToken jwt) { var discovery = await discoveryCache.GetAsync(); if (discovery.IsError) { throw new Exception("Unauthorized (authority discovery failed)"); } var client = httpClientFactory.CreateClient(); // this user/pass combo is specific to the IdentityServer demo authority, // and the use of scope as the username is generally specific to IdentityServer client.SetBasicAuthenticationOAuth("api", "secret"); var tokenResponse = await client.IntrospectTokenAsync( new TokenIntrospectionRequest { Address = discovery.IntrospectionEndpoint, ClientId = "interactive.confidential", ClientSecret = "secret", Token = jwt.RawData }); if (tokenResponse.IsError) { throw new Exception($"Unauthorized (introspection error: {tokenResponse.Error})"); } if (!tokenResponse.IsActive) { throw new Exception("Unauthorized (token deactivated by authority)"); } var key = GetCacheKey(jwt); memoryCache.Set(key, jwt.RawData); }
public async Task <TokenResponse> RefreshAccessTokenAsync() { var document = await _discoveryCache.GetAsync(); var tokenClient = _httpClientFactory.CreateClient("tokenClient"); var tokenResonse = await tokenClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest() { Address = document.TokenEndpoint, ClientId = _tenant.Credentials.ClientId, ClientSecret = _tenant.Credentials.ClientSecret, }); lock (_accessLock) { CurrentTokenRecord = new TokenRecord { TokenResponse = tokenResonse, ClientCredential = _tenant.Credentials, Expiration = DateTime.UtcNow.AddSeconds(tokenResonse.ExpiresIn - 300) // give a 5 minute skew. }; return(tokenResonse); } }
static async Task <BackchannelAuthenticationResponse> RequestBackchannelLoginAsync() { var disco = await _cache.GetAsync(); if (disco.IsError) { throw new Exception(disco.Error); } var cibaEp = disco.BackchannelAuthenticationEndpoint; var username = "******"; var bindingMessage = Guid.NewGuid().ToString("N").Substring(0, 10); var req = new BackchannelAuthenticationRequest() { Address = cibaEp, ClientId = "ciba", ClientSecret = "secret", Scope = "openid profile email resource1.scope1 offline_access", LoginHint = username, //IdTokenHint = "eyJhbGciOiJSUzI1NiIsImtpZCI6IkYyNjZCQzA3NTFBNjIyNDkzMzFDMzI4QUQ1RkIwMkJGIiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo1MDAxIiwibmJmIjoxNjM4NDc3MDE2LCJpYXQiOjE2Mzg0NzcwMTYsImV4cCI6MTYzODQ3NzMxNiwiYXVkIjoiY2liYSIsImFtciI6WyJwd2QiXSwiYXRfaGFzaCI6ImE1angwelVQZ2twczBVS1J5VjBUWmciLCJzaWQiOiIzQTJDQTJDNjdBNTAwQ0I2REY1QzEyRUZDMzlCQTI2MiIsInN1YiI6IjgxODcyNyIsImF1dGhfdGltZSI6MTYzODQ3NzAwOCwiaWRwIjoibG9jYWwifQ.GAIHXYgEtXw5NasR0zPMW3jSKBuWujzwwnXJnfHdulKX-I3r47N0iqHm5v5V0xfLYdrmntjLgmdm0DSvdXswtZ1dh96DqS1zVm6yQ2V0zsA2u8uOt1RG8qtjd5z4Gb_wTvks4rbUiwi008FOZfRuqbMJJDSscy_YdEJqyQahdzkcUnWZwdbY8L2RUTxlAAWQxktpIbaFnxfr8PFQpyTcyQyw0b7xmYd9ogR7JyOff7IJIHPDur0wbRdpI1FDE_VVCgoze8GVAbVxXPtj4CtWHAv07MJxa9SdA_N-lBcrZ3PHTKQ5t1gFXwdQvp3togUJl33mJSru3lqfK36pn8y8ow", BindingMessage = bindingMessage, RequestedExpiry = 200 }; bool useRequestObject = false; if (useRequestObject) { req = new BackchannelAuthenticationRequest { Address = req.Address, ClientId = req.ClientId, ClientSecret = req.ClientSecret, RequestObject = CreateRequestObject(new Dictionary <string, string> { { OidcConstants.BackchannelAuthenticationRequest.Scope, req.Scope }, { OidcConstants.BackchannelAuthenticationRequest.LoginHint, req.LoginHint }, { OidcConstants.BackchannelAuthenticationRequest.IdTokenHint, req.IdTokenHint }, { OidcConstants.BackchannelAuthenticationRequest.BindingMessage, req.BindingMessage }, }), }; } var client = new HttpClient(); var response = await client.RequestBackchannelAuthenticationAsync(req); if (response.IsError) { throw new Exception(response.Error); } Console.WriteLine($"Login Hint : {username}"); Console.WriteLine($"Binding Message : {bindingMessage}"); Console.WriteLine($"Authentication Request Id : {response.AuthenticationRequestId}"); Console.WriteLine($"Expires In : {response.ExpiresIn}"); Console.WriteLine($"Interval : {response.Interval}"); Console.WriteLine(); Console.WriteLine($"\nPress enter to start polling the token endpoint."); Console.ReadLine(); return(response); }
public async Task <DiscoveryResponse> GetDiscoveryDocumentAsync(DiscoveryDocumentRequest?request = null, CancellationToken cancellationToken = default) { return(await _discoveryCache.GetAsync().ConfigureAwait(false)); }