示例#1
0
 private async Task <HttpWebResponse> GetAuthAsync(AuthMsg msg)
 {
     return(await ServerCallAsync("about", c =>
     {
         // set Authorization header
         c.Headers.Set("Authorization", msg.ToString());
     }));
 }
        private HttpWebResponse GetAuth(AuthMsg msg)
        {
            try
            {
                // all AuthClientContext requests are GET message to the /About uri
                var c = Prepare(OpenHttpConnection(uri, "GET"));

                // set Authorization header
                c.Headers.Set("Authorization", msg.ToString());
                return(Get(c));
            }
            catch (IOException e)
            {
                throw e;
            }
        }
        /// <summary>
        ///   Attempt standard authentication
        /// </summary>
        /// <param name="resp"> The response to the hello message </param>
        /// <returns>
        ///   true if haystack authentciation was used, false if the
        ///   server does not appear to implement RFC 7235.
        /// </returns>
        private bool OpenStd(HttpWebResponse resp)
        {
            // must be 401 challenge with WWW-Authenticate header
            if (resp.StatusCode != HttpStatusCode.Unauthorized)
            {
                return(false);
            }
            var wwwAuth = ResHeader(resp, "WWW-Authenticate");

            // don't Use this mechanism for Basic which we
            // handle as a non-standard scheme because the headers
            // don't fit nicely into our restricted AuthMsg format
            if (string.IsNullOrEmpty(wwwAuth) || wwwAuth.ToLower().StartsWith("basic", StringComparison.Ordinal))
            {
                return(false);
            }
            // process res/req messages until we have 200 or non-401 failure
            AuthScheme scheme = null;

            for (var loopCount = 0; ; ++loopCount)
            {
                // sanity check that we don't loop too many times
                if (loopCount > 5)
                {
                    throw new AuthException("Loop count exceeded");
                }

                // parse the WWW-Auth header and Use the first scheme
                var       header  = ResHeader(resp, "WWW-Authenticate");
                AuthMsg[] resMsgs = AuthMsg.ListFromStr(header);
                var       resMsg  = resMsgs[0];
                scheme = AuthScheme.Find(resMsg.scheme);

                // let scheme handle message
                var reqMsg = scheme.OnClient(this, resMsg);
                // send request back to the server
                resp = GetAuth(reqMsg);
                try
                {
                    DumpRes(resp, false);
                }
                catch (Exception e)
                {
                    e.ToString();
                }
                // 200 means we are done, 401 means keep looping,
                // consider anything else a failure
                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    break;
                }
                if (resp.StatusCode == HttpStatusCode.Unauthorized)
                {
                    continue;
                }
                throw new AuthException((int)resp.StatusCode + " " + resp.GetResponseStream());
            }
            // init the bearer token
            var     authInfo    = ResHeader(resp, "Authentication-Info");
            AuthMsg authInfoMsg = AuthMsg.FromStr("bearer " + authInfo);

            // callback to scheme for client Success
            scheme.OnClientSuccess(this, authInfoMsg);

            // only keep authToken parameter for Authorization header
            authInfoMsg = new AuthMsg("bearer", new[]
            {
                "authToken",
                authInfoMsg.Param("authToken")
            });
            headers["Authorization"] = authInfoMsg.ToString();

            // we did it!
            return(true);
        }