'--------------------------------------------------------------------------
'
' Module: WebServiceInvocation.vb
'
' Purpose: This module contains code to assist in calling web services
' that use Windows authentication, the NCES SDK, etc.
'
' Notes:
'
' Modification History:
'
' 07/14/2005, Jonathan Cochran
' 1) Original coding.
'
' 04/27/2006, Jonathan Cochran
' 1) Renamed the main procedure to ConfigureProxy.
' 2) Made all parameters to ConfigureProxy mandatory. If they are all
' always passed in, it will be easier to switch from one implementation
' to another.
'
' 07/10/2006, Jonathan Cochran
' 1) Added a configuration option to specify the security protocol a
' web service is called over (TLS, SSL, or none).
'
'
' Copyright 2005-2006
' Alion Science and Technology
'
' US Govt retains rights in accordance
' with DoD FAR Supp 252.227-7013.
'
'--------------------------------------------------------------------------
Imports mil.disa.nces.toolkit.domain.security.saml.token
Imports mil.disa.nces.toolkit.utils.securityengine
Imports Microsoft.Web.Services2.Security.Tokens
Imports System.Web.SessionState
Imports System.Net
Imports System.Security.Cryptography.X509Certificates
Module WebServiceInvocation
'--------------------------------------------------------------------------
'
' Procedure: ConfigureProxy
'
' Purpose: This procedure will configure a web service proxy so the web
' service can be accessed when it is protected.
'
' Parameters: vstrServiceQName - The QName of the web service to call.
' This is used to uniquely identify a
' web service.
' robjWebServiceProxy - The web service proxy to configure.
' vobjClientCertificate - The client certificate object.
' robjSession - The user's session object.
'
' Returns: Nothing
'
' Notes:
'
' 1) This procedure should be called immediately before a web service
' is called. This is because:
' a) The NCES SDK global object (ToolkitSecurityContext) has a single
' configuration for all web services, rather than individual
' configurations for each web service. Since different web
' services may have different needs, this procedure will need to
' be called before each web service call to make sure the
' ToolkitSecurityContext object is configured properly for the
' service being called.
' b) NCES Discovery may need to be called to find the current
' location of the web service.
' c) Currently the NCES SDK global object (ToolkitSecurityContext) is
' shared among all users to the web application. Therefore, the
' end-user assertion needs to be set in the global object as close
' as possible to the web service call to try to avoid using
' another user's end-user assertion.
' 2) A web service QName is:
' web service namespace + "#" + web service name
'
'--------------------------------------------------------------------------
Sub ConfigureProxy( _
ByVal vstrServiceQName As String, _
ByRef robjWebServiceProxy As System.Web.Services.Protocols.SoapHttpClientProtocol, _
ByVal vobjClientCertificate As System.Web.HttpClientCertificate, _
ByRef robjSession As HttpSessionState)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Read settings for this service from Web.Config.
'
' Determine the security protocol for this service.
' Setting Name: "WebService.SecurityProtocol@ServiceQName"
' Supported Values: "SSL3", "TLS", "None"
' Default Value: "None"
Dim strSecurityProtocol As String
strSecurityProtocol = System.Configuration.ConfigurationSettings.AppSettings("WebService.SecurityProtocol@" + vstrServiceQName)
' Determine the authentication method for this service.
' Setting Name: "WebService.Authentication.Method@ServiceQName"
' Supported Values: "Windows", "None"
' Default Value: "None"
Dim strAuthentication_Method As String
strAuthentication_Method = System.Configuration.ConfigurationSettings.AppSettings("WebService.Authentication.Method@" + vstrServiceQName)
' Determine if this service is protected by the NCES SDK.
' Setting Name: "WebService.NCES.Protected@ServiceQName"
' Supported Values: "True", "False"
' Default Value: "False"
Dim strNCES_Protected As String
Dim blnNCES_Protected As Boolean
strNCES_Protected = System.Configuration.ConfigurationSettings.AppSettings("WebService.NCES.Protected@" + vstrServiceQName)
If strNCES_Protected = "True" Then
blnNCES_Protected = True
Else
blnNCES_Protected = False
End If
' Determine if we are using Discovery to find this service.
' Setting Name: "WebService.NCES.UseDiscovery@ServiceQName"
' Supported Values: "True", "False"
' Default Value: "False"
Dim strNCES_UseDiscovery As String
Dim blnNCES_UseDiscovery As Boolean
strNCES_UseDiscovery = System.Configuration.ConfigurationSettings.AppSettings("WebService.NCES.UseDiscovery@" + vstrServiceQName)
If strNCES_UseDiscovery = "True" Then
blnNCES_UseDiscovery = True
Else
blnNCES_UseDiscovery = False
End If
' Determine if we are using address caching for this service (only applicable
' if we are using the NCES SDK and Service Discovery).
' Setting Name: "WebService.NCES.AddressCaching@ServiceQName"
' Supported Values: "True", "False"
' Default Value: "False"
Dim strNCES_AddressCaching As String
Dim blnNCES_AddressCaching As Boolean
strNCES_AddressCaching = System.Configuration.ConfigurationSettings.AppSettings("WebService.NCES.AddressCaching@" + vstrServiceQName)
If strNCES_AddressCaching = "True" Then
blnNCES_AddressCaching = True
Else
blnNCES_AddressCaching = False
End If
' We also can't do address caching if the Session object wasn't passed in.
If robjSession Is Nothing Then
blnNCES_AddressCaching = False
End If
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Configure the application to use the specified security protocol.
Select Case strSecurityProtocol
Case "SSL3"
Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Ssl3
Case "TLS"
Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls
Case "None"
' Nothing extra to do.
Case Else
' Nothing extra to do.
End Select
' Configure security settings for the proxy so this service can be accessed.
Select Case strAuthentication_Method
Case "Windows"
robjWebServiceProxy.Credentials = System.Net.CredentialCache.DefaultCredentials
Case "ClientCertificate"
' NOTE: This option is not supported yet.
'Dim objCertificate As System.Security.Cryptography.X509Certificates.X509Certificate
'objCertificate = System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile("")
'robjWebServiceProxy.ClientCertificates.Add(objCertificate)
Case "None"
' Nothing extra to do.
Case Else
' Nothing extra to do.
End Select
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Perform Trust Override for webservices invocation. (NOTE.
' this will ignore invalid server certificates when calling the
' webservices)
'
System.Net.ServicePointManager.CertificatePolicy = New MyPolicy
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Perform processing necessary for the NCES SDK.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Use Service Discovery to find the address of this service.
'
' The address to use for this service.
Dim strServiceAddress As String
strServiceAddress = ""
' The Session variable used to store the address for this
' service (if address caching is used).
Dim strServiceURLSessionVar As String
strServiceURLSessionVar = "WebService.CachedURL." + vstrServiceQName
' Find the cached location of the service.
If blnNCES_AddressCaching Then
If CStr(robjSession(strServiceURLSessionVar)) <> "" Then
strServiceAddress = CStr(robjSession(strServiceURLSessionVar))
End If
End If
' Use Service Discovery to find the address of this service.
' This is done either if we are not using address caching, or if we are
' using address caching but we haven't obtained the address for this
' service yet. However, it is only done if the setting in Web.Config
' said to use Discovery.
'VS2008x If blnNCES_UseDiscovery And strServiceAddress = "" Then
'VS2008x Dim objInquiryService As New InquiryService_Proxy
'VS2008x Dim objRequest As New mil.disa.nces.toolkit.domain.discovery.request.GetServiceByQName
'VS2008x Dim objResponse As mil.disa.nces.toolkit.domain.discovery.Service
' Specify the QName of this service for the Discovery request.
' The QName is "Namespace#ServiceName".
'VS2008x objRequest.serviceQName = vstrServiceQName ' ex: "urn:nces:security:0.3:service:CertificateValidationService#CertificateValidationService"
' Get the address of this service.
'VS2008x objResponse = objInquiryService.getServiceByQName(objRequest)
' If a valid response came back, extract the address for the first
' returned binding.
'VS2008x If Not IsNothing(objResponse) Then
'VS2008x strServiceAddress = objResponse.bindings(0).accessPoint
' If we are doing address caching, save the address for later use.
'VS2008x If blnNCES_AddressCaching Then
'VS2008x robjSession(strServiceURLSessionVar) = strServiceAddress
'VS2008x End If
'VS2008x End If
'VS2008x End If
' Set the address for this service if found. If not found, the service
' will retain its initially set address.
If strServiceAddress <> "" Then
robjWebServiceProxy.Url = strServiceAddress
End If
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'VS2008x If blnNCES_Protected Then
' Set the security token for invocation (this is the end-user token to
' specify who is calling the service, not who digitally signs the
' request).
' This only needs to be done if we have an end-user certificate for
' which to create a token.
'VS2008x If Not vobjClientCertificate Is Nothing Then
'VS2008x If vobjClientCertificate.IsPresent Then
'VS2008 Dim samlToken As SecurityToken
'VS2008x ToolkitSecurityContext.ResetCurrentSecurityContext()
'VS2008 samlToken = SAMLAssertionToken.CreateX509AuthenticationAssetion(vobjClientCertificate.Subject)
'VS2008 ToolkitSecurityContext.CurrentSecurityContext.SetSecurityTokenForInvocation(samlToken)
'VS2008x End If
'VS2008x End If
'VS2008x Else
' TODO: If the NCES SDK is enabled for this project, but we need to call a
' service that is not protected by the NCES SDK, settings will have to
' be made to ToolkitSecurityContext to prevent digitally signing the
' SOAP message, etc. To do this, we would need a setting saying whether
' the NCES SDK filters are in place (unless we can obtain that information
' from already existing sources). I think following are the options that
' would need to be set:
' If <USING_NCES> Then
' ToolkitSecurityContext.CurrentSecurityContext.RequireSignatureForInvocation = False
' ToolkitSecurityContext.CurrentSecurityContext.CollectInputSecurityTokensDisabled = True
' ToolkitSecurityContext.CurrentSecurityContext.CallCertificateValidationServiceDisabled = True
' End If
'VS2008x End If
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''