Exemplo n.º 1
0
        public async Task DiscoverEndpoints(IHttpClientFactory factory)
        {
            var httpClient = factory.CreateClient();
            var disco      = await httpClient.GetDiscoveryDocumentAsync(Issuer);

            if (!disco.IsError)
            {
                AccessTokenUrl = disco.TokenEndpoint;
                AuthorizeUrl   = disco.AuthorizeEndpoint;
                JwkSetUrl      = disco.JwksUri;
            }
            else if (AccessTokenUrl.IsPresent())
            {
                disco = await httpClient.GetDiscoveryDocumentAsync(AccessTokenUrl);

                if (!disco.IsError)
                {
                    AccessTokenUrl = disco.TokenEndpoint;
                    AuthorizeUrl   = disco.AuthorizeEndpoint;
                    JwkSetUrl      = disco.JwksUri;
                }
                else if (AuthorizeUrl.IsPresent())
                {
                    disco = await httpClient.GetDiscoveryDocumentAsync(AuthorizeUrl);

                    if (!disco.IsError)
                    {
                        AccessTokenUrl = disco.TokenEndpoint;
                        AuthorizeUrl   = disco.AuthorizeEndpoint;
                        JwkSetUrl      = disco.JwksUri;
                    }
                }
                else if (JwkSetUrl.IsPresent())
                {
                    disco = await httpClient.GetDiscoveryDocumentAsync(JwkSetUrl);

                    if (!disco.IsError)
                    {
                        AccessTokenUrl = disco.TokenEndpoint;
                        AuthorizeUrl   = disco.AuthorizeEndpoint;
                        JwkSetUrl      = disco.JwksUri;
                    }
                }
            }
        }
Exemplo n.º 2
0
        public override async Task <object> AuthenticateAsync(IServiceBase authService, IAuthSession session, Authenticate request, CancellationToken token = default)
        {
            var tokens = Init(authService, ref session, request);
            var ctx    = CreateAuthContext(authService, session, tokens);

            //Transferring AccessToken/Secret from Mobile/Desktop App to Server
            if (request?.AccessToken != null && VerifyAccessTokenAsync != null)
            {
                if (!await VerifyAccessTokenAsync(request.AccessToken, ctx).ConfigAwait())
                {
                    return(HttpError.Unauthorized(ErrorMessages.InvalidAccessToken.Localize(authService.Request)));
                }

                var isHtml       = authService.Request.IsHtml();
                var failedResult = await AuthenticateWithAccessTokenAsync(authService, session, tokens, request.AccessToken, ctx.AuthInfo, token : token).ConfigAwait();

                if (failedResult != null)
                {
                    return(ConvertToClientError(failedResult, isHtml));
                }

                return(isHtml
                    ? await authService.Redirect(SuccessRedirectUrlFilter(ctx, session.ReferrerUrl.SetParam("s", "1"))).SuccessAuthResultAsync(authService, session).ConfigAwait()
                    : null); //return default AuthenticateResponse
            }

            var httpRequest = authService.Request;
            var error       = httpRequest.GetQueryStringOrForm("error_reason")
                              ?? httpRequest.GetQueryStringOrForm("error")
                              ?? httpRequest.GetQueryStringOrForm("error_code")
                              ?? httpRequest.GetQueryStringOrForm("error_description");

            var hasError = !error.IsNullOrEmpty();

            if (hasError)
            {
                var httpParams = HttpUtils.HasRequestBody(httpRequest.Verb)
                    ? httpRequest.QueryString
                    : httpRequest.FormData;
                Log.Error($"OAuth2 Error callback. {httpParams}");
                return(authService.Redirect(FailedRedirectUrlFilter(ctx, session.ReferrerUrl.SetParam("f", error))));
            }

            var code = httpRequest.GetQueryStringOrForm(Keywords.Code);
            var isPreAuthCallback = !code.IsNullOrEmpty();

            if (!isPreAuthCallback)
            {
                var oauthstate = session.Id;
                var preAuthUrl = AuthorizeUrl
                                 .AddQueryParam("response_type", "code")
                                 .AddQueryParam("client_id", ConsumerKey)
                                 .AddQueryParam("redirect_uri", this.CallbackUrl)
                                 .AddQueryParam("scope", string.Join(" ", Scopes))
                                 .AddQueryParam(Keywords.State, oauthstate);

                if (ResponseMode != null)
                {
                    preAuthUrl = preAuthUrl.AddQueryParam("response_mode", ResponseMode);
                }

                if (session is AuthUserSession authSession)
                {
                    (authSession.Meta ?? (authSession.Meta = new Dictionary <string, string>()))["oauthstate"] = oauthstate;
                }

                await this.SaveSessionAsync(authService, session, SessionExpiry, token).ConfigAwait();

                return(authService.Redirect(PreAuthUrlFilter(ctx, preAuthUrl)));
            }

            try
            {
                var state = httpRequest.GetQueryStringOrForm(Keywords.State);
                if (state != null && session is AuthUserSession authSession)
                {
                    if (authSession.Meta == null)
                    {
                        authSession.Meta = new Dictionary <string, string>();
                    }

                    if (authSession.Meta.TryGetValue("oauthstate", out var oauthState) && state != oauthState)
                    {
                        return(authService.Redirect(FailedRedirectUrlFilter(ctx, session.ReferrerUrl.SetParam("f", "InvalidState"))));
                    }

                    authSession.Meta.Remove("oauthstate");
                }

                var contents = await GetAccessTokenJsonAsync(code, ctx, token).ConfigAwait();

                var authInfo = (Dictionary <string, object>)JSON.parse(contents);
                ctx.AuthInfo = authInfo.ToStringDictionary();

                var accessToken = (string)authInfo["access_token"];

                var redirectUrl = SuccessRedirectUrlFilter(ctx, session.ReferrerUrl.SetParam("s", "1"));

                var errorResult = await AuthenticateWithAccessTokenAsync(authService, session, tokens, accessToken, ctx.AuthInfo, token).ConfigAwait();

                if (errorResult != null)
                {
                    return(errorResult);
                }

                //Haz Access!
                if (HostContext.Config?.UseSameSiteCookies == true)
                {
                    // Workaround Set-Cookie HTTP Header not being honoured in 302 Redirects
                    var redirectHtml = HtmlTemplates.GetHtmlRedirectTemplate(redirectUrl);
                    return(await new HttpResult(redirectHtml, MimeTypes.Html).SuccessAuthResultAsync(authService, session).ConfigAwait());
                }

                return(await authService.Redirect(redirectUrl).SuccessAuthResultAsync(authService, session).ConfigAwait());
            }
            catch (WebException we)
            {
                var errorBody = await we.GetResponseBodyAsync(token).ConfigAwait();

                Log.Error($"Failed to get Access Token for '{Provider}': {errorBody}");

                var statusCode = ((HttpWebResponse)we.Response).StatusCode;
                if (statusCode == HttpStatusCode.BadRequest)
                {
                    return(authService.Redirect(FailedRedirectUrlFilter(ctx, session.ReferrerUrl.SetParam("f", "AccessTokenFailed"))));
                }
            }

            //Shouldn't get here
            return(authService.Redirect(FailedRedirectUrlFilter(ctx, session.ReferrerUrl.SetParam("f", "Unknown"))));
        }
Exemplo n.º 3
0
        public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
        {
            var tokens = Init(authService, ref session, request);

            //Transferring AccessToken/Secret from Mobile/Desktop App to Server
            if (request?.AccessToken != null && VerifyAccessToken != null)
            {
                if (!VerifyAccessToken(request.AccessToken))
                {
                    return(HttpError.Unauthorized("AccessToken is not for client_id: " + ConsumerKey));
                }

                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;
            var error       = httpRequest.QueryString["error_reason"]
                              ?? httpRequest.QueryString["error"]
                              ?? httpRequest.QueryString["error_code"]
                              ?? httpRequest.QueryString["error_description"];

            var hasError = !error.IsNullOrEmpty();

            if (hasError)
            {
                Log.Error($"OAuth2 Error callback. {httpRequest.QueryString}");
                return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", error))));
            }

            var code = httpRequest.QueryString[Keywords.Code];
            var isPreAuthCallback = !code.IsNullOrEmpty();

            if (!isPreAuthCallback)
            {
                var oauthstate = SessionExtensions.CreateRandomSessionId();
                var preAuthUrl = AuthorizeUrl
                                 .AddQueryParam("response_type", "code")
                                 .AddQueryParam("client_id", ConsumerKey)
                                 .AddQueryParam("redirect_uri", this.CallbackUrl)
                                 .AddQueryParam("scope", string.Join(" ", Scopes))
                                 .AddQueryParam(Keywords.State, oauthstate);

                if (session is AuthUserSession authSession)
                {
                    (authSession.Meta ?? (authSession.Meta = new Dictionary <string, string>()))["oauthstate"] = oauthstate;
                }

                this.SaveSession(authService, session, SessionExpiry);
                return(authService.Redirect(PreAuthUrlFilter(this, preAuthUrl)));
            }

            try
            {
                var state = httpRequest.QueryString[Keywords.State];
                if (state != null && session is AuthUserSession authSession)
                {
                    if (authSession.Meta.TryGetValue("oauthstate", out var oauthState) && state != oauthState)
                    {
                        return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "InvalidState"))));
                    }

                    authSession.Meta.Remove("oauthstate");
                }

                var contents = GetAccessTokenJson(code);
                var authInfo = JsonObject.Parse(contents);

                var accessToken = authInfo["access_token"];

                return(AuthenticateWithAccessToken(authService, session, tokens, accessToken)
                       ?? authService.Redirect(SuccessRedirectUrlFilter(this, session.ReferrerUrl.SetParam("s", "1")))); //Haz Access!
            }
            catch (WebException we)
            {
                string errorBody  = we.GetResponseBody();
                var    statusCode = ((HttpWebResponse)we.Response).StatusCode;
                if (statusCode == HttpStatusCode.BadRequest)
                {
                    return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "AccessTokenFailed"))));
                }
            }

            //Shouldn't get here
            return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "Unknown"))));
        }
 protected string GetUserInfoUrl()
 {
     return(AuthorizeUrl.GetOauth2UserInfoUrl(Request.Url.ToString()));
 }
 protected string GetOpenIdUrl()
 {
     return(AuthorizeUrl.GetOauth2BaseUrl(Request.Url.ToString()));
 }
Exemplo n.º 6
0
        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)
            {
                if (!AuthHttpGateway.VerifyGoogleAccessToken(ConsumerKey, request.AccessToken))
                {
                    return(HttpError.Unauthorized("AccessToken is not for client_id: " + ConsumerKey));
                }

                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;
            var error       = httpRequest.QueryString["error_reason"]
                              ?? httpRequest.QueryString["error"]
                              ?? httpRequest.QueryString["error_code"]
                              ?? httpRequest.QueryString["error_description"];

            var hasError = !error.IsNullOrEmpty();

            if (hasError)
            {
                Log.Error($"Google error callback. {httpRequest.QueryString}");
                return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", error))));
            }

            var code = httpRequest.QueryString[Keywords.Code];
            var isPreAuthCallback = !code.IsNullOrEmpty();

            if (!isPreAuthCallback)
            {
                var preAuthUrl = AuthorizeUrl
                                 .AddQueryParam("response_type", "code")
                                 .AddQueryParam("client_id", ConsumerKey)
                                 .AddQueryParam("redirect_uri", this.CallbackUrl)
                                 .AddQueryParam("scope", string.Join(" ", Scopes));

                this.SaveSession(authService, session, SessionExpiry);
                return(authService.Redirect(PreAuthUrlFilter(this, preAuthUrl)));
            }

            try
            {
                var accessTokenUrl = $"{AccessTokenUrl}?code={code}&client_id={ConsumerKey}&client_secret={ConsumerSecret}&redirect_uri={this.CallbackUrl.UrlEncode()}&grant_type=authorization_code";
                var contents       = AccessTokenUrlFilter(this, accessTokenUrl).PostToUrl("");
                var authInfo       = JsonObject.Parse(contents);

                var accessToken = authInfo["access_token"];

                return(AuthenticateWithAccessToken(authService, session, tokens, accessToken)
                       ?? authService.Redirect(SuccessRedirectUrlFilter(this, session.ReferrerUrl.SetParam("s", "1")))); //Haz Access!
            }
            catch (WebException we)
            {
                string errorBody  = we.GetResponseBody();
                var    statusCode = ((HttpWebResponse)we.Response).StatusCode;
                if (statusCode == HttpStatusCode.BadRequest)
                {
                    return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "AccessTokenFailed"))));
                }
            }

            //Shouldn't get here
            return(authService.Redirect(FailedRedirectUrlFilter(this, session.ReferrerUrl.SetParam("f", "Unknown"))));
        }