从C#桌面应用程序到受Siteminder保护的服务器的HTTP请求

我开发了一个C#桌面应用程序 ,它向客户的服务器( 通常是Documentum / SharePoint / Alfresco / NemakiWare / etc基于HTTPS的服务器 )发出HTTPS请求

一些客户要求我们支持受CA SSOSiteminder的新名称 )保护的服务器。

问题:如果允许我的应用程序使用受CA SSO保护的服务器发送HTTPS请求(并接收响应),我需要做些什么?

  • 我已经为我们的C#桌面应用程序开发了NTLM-SSO支持,它运行良好,但我不确定如何进行CA SSO。
  • 我在CA论坛上问了同样的问题 ,但是像大多数问题一样,它仍然没有答案。

要使用CA SSO进行身份validation,然后连接到所需的URL,我们需要访问配置为使用CA SSO身份validation的Web服务器上的受保护资源:

  1. 使用HTTP请求在服务器上请求资源。
  2. 该请求由Web服务器接收,并由CA SSO Web代理拦截。
  3. Web代理确定资源是否受保护,如果是,则收集用户的凭据并将其传递给策略服务器。
  4. 策略服务器根据策略存储中包含的规则和策略对用户进行身份validation,并validation经过身份validation的用户是否已获得所请求资源的授权。
  5. 在对用户进行身份validation和授权后,策略服务器将授予对受保护资源的访问权限。

这是通过以下步骤完成的:

打开连接(在这种情况下为HTTP请求)到受保护资源的URI。 由于请求尚未经过身份validation,因此CA SSO代理将向登录页面发出重定向。 在代码中, AllowAutoRedirect设置为false。 这很重要,因为在下面的步骤3中,后续的登录数据POST将需要重定向URL。 如果AllowAutoRedirect为True,则响应将不包含Location头,并且后续POST将对原始URL进行,然后将再次重定向到登录页面。 但是,在客户端和服务器之间发生POST,在重定向期间,步骤3的请求的有效负载中携带的任何POST数据都将丢失。

 Dim request As HttpWebRequest Dim response As HttpWebResponse Dim url As String = PROTECTED_URL request = WebRequest.Create(url) request.AllowAutoRedirect = False response = request.GetResponse ' make sure we have a valid response If response.StatusCode <> HttpStatusCode.Found Then Throw New InvalidProgramException End If ' get the login page url = response.Headers("Location") request = WebRequest.Create(url) request.AllowAutoRedirect = False response = request.GetResponse 

下一步是创建一个HTTPS请求,将所有表单数据(包括用户ID和密码)POST回服务器。 身份validation代理的目的是通过validation用户标识和密码来validation用户的身份。 因此,他们的URL自然使用SSL(安全套接字层)并为我们加密,因此我们不需要在我们的程序中进一步加密。 但是,POST数据的格式化很有意思,因为有两种选择。 示例程序使用更简单的方法将内容类型设置为application / x-www-form-urlencoded。 POST数据的格式类似于查询字符串,并作为下一个请求的一部分发送。

 Dim postData As String postData = "" For Each inputName As String In tags.Keys If inputName.Substring(0, 2).ToLower = "sm" Then postData &= inputName & "=" & _ HttpUtility.UrlEncode(tags(inputName)) & "&" End If Next postData += "postpreservationdata=&" postData += "USER=" + HttpUtility.UrlEncode(USERNAME) & "&" postData += "PASSWORD=" + HttpUtility.UrlEncode(PASSWORD) request = WebRequest.Create(url) cookies = New CookieContainer request.CookieContainer = cookies request.ContentType = FORM_CONTENT_TYPE request.ContentLength = postData.Length request.Method = POST_METHOD request.AllowAutoRedirect = False ' Important Dim sw As StreamWriter = New StreamWriter(request.GetRequestStream()) sw.Write(postData) sw.Flush() sw.Close() response = request.GetResponse 

与Mohit的答案相同,但可以使用更简单的代码完成:

  //Make initial request for SM to give you some cookies and the authentication URI RestClient client = new RestClient("http://theResourceDomain/myApp"); client.CookieContainer = new CookieContainer(); IRestResponse response = client.Get(new RestRequest("someProduct/orders")); //Now add credentials. client.Authenticator = new HttpBasicAuthenticator("username", "password"); //Get resource from the SiteMinder URI which will redirect back to the API URI upon authentication. response = client.Get(new RestRequest(response.ResponseUri)); 
  • 虽然这使用了RestSharp,但它可以使用HttpClient甚至HttpWebRequest轻松复制。