views:

1523

answers:

4

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)?

A: 

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)

sebastian
Know of a way to inject an http header before the request gets to the WebHttpBinding? A custom binding element perhaps? Any examples of manipulating the HTTP header in a custom binding would be great.
TheSoftwareJedi
sorry dude I don't... -1!, WTF?
sebastian
A: 

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.

JarrettV
A: 

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".

Adron
yes - but it doesn't even hit any role provider if it doesn't get a authenticate header. It just quickly returns a 401 from the binding code.
TheSoftwareJedi
A: 

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
Ronald Wildenberg
Actually HttpListener is quite capable of supporting multiple authentication schemes. You just need to implement a handler for the AuthenticationSchemeSelectorDelegate property of HttpListener. It is WCF that is screwing you over. Once again.
Darrel Miller
Yes, WCF does not provide a way to attach a handler to this event, otherwise it would be possible...
Ronald Wildenberg