Аутентификация ADFS с использованием HttpWebRequest - PullRequest
0 голосов
/ 18 мая 2018

Я работаю над приложением, которое должно подключиться к нашей среде O365.Мы объединены с O365, поэтому пользователи получают доступ к службам со своими обычными сетевыми учетными данными.

Приложение позволяет пользователям подключаться, используя имя пользователя / пароль или встроенную проверку подлинности Windows, когда они подключены к локальной сети.Комбинация имени пользователя и пароля работает нормально, однако, когда я передаю веб-запрос на сервер ADFS с использованием учетных данных по умолчанию, я получаю ответ от ADFS в форме веб-страницы, в которой говорится, что веб-браузер не поддерживает JavaScript:

<div id="noScript" style="position:static; width:100%; height:100%; z-index:100">
    <h1>JavaScript required</h1>
    <p>JavaScript is required. This web browser does not support JavaScript or JavaScript in this web browser is not enabled.</p>
    <p>To find out if your web browser supports JavaScript or to enable JavaScript, see web browser help.</p>
</div>

Я не уверен, почему я получаю это вместо автоматической аутентификации.Я включил код для метода ниже:

    private string GetAdfsSAMLTokenWinAuth()
    {
        // Makes a seurity token request to the corporate ADFS proxy integrated auth endpoint.
        // If the user is logged on to a machine joined to the corporate domain with her Windows credentials and connected
        // to the corporate network Kerberos automatically takes care of authenticating the security token request to ADFS.
        // The logon token is used to talk to MSO STS to get an O365 service token that can then be used to sign into SPO.

        string samlAssertion = null;

        //HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(this.adfsIntegratedAuthUrl);
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.adfsIntegratedAuthUrl);
        request.UseDefaultCredentials = true; // use the default credentials so Kerberos can take care of authenticating our request

        // TODO: This fails becuase the request doesn't support JavaScript... Need to find a way around this...
        byte[] responseData = HttpHelper.SendHttpRequest(
            this.adfsIntegratedAuthUrl,
            "GET",
            null,
            "text/html; charset=utf-8",
            request);

        if (responseData != null)
        {
            try
            {
                StreamReader sr = new StreamReader(new MemoryStream(responseData), Encoding.GetEncoding("utf-8"));
                integratedauthresponse = sr.ReadToEnd();
                XPathNavigator nav = new XPathDocument(sr).CreateNavigator();
                XPathNavigator wresult = nav.SelectSingleNode("/html/body/form/input[@name='wresult']");
                if (wresult != null)
                {
                    responsedata = true;
                    string RequestSecurityTokenResponseText = wresult.GetAttribute("value", "");

                    sr = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(RequestSecurityTokenResponseText)));
                    nav = new XPathDocument(sr).CreateNavigator();
                    XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
                    nsMgr.AddNamespace("t", "http://schemas.xmlsoap.org/ws/2005/02/trust");
                    XPathNavigator requestedSecurityToken = nav.SelectSingleNode("//t:RequestedSecurityToken", nsMgr);

                    // Ensure whitespace is reserved
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(requestedSecurityToken.InnerXml);
                    doc.PreserveWhitespace = true;
                    samlAssertion = doc.InnerXml;
                }
            }
            catch
            {
                // we failed to sign the user using integrated Windows Auth... *sob*
            }
        }
        methodused = "Windows Authentication";
        return samlAssertion;
    }

У кого-нибудь был подобный опыт?Если так, то как вы обошли это?Я не думаю, что могу подделать совместимость с JavaScript, но это не должно иметь значения ... Благодарен за любой совет, который кто-либо может дать по этому поводу.

1 Ответ

0 голосов
/ 26 мая 2018

Мне удалось получить токен из ADFS с помощью встроенной аутентификации с использованием кода ниже:

    public GenericXmlSecurityToken GetToken()
    {
        WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.Transport);
        binding.Security.Message.EstablishSecurityContext = false;
        binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
        WSTrustChannelFactory factory = new WSTrustChannelFactory((binding), new EndpointAddress(stsEndpoint));
        factory.TrustVersion = TrustVersion.WSTrustFeb2005;
        factory.Credentials.SupportInteractive = false;
        var rst = new RequestSecurityToken
        {
            RequestType = RequestTypes.Issue,
            AppliesTo = new EndpointReference(realm),
            KeyType = KeyTypes.Bearer
        };
        IWSTrustChannelContract channel = factory.CreateChannel();
        return channel.Issue(rst) as GenericXmlSecurityToken;
    }
...