none
Method-Level Authentication RRS feed

  • Question

  • Friends,

    I have created a kickass service oriented Membership System using WCF.  First off, WCF is really the greatest thing since Solitaire.  That says alot.

    So, a quick overview and then my question.

    Basically, I am using multiple endpoints to satisfy my clients for authentication.  One endpoint uses the UserName authentication and another uses Windows authentication.  All methods within the WCF Service sit behind these endpoints.  I have created a custom UserNameValidator to handle non-Windows authentication requests.  That works great.  I have also created a custom AuthorizationPolicy and AuthorizationManager to handle some other various needs for the application.

    Now, I have an OperationContract/method called 'Authenticate' that needs to be called anonymously (obviously, since the user is not yet authenticated).  The method authenticates them to our database using their username/password or their Windows SID (depending on which endpoint they came through on) to determine their roles, etc.  With the Windows Authentication, there's no problem since their token is passed along with their request and they are already theoretically authenticated.  I just grab their roles based upon their SID.

    The problem comes when the request comes in through the UserName endpoint.  First, my custom  UserName validator is hit which will throw a security exception because there is no username/password yet.  Then, my AuthorizationManager is hit and then my AuthorizationPolicy.  So, what is the best way for me to handle anonymous requests to my 'Authenticate' OperationContract while not allowing any other methods to be executed until they are authenticated?

    Thanks!

    Shaun McDonnell

    Tuesday, October 31, 2006 5:58 PM

Answers

  • The simplest way which occurs to me is to add a third endpoint with anonymous authentication and host the Authenticate() method on that endpoint.  How exactly you do this depends on the specific binding and security mode you're using, but basically you want to set the client credential type to none or anonymous.

    I'm curious, though.  It sounds like ultimately all clients end up authenticating against the DB based on their primary SID, so why not leverage WCF's default behavior of Windows mapping username/passwords and require all clients using the username/password endpoint to be able to present a valid username/password pair at all times?

    Tuesday, October 31, 2006 7:02 PM

All replies

  • The simplest way which occurs to me is to add a third endpoint with anonymous authentication and host the Authenticate() method on that endpoint.  How exactly you do this depends on the specific binding and security mode you're using, but basically you want to set the client credential type to none or anonymous.

    I'm curious, though.  It sounds like ultimately all clients end up authenticating against the DB based on their primary SID, so why not leverage WCF's default behavior of Windows mapping username/passwords and require all clients using the username/password endpoint to be able to present a valid username/password pair at all times?

    Tuesday, October 31, 2006 7:02 PM
  • Good point.

    My clients include users internal to the company and users external to the company as well that use the same application.  The default behavior of mapping Windows usernames/passwords only works with one set of clients and I need it to work for both.  Thus, if a user enters an application and has a Windows Token that was passed through IIS, I send them to the endpoint that uses Windows Authentication.  If the user comes into IIS anonymously, I give them a page that prompts them for a username and password.  So, not all clients have a SID - just the internal ones who are authenticated on the domain.  I can check the incoming identity of the user and see if it is anonymous and then direct the requests to their respective endpoints.  Does that make sense?  It gets even weirder.  Alot of ours apps are .NET 1.1, so I am using WSE 2.0 to calls the WCF Service through a basicHttpBinding (since netTcp is not supported through .NET 1.1 calls to the proxy) and for our 2.0 apps, the calls are made directly through the netTcpBinding.  netTcpBinding is a ton faster.

    So, all in all, we have over 5 endpoints for one service.  But, to me, that's the beauty of it all because it all consolidated into 1 service contract.  Makes integrated a ton easier for this large pharma I work for.

    Thanks for the input.

    Shaun McDonnell

    Tuesday, October 31, 2006 7:11 PM