public async Task<IAuthenticatedCrest> Authenticate(string clientId, string clientSecret, Uri listenUri, AuthenticatedCrestScope scope) { var result = new AuthenticatedCrest { ClientId = clientId, ClientSecret = clientSecret }; var state = Guid.NewGuid(); try { return await Task.Factory.StartNew( () => { _authenticatedCrests[state] = result; WEBSERVER.ListenFor(listenUri); var scopeString = GetScopeString(scope); Process.Start( $"{Settings.SsoUrl}oauth/authorize?response_type=code&redirect_uri={HttpUtility.UrlEncode(listenUri.ToString())}&client_id={clientId}&state={state}&scope={scopeString}"); var start = DateTime.UtcNow; while (result.State == AuthenticatedCrestState.WaitingForAuthentication && (DateTime.UtcNow - start) < Settings.AuthenticationTimeout) { lock (_monitor) { Monitor.Wait(_monitor, Settings.AuthenticationTimeout); } } //check for timeout if (result.State == AuthenticatedCrestState.WaitingForAuthentication) { result.State = AuthenticatedCrestState.AuthenticationFailed; } return result; }, TaskCreationOptions.LongRunning) .ConfigureAwait(false); } catch (Exception e) { Log.Logger.Error(e, $"Could not authenticate/authorize {clientId}"); result.State = AuthenticatedCrestState.AuthenticationFailed; } finally { _authenticatedCrests.Remove(state); } return result; }
public static async Task<CrestAuthorization> RequestCrestAuthorization(AuthenticatedCrest authenticatedCrest) { var startOfRequest = DateTime.UtcNow; var request = (HttpWebRequest) WebRequest.Create($"{Crest.Settings.SsoUrl}oauth/token"); var data = Encoding.ASCII.GetBytes($"grant_type=authorization_code&code={authenticatedCrest.AccessToken}"); //token is one time use only authenticatedCrest.AccessToken = null; request.Method = "POST"; request.UserAgent = Crest.UserAgent; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; var base64ClientData = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{authenticatedCrest.ClientId}:{authenticatedCrest.ClientSecret}")); request.Headers["Authorization"] = $"Basic {base64ClientData}"; using (var stream = await request.GetRequestStreamAsync()) { stream.Write(data, 0, data.Length); } using (var response = (HttpWebResponse) await request.GetResponseAsync()) { using (var resStream = response.GetResponseStream()) { if (resStream == null) { throw new Exception($"Could not get response stream for {request}"); } using (var reader = new StreamReader(resStream)) { var stringResult = reader.ReadToEnd(); var jsonModel = JsonConvert.DeserializeObject<CrestAuthorizationJsonModel>(stringResult); return new CrestAuthorization( jsonModel.access_token, startOfRequest + TimeSpan.FromSeconds(jsonModel.expires_in), jsonModel.token_type, jsonModel.refresh_token); } } } }
public async Task<IAuthenticatedCrest> Authenticate(string clientId, string clientSecret, string refreshToken) { var result = new AuthenticatedCrest { ClientId = clientId, ClientSecret = clientSecret, CrestAuthorization = new CrestAuthorization(null, DateTime.MinValue, null, refreshToken) }; await result.Refresh().ConfigureAwait(false); return result; }