PortSight Secure Access Documentation

Securing Your Web Services Using Secure Access and Microsoft WSE


This chapter will guide you through the securing your Web Service using PortSight Secure Access and WS-Security. Security credentials transmitted with the SOAP message are in the form of a user name and/or password - for more information about UsernameToken please refer to the Microsoft WSE 1.0 Documentation at http://msdn.microsoft..com.


 

 

    Sample Source Code

The source code for this sample is placed in the Examples\SampleSecuredWebService_Client and Examples\SampleSecuredWebService_WebService folders in the PortSight Secure Access installation folder.



Sample of the Web Service and client secured using Secure Access and Microsoft WSE 1.0:

  • SampleWSService
  • SampleWSClient

Creating the Service

  1. Launch Visual Studio.NET and create a new ASP.NET Web Service project.

  2. Add reference to the following assemblies:

?SPAN style="FONT: 7pt 'Times New Roman'">        Microsoft.Web.Services.dll (Microsoft WSE 1.0 SP1)

?SPAN style="FONT: 7pt 'Times New Roman'">        ARCatalogs.dll (PortSight SecureAccess library)

?SPAN style="FONT: 7pt 'Times New Roman'">        ARObjects.dll (PortSight SecureAccess library)


  1. Create PasswordProvider class by implementing Microsoft.Web.Services.Security.IPasswordProvider interface. The class implements only one method GetPassword() that returns a plain text password for the user name passed in. This is done by reading user details from the Secure Access catalog. The return value of GetPassword must match the password the client used to create a new instance of the UsernameToken class in the Web Service request.



    Public Class PasswordProvider

       Implements Microsoft.Web.Services.Security.IPasswordProvider



      

    Public Function GetPassword(ByVal token As UsernameToken) As String Implements IPasswordProvider.GetPassword

        Dim passwd As String = Nothing

        ' Get the ARConnection object with connection established to the specified catalog.

        Dim Connection As ARConnection = Math.GetConnection()

        ' Get the specified account

        Dim user As ARUser = Connection.GetUserByLogin(token.Username)

        ' ...and if found, return its password

        If Not user Is Nothing Then

          passwd = user.Password

        End If

        Connection.Close()

        Return passwd
    End Function
    End Class



     Note: You can find the GetConnection method in the sample code. It only returns ARConnection object with an opened connection.


  1. Register the PasswordProvider in the web.config:



     
    <microsoft.web.services>

        <security>

          <passwordProvider type="SampleWSService.PasswordProvider,SampleWSService" />

        </security>

      </microsoft.web.services>


 

  1. Configure IIS - do not forget to set appropriate permissions to this folder and allow Anonymous access in the IIS.





    Make sure that the virtual directory you created has anonymous access enabled. If you do not use anonymous access, then modifications must be made to the clients so that they include valid credentials in the Credentials property of all proxies.

  2. Now the user authentication is set up in your Web Service. The next steps describe how you can use Secure Access authorization features to your Web Service methods.

  3. Add the following code to your Web Service class:



       <WebMethod()> Public Function Add(ByVal A As Double, ByVal B As Double) As Double

            Dim requestContext As SoapContext = HttpSoapContext.RequestContext

            ' Verifies that a SOAP request was received. 

            If IsNothing(requestContext) Then

                Throw (New ApplicationException("Either a non-SOAP request was " & _

                   "received or the WSE is not properly installed for " & _

                   "the Web application hosting the XML Web service."))

            End If

            ' Get security token

            Dim userToken As UsernameToken = GetFirstUsernameToken(requestContext.Security)

            If IsNothing(userToken) Then

                Throw New ApplicationException("No security credentials provided.")

            End If

            Try

                ' Get the ARConnection object with connection established to the specified catalog.

                Dim Connection As ARConnection = GetConnection()

                ' Get the specified user

                Dim user As ARUser = Connection.GetUserByLogin(userToken.Username)

                ' Get the role required for the Add operation

                Dim role As ARObject = Connection.GetObjectByAlias("Calculator.Mathematician", ARObjectTypesEnum.ARRole)

                ' Verify that the user has role "SampleWSClient.Mathematician"

                ' necessary for performing mathematical operations

                If role Is Nothing OrElse Not user.IsMemberAll(role.ObjectID) Then

                    Throw New ApplicationException("You have not permission to call Math.Add() function.")

                End If

                ' Close the connection

                Connection.Close()

            Catch e As Exception

                ' Cannot get object from the catalog.

                Throw New ApplicationException("Unknown error.", e)

            End Try

            Return A + B

        End Function


 

What you did:


 

You created a function that adds two numbers. It IsMemberAll method to check that the user is member of the Calculator.Mathematician group. If not, it throws an application exception. Please notice the following methods:

  • GetFirstUsernameToken() - it retrieves username token from the SOAP request.
  • GetConnection() - it creates and returns database connection to the Secure Access catalog. It reads connection strings from the catalogs.xml file whose name is configured in the web.config file as well as Catalog ID.


Client

  1. Create a new console application project.

  2. Add web reference to your Web Service and add the generated proxy file to the project.

  3. Add reference to the following assemblies:

       ?SPAN style="FONT: 7pt 'Times New Roman'">        Microsoft.Web.Services.dll (Microsoft WSE 1.0 SP1)

  4. Before calling your Web Service Proxy methods configure the proxy object and add the UsernameToken object. The code for calling the Web Service Proxy method may look like this one:


     

    ' Prepare UsernameToken based on the provided credentials

           Dim userToken As UsernameToken = _

                New UsernameToken(login, passwd, PasswordOption.SendPlainText)

            ' Create instance of the web service proxy

            Dim serviceProxy As MathProxy = New MathProxy()

            'Sign message

            serviceProxy.RequestSoapContext.Security.Tokens.Add(userToken)

            serviceProxy.RequestSoapContext.Security.Elements.Add(New Signature(userToken))

            'Set timestamp

            serviceProxy.RequestSoapContext.Timestamp.Ttl = 60000

            ' Call the service and display the results

            Console.WriteLine("1 + 2 = " + serviceProxy.Add(1.0, 2.0).ToString())

     


     


 

Important Additional Notes

 

  1. The sample assumes that you store user passwords in plaintext format. If you use SHA1 you can use PasswordOption.SendHashed instead. Unfortunately MD5 hashes are not supported in Microsoft WSE.

  2. Although the service requires authentication and authorization now, it's not secure. It's strongly recommended that you use symmetric encryption or X.509 certificates to encrypt the communication. Please have a look at the ARWebService source code that is delivered with Secure Access. It's necessary to call the SetupSecurityContext() method at the beginning of each Web Service methods. You can copy this method as well as other related methods to your application. Then you can configure symmetric or assymetric encryption for your application as you do for ARWebServiceUsing Secure Access Web Service (ARWebService) - please read Using Secure Access Web Service (ARWebService) chapter for more details.