I’ve been scouring the internets looking for a simple solution for authentication with WP7.
I am using a simple WCF REST web service based on the template for .net 4.0
Here are the two solutions I ended up with:
Solution 1 – Use the built in authentication service
Add a new WCF service to your project, remove the code behind file and change the svc file to this:
<%@ ServiceHost Language="C#" Debug="true" Service="System.Web.ApplicationServices.AuthenticationService" %>
Add the forms authentication and membership configuration (just like any asp.net website)
Now in the WP7 project, you can add a service reference, again, this part is very standard.
To get this working, you need to use the cookie container on calls to both services.
Instead of detailing this approach, I figured I’ll just link to Kevin Hoffman’s blog post
Solution 2 – Use basic authentication
This solution is a lot more restful. There’s no state saved on the server, no session and no cookies.
I’ve decided to use RestSharpfor server calls from WP7.
It’s very easy to ad basic authentication code on the client side when using RestSharp since the library has built in support for it using the HttpBasicAuthenticator.
var request = new RestRequest("Orders");
request.Method = Method.GET;
request.RequestFormat = DataFormat.Json;
var client = new RestClient(baseUrl);
client.Authenticator = new HttpBasicAuthenticator(userName, password);
client.ExecuteAsync(request, (response) =>
if (response.StatusCode == HttpStatusCode.OK)
//deal with the response
What I like about RestSharp is being able to define my resource. To get authentication working, I just needed one line of additional code on the client side.
So far, I’m sending the basic auth base64 encoded header to the server, now I need to intercept it on the server side and authenticate the user.
To do that, I added a class that inherits from ServiceAuthorizationManager, here’s the code:
public class BasicAuthorization : ServiceAuthorizationManager
protected override bool CheckAccessCore(OperationContext operationContext)
string authtext = HttpContext.Current.Request.Headers["Authorization"];
string decoded = DecodeFrom64(authtext.Replace("Basic ", String.Empty)).Split(':');
string username = decoded;
string password = decoded;
if (Membership.ValidateUser(username, password))
MembershipUser user = Membership.GetUser(username);
GenericIdentity identity = new GenericIdentity(user.UserName);
//RolePrincipal principal = new RolePrincipal(identity);
GenericPrincipal principal = new GenericPrincipal(identity, "UserRole".Split(','));
System.Threading.Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
//always return true, we just want to get the identity set up so methods can support authorization
/// The method to Decode your Base64 strings.
/// <param name="encodedData">The String containing the characters to decode.</param>
/// <returns>A String containing the results of decoding the specified sequence of bytes.</returns>
private static string DecodeFrom64(string encodedData)
byte encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
string returnValue = System.Text.Encoding.UTF8.GetString(encodedDataAsBytes);
There’s nothing complicated here, I’m just decoding the base64 string from the header and using the membership functions to validate the user’s credentials and create an IPrincipal object which is then set as the current user. This will allow methods in the actual service to access the membership object in a standard way. That’s also the reason the method always returns true. I’m not interested in blocking access at this point, I’ll leave that up to individual methods. (If you wanted to secure the entire service for authenticated users, you could return the result of the ValidateUser call, I wanted to have a methods that can be called by anonymous users as well).
This sample doesn’t add the user’s actual roles, which will be easy to implement (just get the roles using the username and add to the principal)
The last step is to update the servicemodel configuration to use the BasicAuthorization class. Just find the default behavior for your REST service and add the ServiceAuthoization element.
<serviceAuthorization serviceAuthorizationManagerType="SampleWCFRESTService.BasicAuthorization, SampleWCFRESTService" />
Now checking “HttpContext.Current.User.Identity.IsAuthenticated” in any method in the web service will work.
The problem with basic authentication
The problem of course, is sending user credentials with every request. Since I don’t want to send all of the requests over SSL due to performance issues (and I usually don’t really have to) I need a better solution.
The standard solution for this problem is to make the first call over SSL to an “Authenticate” resource, create a token and send it back to the client. From that point on you can send the token with subsequent requests.
To add support for a token, you can add another ServiceAuthorizationManager or just update the logic to check if the Authorization header starts with Basic or CustomName.
The encrypted token should include the username and password and you can add other elements to it (like expiration for example).
In my implementation, my Authentication resource andthe ServiceAuthotizationManager both use the same class to encrypt/decrypt the username and password and in that class I also check if the token has expired.
I decided to go with the second solution since it seems to be the standard way REST services are developed (sending user/pass and getting a token). I wouldn’t really want to deal with cookies and that solution might not be friendly to other platforms.