1

I have a ServiceHost that implements many Contacts on various endpoints and bindings ((http & https) x (rest & soap) with Anonymous Access, Windows, or Custom authentication, as bound depending on the Contract) & nettcp with Windows authentication. Custom authentication is embedded in the http or soap headers. Each endpoint and contract has its purpose. It should all be manageable on a single ServiceHost - I don't want to split it up.

I've gotten it to the point where all the endpoints work and serve their content correctly, but the authentication/authorization isn't integrated into the WCF stack. I have been using a MessageInspector to handle validation of the authentication header and allowing it if the token was valid.

Now I want to integrate the authentication/authorization into the WCF stack. I want to be able to access the identity and check the claims in each Operation's implementation. And perhaps basic claims can be authorized centrally, like "are these claims authorizing anything at all in this contract?" (by contract type).

In the case of custom authentication, I have a signed/secure token that includes a custom implementation of identity and property claims which I can properly extract and convert into WCF claims upon receipt (even if I don't know exactly where to put them once I've got them). For Windows authentication, I just need access to the default Windows identity stuff.

I can set the ServiceAuthenticationManager and ServiceAuthorizationManager each to custom values, but it's not doing anything I want it to and I'm getting totally lost.

For example, the ReadOnlyCollection<IAuthorizationPolicy> authPolicy coming into Authenticate() seems to be inconsistent - sometimes it's empty, sometimes it has one UnconditionalPolicy and sometimes it has 2 or more (4?) of my custom IAuthorizationPolicy already there. Meanwhile IAuthorizationPolicy.Evaluate() gets executed anywhere from 0 to ~9 times per request. Sometimes, within IAuthorizationPolicy.Evaluate(), OperationContext.Current is null! And sometimes the evaluationContext.ClaimSets already has my claimset. Yet state is always null even when I give it a value in a previous enactment.

Rather than tackling these problems individually, I think it'd be better to step back and ask for some high-level explanation of what I should do/expect to see.

Authentication: When a request comes into the ServiceHost, it needs to get Authenticated. At this point in the pipeline, I don't need to know what they can do, just who they are. If a client submits both Windows credentials and a custom authentication ticket to a Contract/Binding on which I require just a custom authentication ticket, the service shouldn't be tricked into evaluating the wrong one. But perhaps at this stage in the WCF pipeline, the Contract hasn't been resolved so perhaps during this stage, all found identities/claims/tokens should be captured and selected among later. Is this right? How is this done?

Message Inspection: I have a custom MessageInspector which I'll still need for CORS support and OPTIONS request processing on some of the endpoints. I believe this happens after authentication and before authorization. In the case of OPTIONS, I set ref message to null and skip the Operation entirely, jumping straight to the BeforeSendReply. Clients don't send the auth-token on a CORS OPTIONS preflight request and so I allow these requests unconditionally.

Authorization: Depending on the Contract, I want to require certain authentication mechanisms and ignore others. I believe some setup needs to prepare the Thread Principal and Operation Context principal to the correct value. It seems that multiple Authorization policies can be in play at once. How do they interact?

Operation: I want to be able to implement each operation assuming that the identity of the caller is authenticated using a supported authentication (by Contract, which I'm OK maintaining hard-coded somewhere ONCE) and get the validated caller identity and assert simple permissions checks againsts the verified Claims.

How do I achieve this (code preferred over config xml)?

Thanks!

Jason Kleban
  • 20,024
  • 18
  • 75
  • 125
  • 1
    Using single service host across all of different security boundaries is not optimal. Why you don't want to split them up? Why would single client send both Windows and custom token on a same endpoint? If you are hosting in IIS you could take advantage of IIS CORS options. This setup seems overly complex. – Petar Vučetin Jul 29 '13 at 16:30
  • Will this answer help? http://stackoverflow.com/questions/3715778/custom-wcf-authentication-with-system-servicemodel-serviceauthenticationmanager – Mike Goodwin Jul 29 '13 at 22:41
  • Petar - I appreciate your concern but those questions are irrelevant to the goal of *how*. However, it's not a single client - it's different kinds of clients that work together. The windows service, in part, connects to request principal tokens on behalf of the other clients. There is some serving of static content. And some clients might perform multiple duties. – Jason Kleban Jul 30 '13 at 01:36
  • Mike, I saw that post and it is helpful, but it didn't answer all my questions. – Jason Kleban Jul 30 '13 at 01:36
  • @PetarVučetin - FYI I did end up splitting to multiple servicehosts be authentication type. – Jason Kleban Aug 15 '13 at 00:47

0 Answers0