Here's what I'm trying to do.
We have a SSO authentication service that other externally facing web pages and services use to authenticate users. A user tries to reach a service, if no cookie is found containing an authentication token, they are redirected to the SingleSignOn authentication service. The auth service does it's work, and redirects the user (HTTP 302) to the original URL with their encrypted authentication token in the URL. Great.
How can I invoke this from a WCF POX service? No SOAP here, just HTTP GET/POST with XML responses.
What I'm currently doing is, in each service method implementation method, checking the headers for the cookie. If the cookie exists, verify the auth token and process the request. If the cookie doesn't exist or the auth token has expired, then respond with:
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Redirect;
WebOperationContext.Current.OutgoingResponse.Location = string.Format( authServiceURL, returnURL );
That works, but isn't integrated with any of the WCF features, and requires me to manually code for a whole bunch of scenarios. Is there a way I could implement this using these classes:
<serviceCredentials>
<issuedTokenAuthentication>
</issuedTokenAuthentication>
or use some other means that checks each request to the service?
I've been reading pages like: How to: Create a Custom Token, but I don't see how it applies to my needs.
Any suggestions would be appreciated. I'm looking into this because I have some time before my project kicks off, and I'd like to implement this project correctly and learn about WCF as much as I can.
I hate to answer my own question, but I'll post what I ended up doing for this.
We have an authentication service that we can redirect (Http 301) clients to, that will redirect them back to our service after appending an authentication token in the url. Using that, here's the steps my service takes.
I added a System.ServiceModel.ServiceAuthorizationManager implementation, and overrode the CheckAccessCore method to check for the authentication token in either a cookie/header or the url. If found, I'd verify that the token is valid. That method simply returns true or false, indicating if the request passed authentication or not. If the message passed, I created a IExtension object to contain some data and added it to the OperationContext extensions.
I also added an implementation of a IDispathMessageInspector. This has AfterReceiveRequest and BeforeSendReply methods. I used the BeforeSendReply method to hijack the response. If the message didn't pass authentication (didn't have my IExtension object in the OperationContext extensions), I set the WebOperationContext.Current.OutgoingResponse.StatusCode to redirect and the Location to the url of the authentication service.
If it did pass authentication, I made sure the auth token was in the response message cookie/header in the BeforeSendReply method.
This article helped me figure out how to hook things up. Is this the best way? No idea. But this works for my WCF/REST service. It blocks all unauthenticated messages from even getting to my ServiceContract implementation, redirecting all requests to the authentication service.