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

Nic*_*oul 13 c# desktop-application siteminder single-sign-on

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

一些客户要求我们支持受CA SSO(Siteminder的新名称)保护的服务器.

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

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

Moh*_*ava 6

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

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

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

打开连接(在这种情况下为HTTP请求)到受保护资源的URI.由于请求尚未经过身份验证,因此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
Run Code Online (Sandbox Code Playgroud)

下一步是创建一个HTTPS请求,将所有表单数据(包括用户ID和密码)POST回服务器.身份验证代理的目的是通过验证用户标识和密码来验证用户的身份.因此,他们的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
Run Code Online (Sandbox Code Playgroud)