Exemplo n.º 1
0
        private IPromise <ICredentials> DefaultAuthCallback(INetCredentials netCred, string endpoint, bool async)
        {
            var promise = new Promise <ICredentials>();

            if (string.IsNullOrEmpty(endpoint))
            {
                promise.Resolve(netCred);
            }
            else
            {
                var handler = new SyncClientHandler()
                {
                    Credentials     = netCred.Credentials,
                    PreAuthenticate = true
                };
                var http = new SyncHttpClient(handler);

                var endpointUri = new Uri(endpoint + "?db=" + netCred.Database);
                var trace       = new LogData(4, "Innovator: Authenticate user via mapping", Factory.LogListener)
                {
                    { "database", netCred.Database },
                    { "user_name", netCred.Credentials.GetCredential(endpointUri, null).UserName },
                    { "url", endpointUri },
                };
                http.GetPromise(endpointUri, async, trace)
                .Done(r =>
                {
                    var res  = r.AsXml().DescendantsAndSelf("Result").FirstOrDefault();
                    var user = res.Element("user").Value;
                    var pwd  = res.Element("password").Value;
                    if (pwd.IsNullOrWhiteSpace())
                    {
                        promise.Reject(new ArgumentException("Failed to authenticate with Innovator server '" + endpoint + "'. Original error: " + user, "credentials"));
                    }

                    var needHash = !string.Equals(res.Element("hash").Value, "false", StringComparison.OrdinalIgnoreCase);
                    if (needHash)
                    {
                        promise.Resolve(new ExplicitCredentials(netCred.Database, user, pwd));
                    }
                    else
                    {
                        promise.Resolve(new ExplicitHashCredentials(netCred.Database, user, pwd));
                    }
                }).Fail(ex =>
                {
                    // Only hard fail for problems which aren't time outs and not found issues.
                    var webEx = ex as HttpException;
                    if (webEx != null && webEx.Response.StatusCode == HttpStatusCode.NotFound)
                    {
                        promise.Resolve(netCred);
                    }
                    else if (webEx != null && webEx.Response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        promise.Reject(ElementFactory.Local.ServerException("Invalid username or password"));
                    }
                    else if (webEx != null)
                    {
                        try
                        {
                            var result = ElementFactory.Local.FromXml(webEx.Response.AsStream);
                            if (result.Exception != null)
                            {
                                promise.Reject(result.Exception);
                            }
                            else
                            {
                                promise.Reject(ex);
                            }
                        }
                        catch (Exception)
                        {
                            promise.Reject(ex);
                        }
                    }
                    else if (ex is TaskCanceledException)
                    {
                        promise.Resolve(netCred);
                    }
                    else
                    {
                        promise.Reject(ex);
                    }
                }).Always(trace.Dispose);
            }

            return(promise);
        }
Exemplo n.º 2
0
        private IPromise <TokenCredentials> GetCredentials(bool async)
        {
            var req = new HttpRequest
            {
                Content = new SimpleContent(new Dictionary <string, string>()
                {
                    { "client_id", "IOMApp" },
                    { "grant_type", "password" },
                    { "scope", "Innovator" },
                    { "username", Uri.EscapeDataString(_hashCred.Username) },
                    { "database", Uri.EscapeDataString(_hashCred.Database) },
                    { "password", Uri.EscapeDataString(_hashCred.PasswordHash) },
                }.Select(k => k.Key + "=" + k.Value).GroupConcat("&"), "application/x-www-form-urlencoded")
            };

            req.Headers.Add("Accept", "application/json");
            var result = new Promise <TokenCredentials>();

            result.CancelTarget(
                _service.PostPromise(_config.TokenEndpoint, async, req, new LogData(4
                                                                                    , "Innovator: Get OAuth token"
                                                                                    , Factory.LogListener)
            {
                { "database", _hashCred.Database },
                { "url", _config.TokenEndpoint },
                { "user_name", _hashCred.Username },
            })
                .Convert(r => new TokenCredentials(r.AsStream, _hashCred.Database))
                .Done(result.Resolve)
                .Fail(e =>
            {
                try
                {
                    if (!(e is HttpException httpEx))
                    {
                        result.Reject(e);
                        return;
                    }
                    var faultCode   = default(string);
                    var faultstring = default(string);
                    using (var reader = new Json.Embed.JsonTextReader(httpEx.Response.AsStream))
                    {
                        foreach (var kvp in reader.Flatten())
                        {
                            switch (kvp.Key)
                            {
                            case "$.error":
                                faultCode = kvp.Value?.ToString();
                                break;

                            case "$.error_description":
                                faultstring = kvp.Value?.ToString();
                                break;
                            }
                        }
                    }

                    result.Reject(ElementFactory.Local.FromXml(@"<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:i18n='http://www.aras.com/I18N'>
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode>@0</faultcode>
      <faultstring>@1</faultstring>
      <faultactor>OAuthServer</faultactor>
      <detail>unknown error</detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>", faultCode, faultstring).Exception);
                }
                catch (Exception ex)
                {
                    result.Reject(ex);
                }
            }));
            return(result);
        }
Exemplo n.º 3
0
        public static IPromise <IAuthenticator> GetAuthenticator(Uri innovatorServerBaseUrl, HttpClient service, ICredentials creds, bool async)
        {
            var discovery = new Uri(innovatorServerBaseUrl, "OAuthServerDiscovery.aspx");
            var req       = new HttpRequest();

            req.Headers.Add("Aras-Set-HttpSessionState-Behavior", "switch_to_initial");
            var oauthBaseUri = default(Uri);

            var result = new Promise <IAuthenticator>();

            result.CancelTarget(
                service.GetPromise(discovery, async, new LogData(4
                                                                 , "Innovator: Get OAuth URL"
                                                                 , Factory.LogListener)
            {
                { "url", discovery },
            }, req)
                .Continue(r =>
            {
                if (r.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    throw new Exception("OAuth not found");
                }

                var serverUrls = default(List <Uri>);
                using (var json = new Json.Embed.JsonTextReader(r.AsStream))
                {
                    serverUrls = json.Flatten()
                                 .Where(k => k.Key.StartsWith("$.locations[") &&
                                        k.Key.EndsWith("].uri") &&
                                        k.Value is string str &&
                                        !string.IsNullOrEmpty(str))
                                 .Select(k => new Uri(k.Value.ToString()))
                                 .OrderBy(u => string.Equals(u.Host, innovatorServerBaseUrl.Host, StringComparison.OrdinalIgnoreCase) ? 0 : 1)
                                 .ToList();
                }

                if (serverUrls?.Count < 1)
                {
                    throw new InvalidOperationException("OAuth server URL could not be found");
                }

                oauthBaseUri = serverUrls[0];
                var oauthUri = new Uri(oauthBaseUri, ".well-known/openid-configuration");
                return(service.GetPromise(oauthUri, async, new LogData(4
                                                                       , "Innovator: Get OAuth Config"
                                                                       , Factory.LogListener)
                {
                    { "url", oauthUri },
                }));
            })
                .Progress(result.Notify)
                .Done(r =>
            {
                try
                {
                    var config = new OAuthConfig(r.AsString(), oauthBaseUri);
                    if (config.ProtocolVersion >= new Version("1.0"))
                    {
                        result.Resolve(new OAuthAuthenticator(service, config, creds));
                    }
                    else
                    {
                        result.Resolve(new LegacyAuthenticator(innovatorServerBaseUrl, creds));
                    }
                }
                catch (Exception ex)
                {
                    result.Reject(ex);
                }
            })
                .Fail(e =>
            {
                result.Resolve(new LegacyAuthenticator(innovatorServerBaseUrl, creds));
            }));
            return(result);
        }