Thanks for visiting my blog!
I was trading tweets today with @pauliom about whether RIA Services would solve some Auth problems he was having out of the browser. While RIA does do some interesting things with roles/users, I mentioned that typical Forms Auth out of the box should just work.
To that end I have created a simple example of how to protected WCF Services with Forms Auth (works with ADO.NET Data Services as well BTW). Because I wanted to support it out of the browser as well, I used the new Forms Auth service. To do so, just add a new .svc file to your project and put this in the body:
<%@ ServiceHost Language="C#"
Service="System.Web.ApplicationServices.AuthenticationService" %>
The web.config also needs to know about the service. So first, add a web extensions like so:
<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true"/>
</webServices>
</scripting>
</system.web.extensions>
Finally, the WCF configuration bits:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior
name="OutOfBrowserFormsAuth.Web.AuthServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service
behaviorConfiguration="OutOfBrowserFormsAuth.Web.AuthServiceBehavior"
name="System.Web.ApplicationServices.AuthenticationService">
<endpoint address=""
binding="basicHttpBinding"
contract="System.Web.ApplicationServices.AuthenticationService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Once you have all those pieces you can create the proxy like any other service (with “Add Service Reference…”). Then you can login from the Silverlight application:
var authSvc = new AuthenticationServiceClient();
authSvc.LoginCompleted += (s, a) =>
{
if (a.Error != null)
{
result.Items.Add(string.Concat("Error logging in: ", a.Error.Message));
}
else
{
result.Items.Add(string.Concat("Login: ", a.Result));
}
};
authSvc.LoginAsync("swildermuth", "P@ssw0rd", null, false);
So securing the web service becomes pretty simple. I created a new “Silverlight WCF Service” inside a secure folder:
I created the web service and then the Service Reference before enabling security so adding a Service Reference would work. This is the one pain point in that you must disable the folder security to add the reference then re-enable it afterwards:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
</system.web>
</configuration>
Now the web service will only work once the login happens. You can test this in or out of the browser and with both stacks with the source code. Here’s a quick screenshot showing it working after login and not working after logout:
You can download the source code here:
http://wilderminds.blob.core.windows.net/downloads/ProtectedWCF.zip
UPDATE: Here are some links to the actual docs for this:
Configuring the Authentication Service: