Question

All of this is pertaining to WebHttp binding, hosted in a custom Service Host (IIS is not an option at this time).

I've implemented a custom UserNamePasswordValidator, and a custom IAuthorizationPolicy. When I configure the endpoint's binding to use Basic authentication, everything works just as I'd like (custom principal, custom roles, etc..).

I'd like to add the ability for anonymous HTTP access as well, and have my custom implementations put the Anonymous user in some default roles, etc.. (if no Authenticate header is sent).

What happens now is that anonymous users are given a 401 before any of my custom code is hit. If I turn off the HTTP Basic authentication requirement, then the Authenticate header is ignored altogether.

How do I configure, or inject an Authenticate header, to do this both ways (without creating 2 separate endpoints)?

Was it helpful?

Solution

First of all, the service responds correctly to the anonymous call, according to the specification.

Second, this is impossible. When you are self-hosting your service and you have some http binding, WCF will use a System.Net.HttpListener instance to be able to respond to http requests (created in System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen). This listener has a method called HandleAuthentication that is called way before any of your custom code is called. It is responsible for sending back the 401 response with the challenge (WWW-Authenticate). There is nothing you can do about this. If there is, I'd like to know.

So you're left with the following options:

  • two endpoints
  • configure your clients to know the default credentials
  • change your clients so they can respond to the challenge

OTHER TIPS

I've done research on this in the past and found that it is not possible through configuration unless you create 2 separate endpoints (which is not what you want). It just simply isn't supported out of the box by WCF.

However, WCF is extremely customizable and you could likely do this by writing a custom channel/binding that will do what you want. I recommend you take a look at the REST Chess source code. It should get you started.

Your best bet is to implement a default roles via a roles provider and let anonymous users automatically join that role. Then either programmatically, or via policy injection (aspect oriented) policy, set so that certain anonymous access be allowed via the particular role.

As for setting this up via configuration, if it is possible, it would be rather difficult and sort of "hacky".

I don't think so... I was just writing you need to create to separate endpoint when I decided to read you question again and noticed the last statement of your question. So the answer would be no (that I know of)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top