Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Web Services / August 2006

Tip: Looking for answers? Try searching our database.

CustomUsernameTokenManager

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
FrikOlivier - 08 Jan 2005 17:09 GMT
After I've been unsuccesfull with my own code, I compiled the example file
from the WSE 2.0 SP2 and got the same result as mentioned in a post before
(and now solution was found, even I went through all the stuff that was
mentioned).

My CustomUsernameTokenManager class is not being called to do the server
service side verification.

On the client side the CustomUsernameTokenManager is being called with the
line:
token = new UsernameToken(username, "BadPassword", PasswordOption.SendHashed);

But in the server side it goes through without calling the constructors,
even without verifying the password!  With the above token created inside the
client, the Service is returning the request without a problem!

I’m suspecting that the following Service side code is the problem:

UsernameToken usernameToken =
AppBase.GetSigningToken(RequestSoapContext.Current);
if (usernameToken == null || usernameToken.PasswordOption ==
PasswordOption.SendPlainText)
{
  throw new SecurityFault(SecurityFault.FailedAuthenticationMessage,
SecurityFault.FailedAuthenticationCode);
}

And what I'm suspecting is that it is because their is no 'new' constructor
call?  The AppBase.GetSigningToken looks like this:

public static SecurityToken GetSigningToken(SoapContext context)
       {
           foreach ( ISecurityElement element in context.Security.Elements )
           {
               if ( element is MessageSignature )
               {
                   // The given context contains a Signature element.
                   MessageSignature sig = element as MessageSignature;

                   if (CheckSignature(context, sig))
                   {
                       // The SOAP Body is signed.
                       return sig.SigningToken;
                   }
               }
           }

           return null;
       }

My web.config:
 <microsoft.web.services2>
   <diagnostics>
        <detailedErrors enabled="false" />
   </diagnostics>
   <security>
     <securityTokenManager
type="UsernameSignCodeService.CustomUsernameTokenManager,
UsernameSignCodeService"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" qname="wsse:UsernameToken" />
   </security>
 </microsoft.web.services2>

What should I do to 'link' the service side as well?
Dilip Krishnan - 08 Jan 2005 17:32 GMT
Hello FrikOlivier,

Could you post the code for the Authenticate method in the CustomUsernameTokenManager
please? It should be authenticating the token there
HTH
Regards,
Dilip Krishnan
MCAD, MCSD.net
dkrishnan at geniant dot com
http://www.geniant.com

> After I've been unsuccesfull with my own code, I compiled the example
> file from the WSE 2.0 SP2 and got the same result as mentioned in a
[quoted text clipped - 61 lines]
> </microsoft.web.services2>
> What should I do to 'link' the service side as well?
FrikOlivier - 08 Jan 2005 22:21 GMT
Here is the complete file.  It is the UsernameSigningCode example.

What I did in the meantime is to SHA1CryptoServiceProvider the password in
the client, Convert.ToBase64String, and then send it to the Service using
PasswordOption.SendPlainText in the UsernameToken.  I then
Convert.FromBase64String the plain (encrypted) text in the Service and
compare it with the password which is stored as SHA1CryptoServiceProvider in
the Database.

This seems to work and even I use PlainText option, I don't send the actual
password.  ALthough I still could not get it to use my
CustomeUsernameTokenManager....

/*================================================================================
 File:      UsernameTokenManager.cs

 Summary:   This is a sample which allows the user to send a message to a Web
            service that has been signed with a username and password
----------------------------------------------------------------------------------
This file is part of the Web Services Enhancements 2.0 for Microsoft .NET
Samples.

Copyright (C) Microsoft Corporation.  All rights reserved.

This source code is intended only as a supplement to Microsoft Development
Tools
and/or on-line documentation.  See these other materials for detailed
information
regarding Microsoft code samples.

This sample is designed to demonstrate WSE features and is not intended
for production use. Code and policy for a production application must be
developed to meet the specific data and security requirements of the
application.

THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES
OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE
================================================================================*/

using System;
using System.Xml;
using System.Security.Permissions;

using Microsoft.Web.Services2.Security;
using Microsoft.Web.Services2.Security.Tokens;

namespace UsernameSignCodeService
{
   /// <summary>
   /// By implementing UsernameTokenManager we can verify the signature
   /// on messages received.
   /// </summary>
   /// <remarks>
   /// This class includes this demand to ensure that any untrusted
   /// assemblies cannot invoke this code. This helps mitigate
   /// brute-force discovery attacks.
   /// </remarks>
   [SecurityPermissionAttribute(SecurityAction.Demand,
Flags=SecurityPermissionFlag.UnmanagedCode)]
   public class CustomUsernameTokenManager : UsernameTokenManager
   {
       /// <summary>
       /// Constructs an instance of this security token manager.
       /// </summary>
       public CustomUsernameTokenManager()
       {
       }

       /// <summary>
       /// Constructs an instance of this security token manager.
       /// </summary>
       /// <param name="nodes">An XmlNodeList containing XML elements from
a configuration file.</param>
       public CustomUsernameTokenManager(XmlNodeList nodes)
           : base(nodes)
       {
       }

       /// <summary>
       /// Returns the password or password equivalent for the username
provided.
       /// </summary>
       /// <param name="token">The username token</param>
       /// <returns>The password (or password equivalent) for the
username</returns>
       protected override string AuthenticateToken( UsernameToken token )
       {
           // This is a very simple manager.
           // In most production systems the following code
           // typically consults an external database of
(username,password) pairs where
           // the password is often not the real password but a password
equivalent
           // (for example, the hash of the password). Provided that both
client and
           // server can generate the same value for a particular username,
there is
           // no requirement that the password be the actual password for
the user.
           // For this sample the password is simply the reverse of the
username.
           byte[] password = System.Text.Encoding.UTF8.GetBytes(
token.Username );

           Array.Reverse( password );

           return Convert.ToBase64String( password );
       }
   }
}
William Stacey [MVP] - 10 Jan 2005 04:04 GMT
> This seems to work and even I use PlainText option, I don't send the actual
> password.  ALthough I still could not get it to use my

Is the protocol encrypting the PasswordOption.SendPlainText pw (i.e. your
base64 string)?

Signature

William Stacey, MVP
http://mvp.support.microsoft.com

dafan - 31 Aug 2006 04:01 GMT
Here's one of the solution:

You must put the CustomTokenManager's dll file into
GAC (Global Assembly Cache) which located into "C:\WINDOWS\assembly"

Step 1: Create a project named "CustomClass" using VS. studio 2005
Step 2: Create the CustomToken manager code as below:

Imports System
Imports System.Xml
Imports System.Security.Permissions
Imports System.Web.Security
Imports System.Security.Principal

Imports Microsoft.Web.Services3.Security
Imports Microsoft.Web.Services3.Security.Tokens

Namespace Service

   <SecurityPermissionAttribute(SecurityAction.Demand, Flags:
=SecurityPermissionFlag.UnmanagedCode)> _
       Public Class CustomUsernameTokenManager
       Inherits UsernameTokenManager

       Public Sub New()
       End Sub

       Public Sub New(ByRef nodes As XmlNodeList)
           MyBase.New(nodes)
       End Sub

       Protected Overrides Function AuthenticateToken(ByVal token As
UsernameToken) As String
           Dim blnValidCredential As Boolean = False
           Dim objIdentity As GenericIdentity
           Dim objPrincipal As GenericPrincipal
           Dim strRole As String()

           If token.Username = "JohnDoe" And token.Password = "johnd123"
Then
           Else
               Throw New ApplicationException("Can not authenticate this
user")
           End If

           strRole = New String() {"GuestUser"}
           objIdentity = New GenericIdentity(token.Username)
           objPrincipal = New GenericPrincipal(objIdentity, strRole)
           token.Principal = objPrincipal

           Return token.Password

       End Function

   End Class

End Namespace

Step 3: Before compile the project to produce the "CustomClass.dll",
you must follow the instruction from this link
(How to install an assembly in the Global Assembly Cache):

http://support.microsoft.com/default.aspx?scid=kb;en-us;315682

Step 4: Record the "AssemblyName", "Version", "Culture", "Public Key Token"
in the "C:\WINDOWS\assembly"

Step 5: Go to "Web.config" in the Server Side Web Services project
and add what you recorded in the ""C:\WINDOWS\assembly" like
the following sample:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
......

<system.web>

  <compilation debug="true" strict="false" explicit="true">
     <assemblies>
    <add assembly="CustomClass, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=10697CC0ABF25E2F"/>
     </assemblies>
   </compilation>

</system.web>

<microsoft.web.services3>
  <policy fileName="wse3policyCache.config"/>
    <security>
        <securityTokenManager>
         <add localName="UsernameToken" type="CustomClass.Service.
CustomUsernameTokenManager, CustomClass, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=10697CC0ABF25E2F" namespace="
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/

        </securityTokenManager>
    </security>
 </microsoft.web.services3>
</configuration>

   
That's all folk.

To.Ph.

------------------------------------------------------------------------------
-------------------------------
------------------------------------------------------------------------------
------------------------------

>After I've been unsuccesfull with my own code, I compiled the example file
>from the WSE 2.0 SP2 and got the same result as mentioned in a post before
[quoted text clipped - 60 lines]
>
>What should I do to 'link' the service side as well?

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.