Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

UserNamePasswordValidator method never called

541 views
Skip to first unread message

Kai Fransson

unread,
Jan 28, 2009, 8:44:01 AM1/28/09
to
My problem is that my Validator method, which overrides
UserNamePasswordValidator.Validate is never being called.

I use VS 2008 with built-in Cassini webserver. My WCF service is supposed to
be hosted in IIS 6 on Win Srv 2003.

Users will be authenticated against the applications SQL Server database.

My class looks like this:

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

Imports Scania.CLAW.ServerCache.Cache
Imports System.Collections.Generic
Imports System.IdentityModel.Selectors
Imports System.IdentityModel.Tokens
Imports System.ServiceModel

Public Class Security
Inherits UserNamePasswordValidator

Public Overrides Sub Validate(ByVal username As String, ByVal password
As String)

Try

Throw New FaultException("Hello")


Catch ex As Exception
Throw New SecurityTokenException("Unknown error validating user")
End Try

End Sub

End Class

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

My web.config, in my WCF service looks liks this:
-------------------------------------------

<?xml version="1.0"?>

<configuration>
<system.serviceModel>

<behaviors>
<serviceBehaviors>
<behavior name="CustomValidator">
<serviceDebug includeExceptionDetailInFaults ="true"/>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />

<serviceCredentials>
<userNameAuthentication
customUserNamePasswordValidatorType="Scania.CLAW.ExternalServices.Security,Scania.CLAW.ExternalServices"
userNamePasswordValidationMode="Custom" />
</serviceCredentials>


</behavior>
</serviceBehaviors>
</behaviors>

<bindings>
<wsHttpBinding>
<binding name="WsHttpBinding">

<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"
negotiateServiceCredential="false" algorithmSuite="Default"
establishSecurityContext="false" />
</security>

</binding>
</wsHttpBinding>
</bindings>



<services>
<service behaviorConfiguration="CustomValidator"
name="Scania.CLAW.CLAWservice.CLAWService">
<endpoint address="" binding="wsHttpBinding"
name="Scania.CLAW.CLAWservice"
contract="Scania.CLAW.CLAWservice.ICLAWService" />
</service>
</services>

</system.serviceModel>
<system.web>
<compilation debug="true"/></system.web></configuration>


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

I have two questions

1. First of all, naturally, why is my Validate method not being called? My
test client can connect and successfully call methods and gets a correct
response back, with or without supplying user credentials. The client
attaches it user credentials in the following function:

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

Private Function GetProxy() As ws1.CLAWServiceClient

Dim proxy As New ws1.CLAWServiceClient

System.Net.ServicePointManager.CertificatePolicy = New
AcceptAllCertificatePolicy()

proxy.ClientCredentials.UserName.UserName = "kai"
proxy.ClientCredentials.UserName.Password = "superduper"

Return proxy
End Function
---------------------------------------------

2. Second, if I use wsHttpBinding with Message security, what use do I have
of the SSL certificate, that is already installed on the IIS where my service
is to be hosted? Messages are encrypted anyway if I understand things
correctly. For performance reasons, perhaps I better not use SSL or some
other approach?

Allen Chen [MSFT]

unread,
Jan 29, 2009, 5:10:30 AM1/29/09
to
Hi,

My name is Allen Chen. It's my pleasure to work with you on this issue. I
spent some time trying to reproduce this issue but it worked fine on my
side. By looking at your code again I found that it's due to the
bindingConfiguration isn't specified for the endpoint. From your code we
can see the binding is defined like below:

<wsHttpBinding>
<binding name="WsHttpBinding">

<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"
negotiateServiceCredential="false" algorithmSuite="Default"
establishSecurityContext="false" />
</security>

</binding>
</wsHttpBinding>

However, the binding that the endpoint uses is the default wsHttpBinding.
To apply the above wsHttpBinding please add the bindingConfiguration in
this way:

<endpoint address="" binding="wsHttpBinding"
name="Scania.CLAW.CLAWservice"
contract="Scania.CLAW.CLAWservice.ICLAWService"

bindingConfiguration="WsHttpBinding" />

By adding this bindingConfiguration attribute we'll use the defined
WsHttpBinding. Please have a try and let me know if it works.
==================================================


2. Second, if I use wsHttpBinding with Message security, what use do I have
of the SSL certificate, that is already installed on the IIS where my
service
is to be hosted? Messages are encrypted anyway if I understand things
correctly. For performance reasons, perhaps I better not use SSL or some
other approach?

==================================================
The SSL can provide point-to-point security while Message security can
provide end-to-end security. Considering this SSL is seldom used along with
Message security. There's probably one reason that we may do so, that is to
maximize security. However, as you said, it's not recommended to do this
from the performance reason. If you mean the X.509 certificate, it can be
used as the credential for the client to authenticate the server. Like this:

http://msdn.microsoft.com/en-us/library/ms733098.aspx

Regards,
Allen Chen
Microsoft Online Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msd...@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Kai Fransson

unread,
Jan 29, 2009, 5:52:01 AM1/29/09
to
Thank you!

Adding the attribute, according to your suggestion, took me one step
further. I now get an error saying "The service certificate is not provided.
Specify a service certificate in ServiceCredentials."

As you can see from my original post, I have no such section in my
web.config. Can I somehow reference the already installed SSL certificate
(from Verisign) in this section? How would I do that?


The more I think about this, the more I would like for a much easier way to
accomplish my goal. I want the client to somehow attach username and password
credentials to his server requests, and for my custom validation routine in
the wcf service to authenticate. My original idea was to simply apply
Transport security using the installed SSL certificate on the server. This
would be easy and interoperable.

I started trying out Message security though, because I understand that
hosting my service in IIS (which is a demand) will pose problems with custom
Username authentication and transport security, since I would have to hack in
to the way IIS handles basic authentication. Do you have a good
recommendation for me here?

Allen Chen [MSFT]

unread,
Jan 29, 2009, 8:58:38 PM1/29/09
to
Hi,

Thanks for your update. This exception means we need to provide a service
certificate for the client to authenticate. To do this we need to provide a
service certificate in this way:

<serviceBehaviors>
<behavior name="WcfSecurity.Service1Behavior">
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" findValue="75 5c 8c
1b df 88 cd c8 01 eb 0f 16 a1 e2 b1 8a e4 6a a9 58"
x509FindType="FindByThumbprint"/>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WcfSecurity.MyValidator, WcfSecurity"/>
</serviceCredentials>

..
</behavior>
</serviceBehaviors>
</behaviors>
</serviceBehaviors>

The key is the serviceCertificate element. Here the certificate I used is
my test certificate that is self signed. You can find your certificate in
the Microsoft Management Console:
http://msdn.microsoft.com/en-us/library/ms788967.aspx

After finding the certificate we can use its Thumbprint for WCF to find it.
That is the "75 5c ..." in the above configuration. You can get the
Thumbprint by double clicking the certificate in MMC and finding the
Thumbprint field in the Details tab. Don't forget to set
x509FindType="FindByThumbprint", which means we find the certificate by
Thumbprint. The storeLocation attribute specifies where the certificate is
stored. After that the exception should be eliminated.

Kai Fransson

unread,
Jan 30, 2009, 3:41:01 AM1/30/09
to
Hi, thank you for your reply. I am not quite happy yet though :-)

Having a server certificate pointed out in my web.config seems doable,
although I find it a little too complicated for my needs. I will try it out
if I have to.

However, isn't there a way to just apply Transport security and only let my
service worry about authenticating the users via my custom authentication
function, which is pointed out in my web.config?
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Scania.CLAW.ExternalServices.Security,Scania.CLAW.ExternalServices" />
</serviceCredentials>


This way, IIS will handle the transport security (with SSL), and my service
would only have to authenticate the username and password. Also, performance
would be better than "Message security".

Is this possible for a service that is hosted in IIS? What is your
recommendation here?

Allen Chen [MSFT]

unread,
Feb 1, 2009, 10:35:00 PM2/1/09
to
Hi,

Thanks for the question. First, as to the exception ""The service

certificate is not provided. Specify a service certificate in

ServiceCredentials." I guess you're using the Message security. In this
case we need to provide a service certificate to protect the message in
application level.

When hosting WCF in IIS, Message security along with HTTPS is seldom used.
It's just as what I said in my first reply, is probably only used to
maximize the security.

When using TransportWithMessageCredential it provides point-to-point
security and the authentication extensibility of Message security (please
note TransportWithMessageCredential doesn't mean using both Transport and
Message security, refer to
http://msdn.microsoft.com/en-us/library/ms735093.aspx).


In a word, I think you have two options:

" Best performance. TransportWithMessageCredential security + your custom
UserNamePasswordValidator

" Best security. Message security + your custom UserNamePasswordValidator +
certificate specified in Web.config.

Of course, if you don't want to use UserNamePasswordValidator or HTTPS
there're other options to do the custom authentication and secure the
message. It's probably out of the boundary of this discussion so I don't
want to say much on this.

Some related articles about security FYI.

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2006/06/0
8/5848.aspx
http://blogs.msdn.com/suwatch/archive/2007/04/06/x509-and-wcxf-security.aspx

If you have additional questions please feel free to ask.

Kai Fransson

unread,
Feb 3, 2009, 4:09:00 AM2/3/09
to
Hi again and thank you for your reply!

I will go for TransportWithMessageCredential then. If I understand things
correctly this will make use of Transport security and the SSL certificate I
have installed in IIS on the production server, while at the same time
allowing me to use custom username authentication in my service.

This is apprantly not so easy to debug in Visual Studio. Is it even possible
to debug this in Visual Studio using only the built-in Cassini webserver?
Could you please advice the best way to develop/debug this setup? (I could
install IIS6 on my development machine (Windows Vista) I guess.)

Regards
Kai

Allen Chen [MSFT]

unread,
Feb 3, 2009, 4:42:52 AM2/3/09
to
Hi Kai,

Thanks for the update. To debug the project we need to deploy it to IIS
first. There's no way to use the WebDev.WebServer in this case because we
need IIS to help to secure the message.

After deploying the project to IIS you can use Visual Studio to attach the
process w3wp.exe (the IIS process) by selecting Debug->Attach to
Process..->choose the w3wp and click "Attach"

You can set the breakpoint in the source code of your project and run the
client application to call web service. It will enter the breakpoint as
normal.

Kai Fransson

unread,
Feb 3, 2009, 4:52:02 AM2/3/09
to
Thank you!

I have now installed IIS 7 on my development machine. I was hoping there
would be some way to automatically let Visual Studio use IIS 7, instead of
WebDev.WebServer, but perhaps I, as you say, have to manually attach to the
process each time I debug my application?

I will surf the web for some guidelines on how to best deploy my wcf service
in iis 7, but perhaps you have a good link that you could supply?

Thank you for all your help.

/Kai

Allen Chen [MSFT]

unread,
Feb 3, 2009, 10:39:18 PM2/3/09
to
Hi Kai,

Quote from Kai==================================================


I have now installed IIS 7 on my development machine. I was hoping there
would be some way to automatically let Visual Studio use IIS 7, instead of
WebDev.WebServer, but perhaps I, as you say, have to manually attach to the
process each time I debug my application?

==================================================

Glad to know you've upgraded to IIS 7. As to debugging I'm afraid manually
attaching to the w3wp process is the only way to debug your application. If
you're using HTTP, of course, you can use the WebDev.WebServer to debug by
right click the .svc file, select "View in Browser", get the WSDL and use
it to add web reference for your client application. Then you can debug as
normal.

Quote from Kai==================================================


I will surf the web for some guidelines on how to best deploy my wcf
service
in iis 7, but perhaps you have a good link that you could supply?

==================================================

You can refer to:
http://msdn.microsoft.com/en-us/library/aa751802.aspx
http://msdn.microsoft.com/en-us/library/ms734710.aspx
http://msdn.microsoft.com/en-us/library/ms733766.aspx
http://yourbit.com/2008/03/09/hosting-a-windows-communication-foundation-ser
vice-in-iis7-on-windows-vista/

Allen Chen [MSFT]

unread,
Feb 6, 2009, 2:19:04 AM2/6/09
to
Hi Kai,

Do you have additional questions? If you have please don't hesitate to ask.
I'll do my best to follow up.

G P

unread,
May 8, 2009, 4:52:14 PM5/8/09
to
Allen... I need some serious help. I've wasted countless hours on
research and am now stressed. Any help would be appreciated.

Like mentioned at the begginning of this post, I can't get my validate
function to call. I think it has something to do with the fact that I
have the override embedded in my .vb service class as part of the other
web service functions. The functions call no problem, but the validate
is always ignored. Once this web service goes live, my users will be
connecting via a SSL (https)channel. I wish to use basicHttpBinding
with a security mode of TransportWithMessageCredential, but before I use
that type of security, I would like to test with a security mode of
NONE. What am I doing wrong? - Thanks.

**************Here's my config:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="defaultbehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>


<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"
/>
<serviceCredentials>
<userNameAuthentication

customUserNamePasswordValidatorType="MyShipmentUpdateService.ShipmentUpd
ateService,ShipmentUpdateService"


userNamePasswordValidationMode="Custom"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>

<basicHttpBinding>
<binding name="Binding1" >
<security mode="None">
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MyShipmentUpdateService.ShipmentUpdateService"
behaviorConfiguration="defaultbehavior">
<endpoint address="" binding="basicHttpBinding"
contract="MyShipmentUpdateService.IShipmentUpdate"
bindingConfiguration="Binding1"/>
</service>
</services>
</system.serviceModel>
</configuration>

******* Here's the beggining part of my class
Imports System.ServiceModel
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.Net
Imports System.Web.HttpUtility
Imports System.Runtime.Serialization
Imports System.IdentityModel.Selectors
Imports System.IdentityModel.Tokens

Public Class ShipmentUpdateService
Inherits UserNamePasswordValidator
Implements IShipmentUpdate

Public Overrides Sub Validate(ByVal userName As String, ByVal
password As String)
Throw New ArgumentNullException("userName")
End Sub


*** Sent via Developersdex http://www.developersdex.com ***

0 new messages