简体   繁体   English

使用HttpWebRequest进行ADFS身份验证

[英]ADFS authentication using HttpWebRequest

I'm working on an application which has to connect to our O365 environment. 我正在开发一个必须连接到我们的O365环境的应用程序。 We are federated with O365, so users access services with their normal network credentials. 我们与O365联合,因此用户可以使用其正常的网络凭据访问服务。

The app allows users to connect using username / password or integrated windows authentication when they're connected to the local LAN. 该应用程序允许用户在连接到本地LAN时使用用户名/密码或集成的Windows身份验证进行连接。 The username / password combination part works fine, however when I pass a web request to the ADFS server using default credentials, I get a response from ADFS in the form of a web page which says the web browser doesn't support JavaScript: 用户名/密码组合部分可以正常工作,但是当我使用默认凭据将Web请求传递到ADFS服务器时,我以网页形式收到来自ADFS的响应,其中说Web浏览器不支持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>

I'm not sure why I'm getting this instead of being automatically authenticated. 我不确定为什么要得到这个而不是被自动认证。 I've included the code for the method below: 我已包含以下方法的代码:

    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;
    }

Has anyone had a similar experience? 有没有人有过类似的经历? If so, how did you work around it? 如果是这样,您是如何解决的? I don't think I can spoof being JavaScript compatible, but it shouldn't matter. 我认为我不能假冒与JavaScript兼容,但这没关系。

I was able to get a token from ADFS using integrated authentication using the code below: 使用以下代码,我可以使用集成身份验证从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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM