private object RequestCode(IServiceBase authService, IAuthSession session, AuthUserSession userSession, IAuthTokens tokens) { var state = Guid.NewGuid().ToString("N"); userSession.State = state; var codeRequest = AuthorizeUrl + "?response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}" .Fmt(ClientId, CallbackUrl.UrlEncode(), Scopes.Join(","), state); if (!DomainHint.IsNullOrEmpty()) { codeRequest += "&domain_hint=" + DomainHint; } if (!tokens.UserName.IsNullOrEmpty()) { codeRequest += "&login_hint=" + tokens.UserName; } authService.SaveSession(session, SessionExpiry); return(authService.Redirect(PreAuthUrlFilter(this, codeRequest))); }
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request) { var tokens = Init(authService, ref session, request); //Transfering AccessToken/Secret from Mobile/Desktop App to Server if (request?.AccessToken != null) { //https://developer.github.com/v3/oauth_authorizations/#check-an-authorization var url = VerifyAccessTokenUrl.Fmt(ClientId, request.AccessToken); var json = url.GetJsonFromUrl(requestFilter: httpReq => { httpReq.Headers[HttpRequestHeader.UserAgent] = ServiceClientBase.DefaultUserAgent; httpReq.AddBasicAuth(ClientId, ClientSecret); }); var isHtml = authService.Request.IsHtml(); var failedResult = AuthenticateWithAccessToken(authService, session, tokens, request.AccessToken); if (failedResult != null) { return(ConvertToClientError(failedResult, isHtml)); } return(isHtml ? authService.Redirect(SuccessRedirectUrlFilter(this, session.ReferrerUrl.SetParam("s", "1"))) : null); //return default AuthenticateResponse } var httpRequest = authService.Request; //https://developer.github.com/v3/oauth/#common-errors-for-the-authorization-request var error = httpRequest.QueryString["error"] ?? httpRequest.QueryString["error_uri"] ?? httpRequest.QueryString["error_description"]; var hasError = !error.IsNullOrEmpty(); if (hasError) { Logger.Error($"GitHub error callback. {httpRequest.QueryString}"); return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", error)))); } var code = httpRequest.QueryString["code"]; var isPreAuthCallback = !code.IsNullOrEmpty(); if (!isPreAuthCallback) { var scopes = Scopes.Join("%20"); string preAuthUrl = $"{PreAuthUrl}?client_id={ClientId}&redirect_uri={CallbackUrl.UrlEncode()}&scope={scopes}&state={Guid.NewGuid():N}"; this.SaveSession(authService, session, SessionExpiry); return(authService.Redirect(PreAuthUrlFilter(this, preAuthUrl))); } try { string accessTokenUrl = $"{AccessTokenUrl}?client_id={ClientId}&redirect_uri={CallbackUrl.UrlEncode()}&client_secret={ClientSecret}&code={code}"; var contents = AccessTokenUrlFilter(this, accessTokenUrl).GetStringFromUrl(); var authInfo = PclExportClient.Instance.ParseQueryString(contents); //GitHub does not throw exception, but just return error with descriptions //https://developer.github.com/v3/oauth/#common-errors-for-the-access-token-request var accessTokenError = authInfo["error"] ?? authInfo["error_uri"] ?? authInfo["error_description"]; if (!accessTokenError.IsNullOrEmpty()) { Logger.Error($"GitHub access_token error callback. {authInfo}"); return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "AccessTokenFailed")))); } var accessToken = authInfo["access_token"]; return(AuthenticateWithAccessToken(authService, session, tokens, accessToken) ?? authService.Redirect(SuccessRedirectUrlFilter(this, session.ReferrerUrl.SetParam("s", "1")))); //Haz Access! } catch (WebException webException) { //just in case GitHub will start throwing exceptions var statusCode = ((HttpWebResponse)webException.Response).StatusCode; if (statusCode == HttpStatusCode.BadRequest) { return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "AccessTokenFailed")))); } } return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "Unknown")))); }