Facebook Login for Windows Phone Apps

Friday, May 18, 2012 / Posted by Luke Puplett / comments (4)

The brief: allow new customers to sign up and sign in with their Facebook account, because they have this option on the website, so they’re going to need it in the phone app.
This is a high-level blog post about enabling Facebook login in a Windows Phone application. Once you’ve configured your app at and got your client/consumer ID and secret from developers.facebook.com, the process to actually authenticate your users is very simple - it’s the bigger picture that’s more difficult and so this blog post aims to prepare you rather than give you a few code snippets for what is essentially just extracting some tokens from a string.
So, with that said, these are the things to consider before writing any code:

  • How does OAuth work?
  • How will a Facebook account map to my accounts?
  • How does this affect my current secure authentication?
  • How will the login screen work on the phone?
  • What happens when the app has been slept for a long time?

How does OAuth work

Facebook uses a version of OAuth. Personally, I like learning specifications and writing my own code, rather than learning a framework or SDK. Usually, the spec is more clearly documented than other people’s SDKs.
Facebook has its own documentation covering how to authenticate, which I strongly advise you to read. The OAuth specification will give you a wider understanding, it’s pretty simple, but I must point out that Facebook doesn’t stick to the spec.
I’m going to explain the process in a nutshell here, but before I do that, consider that your application must register with Facebook and obtain a Consumer ID and Secret which will identify your app to Facebook. The aim is to get hold of an Access Token, which is a short-lived ticket that represents your rights to act on behalf of a Facebook customer.
  • There are a few types of authentication, depending on whether you’re building web apps or mobile/desktop/GUI apps.
  • For a web app, your server redirects the user to the Facebook OAuth sign-in page and passes across your Consumer ID so Facebook knows it’s issuing an Access Token for your app.
  • When doing so, you pass Facebook a URL to redirect back to, after the user signs in.
  • Your server ‘waits’ for the redirect and then extracts a temporary token from the redirect which it used to fetch the proper Access Token directly from Facebook, using an HTTP get.
  • For a client app with a UI, it’s much simpler.
  • Place a Web Browser control on a page and hook-up the Navigated event.
  • You automate the Web Browser control to navigate to the Facebook OAuth sign-in page, the user then logs in.
  • Facebook then redirects to a page you specify (at a domain you preconfigure with Facebook) and in the URL’s fragment portion, is the Access Token, as this occurs, the Navigated event fires a few times.
  • Inspect the Uri at each point to see if it has the Access Token or an error code. As soon as you have the token, you can progress the UI to the next stage.
  • You’re looking for access_token=xyz and expires_in=123 (seconds) parameters in the Fragment portion of the URI, it’s simply a case of parsing the string.

Why use Facebook to authenticate your customers?

Essentially, there are only a couple of reasons. The first is integration: you’d like your app to connect to Facebook and programmatically post to your customer’s feed or see who their friends are, perhaps. The second is to reduce sign-up friction and provide a better experience to the on-boarding process. This may be simply to remove the need for a customer to remember another password (and providing a way to reset forgotten passwords) or because your sign-up process asks a bunch of questions that you could actually just pull from their Facebook profile.
In the latter case, you’ll likely have your own customer entities in a database that will need to be linked to a Facebook account.

Mapping the Facebook account to your own accounts

If you’re retrofitting Facebook login to an existing app, then you’ve probably already got your own login process, so you’re going to need to offer a login screen supporting the old username and password sign-in as well as the new OAuth method.
As mentioned above, you might need to have a process for reading some details from Facebook and creating an account entity in your own system, and you may even wish to offer a way for users of the old sign-in scheme to connect their accounts.
I won’t go into detail about how to do this linkage, but whichever way you choose to accomplish it, you’ll need to ensure that another Facebook OAuth application cannot simply log-in to your app by just sending a Facebook ID to your login system.
Your server-side system should require the Access Token and user’s Facebook ID, and then use the Access Token against the Facebook Graph API directly to obtain the default FB account and check the ID for the user it returns matches what you’ve been sent.
You’ll also need to prove that the Access Token and user ID have come from your app, so you’ll need to sign the data with a secret that’s shared between your servers and your app, which means obtaining/agreeing a key before the Facebook sign-up occurs.
If you don’t do this, then there’s nothing to stop another Facebook app from getting an Access Token and FB user ID and sending them to your login endpoint and masquerading as one of your customers!
There’s an inherent weakness here, in my opinion, that could be strengthened if, when your server fetches the user account using the supplied Access Token from Facebook, you supply your App Secret and FB could ensure that the Access Token was issued to your app.

How will the login screen work on the phone?

If you don’t have an existing login scheme then you only need to supply the Facebook login option, unless for privacy reasons, you’d like to allow your customers to sign-up without Facebook.
It’s safe to assume that login will take place from a dedicated page, as opposed to a popup control. The user should only be bothered by the login screen when they need to login, and that page needs to play host to a web browser.
We also need to consider sign-up, as well as sign-in; your application may need to collect extra information on sign-up, data that’s not available from Facebook, but also, your customers might not want to use Facebook.
In my scenario, I have a dedicated page and flow for non-Facebook sign-up, and a dedicated page and flow for Facebook sign-up and sign-in (combined).
The flow goes something like this:
OAuth Page Flow
The left-most page is the Home Panorama which detects a guest login and provides two menu options for logging-in and signing-up.
The top path consists of:
  • The Login Method Selector page, offering the Facebook login and a normal username + password UI.
  • Using the latter will call the normal login web service and follow the quick route back to the Home page, while selecting Facebook login, will navigate to a page with a Web Browser control.
  • This page will display the standard Facebook OAuth login screen and upon entering details, the browser control will vanish and, if the customer is signing-up, they’ll be presented with a page through which they can supply a screen-name, otherwise, if logging-in, they’re just navigated to the Home page.
  • If sign-up goes well, then a welcome message is displayed and the user is offered the option to post a Wall message or click to go straight to the Home page.
The bottom path consists of:
  • The Sign-up Method Selector page, offering Facebook and ‘Manual’.
  • The Facebook option takes the user to the top flow, whereas the manual route consists of a few more pages / UI that collects and checks all the extra data that’s needed to create an account, data that is normally taken from their FB account details.

What happens when the app has been slept for a long time?

Login credentials are persisted between app use sessions and the Home page is able to detect which login method the user used last time. For a Facebook login, the previous Facebook Access Token is verified and, if expired, the app navigates to the Facebook login page and brings up the Web Browser control.
If the Web Browser has cached login details then the browser will automatically be logged-in, without the user typing anything, and the app will navigate back to the Home page. This flow happens so quickly that it appears that the app opens at the Facebook page, looks busy for a couple of seconds and then goes to the Home page.
This flow might take some time on slow networks but Manual logins can simply authenticate without navigating anywhere and work much more smoothly.
So far, this is all fine and dandy, but in reality the Home page is not the first page of an app. An app may be entered via the back button or on resume, into a state where the user is no longer considered logged-in – the Access Token has expired or your server session has been pruned.
In my app, I use my own MVCVM pattern. I have a Controller in addition to the ViewModel. This is just a personal preference, I like to keep my ViewModels as just ‘binding and commanding surfaces’ with no logic.
Doing things this way keeps me from adding spiralling side-effect logic in property setters and coerces me to use dedicated helper and utility classes rather than be tempted to inherit too much application logic - I’ve worked on apps that reuse logic by VM subclassing and it gets ugly. I also like to build standard ‘dumb’ VMs which can be reused across the app and contain only what needs to be on the screen.
Saying that, I do use inheritance in this situation. My base PageController has a set of virtual methods which orchestrate all the initialization, one of which is called to check authentication.
Each time a page is navigated to, the PageController runs some code to ensure the user is logged-in which allows me to redirect the user to the Login page and return afterwards using the BackStack. I also check the BackStack and remove the sign-in pages so the user can’t back into them.
With this logic on each page, even if the user lets the phone go idle overnight while on a page deep within my app, the Login flow will run in the morning, as soon as the page resumes.
Of course, you don’t have to have funky Controllers and virtuals to do this, but it needs bearing in mind that authentication isn’t just something that happens on the Home screen.
Time will tell whether this page flow method works. It’s perfectly feasible to embed a Web Control in a popup UI control or inject it into the visual tree. As networks get faster (I’m looking at you, 4G), then Facebook login will become a less irksome UI dance.
Have fun, and here’s some useful links:
Facebook Authentication Documentation
http://developers.facebook.com/docs/authentication/
OAuth 2.12 – although Facebook strays from the standard in some fairly major ways.
http://tools.ietf.org/pdf/draft-ietf-oauth-v2-12.pdf
Where Facebook veres from the OAuth standard.
http://stackoverflow.com/questions/9724442/is-facebooks-oauth-2-0-authentication-a-strict-implementation-of-the-rfc

Labels: , , , , ,

Helpful docs when hardening an IIS web server

Sunday, November 21, 2010 / Posted by Luke Puplett / comments (0)

While clearing up some crap on my desktop I came across a note listing some documents I’d used when preparing my web server for co-location and exposure to the harshness of the public internet.

How To: Harden the TCP/IP Stack
http://msdn.microsoft.com/en-us/library/ff648853.aspx

TCP Receive Window Size and Window Scaling
http://msdn.microsoft.com/en-us/library/ms819736.aspx

How To: Protect Forms Authentication in ASP.NET 2.0
http://msdn.microsoft.com/en-us/library/ff648341.aspx

How To: Perform a Security Deployment Review for ASP.NET 2.0
http://msdn.microsoft.com/en-us/library/ff647403.aspx

How To: Use IPSec for Filtering Ports and Authentication
http://msdn.microsoft.com/en-us/library/ff648481.aspx

How To: Use IISLockdown.exe
http://msdn.microsoft.com/en-us/library/ff650415.aspx

Labels: , , ,

ASP.NET MVC 2 RedirectToSignin

Thursday, August 19, 2010 / Posted by Luke Puplett / comments (1)

If, for whatever reason, you cannot use the [Authorize] attribute on an action method, or as in my case, you have an unusual architecture, then this helpful method directs a visitor back to the sign-in or login screen and then re-runs the original action. It’s designed to work exactly as the AuthorizeAttribute works, but with the difference that you can do your own IsAuthorised logic within the method.

An application I’m working on has a WCF service which is where customers are logged-in. The MVC application simply packages up the web front end and ships all requests, CRUD ops, everything into service calls and then paints the results out via ASP.NET/HTML.

When a customer logs in to my MVC 2 app, it’s really just calling Login on the WCF Authentication Service – the MVC app doesn’t keep track of sessions and is truly stateless. The MVC app does, however, use forms authentication and so the cookie can say “yep, customer is signed-in” while the WCF service says, “Uh uh. This customer’s session expired.”

This means that my action methods with [Authorize] run, but then fail. I wrote this method to redirect the customer to the sign-in box, and then continue to execute the original action, using the returnUrl.

Code:


protected ActionResult RedirectToSignin(
    string returnAction, 
    string returnController, 
    object returnRouteValues, 
    RequestContext requestContext)
{
    UrlHelper u = new UrlHelper(requestContext);
            
    string returnUrl = UrlHelper.GenerateUrl(
        null, returnAction, returnController, new RouteValueDictionary(returnRouteValues),
        u.RouteCollection, requestContext, true);

    string baseAddress = String.Format("{0}://{1}"
        HttpContext.Request.Url.Scheme, HttpContext.Request.Url.Authority);

    return Redirect(String.Format("{0}/Customer/Signin?returnUrl={1}"
        baseAddress, returnUrl));
}

Now within my action method, if I get a null or a fault from my service, I return RedirectToSignin(xyz) instead of returning an error. After sign-in, the action is called again and all is good in the hood.

Labels: , , ,

Adding a UserAgent to WCF Clients

Thursday, July 22, 2010 / Posted by Luke Puplett / comments (0)

A quick post to show how to add a UserAgent to a WCF call so that it can be inspected on the server side, perhaps to see which versions of clients are calling your service.

And completely free of charge, I'm including some extraneous code I use to show how service method calls can be made without having to jump through hoops every time.

The code

        public T CallServiceMethod<T>(Func<T> methodCall, bool canExpectNull)
        {             
            T response;

            using (OperationContextScope scope = new OperationContextScope(this.ServiceClientChannel))
            {                 
                HttpRequestMessageProperty p = new HttpRequestMessageProperty();
 
                p.Headers.Add(System.Net.HttpRequestHeader.Cookie, this.AuthenticationCookie);
 
                p.Headers.Add(System.Net.HttpRequestHeader.UserAgent, typeof(ServiceHelper).Assembly.FullName);
 
                OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, p);

                this.IncrementCallsInProgress();
                try
                {
                    response = methodCall.Invoke();

The blurb

I'm sorry about the broken lines - I so nearly picked a full width Blogger template, too. The method above essentially wraps a delegate invocation in some calls into WCF's OperationContext which adds the headers. It's interesting to look at the OperationContext in the debugger, much as you probably did with the HttpContext when first looking at an ASP.NET app - its sort of the equivalent but in reverse.

The method's ending isn't shown, I'm lazy like that, but it just catches errors, the finally block decrements the calls-in-progress counter and there's some logging.

On the server, I use the HttpContext.Current.Request.UserAgent string to log which client versions my customers are running. Useful.

Notice that I'm also adding a cookie which I store in the class that this method is part of. I'm using the built-in AuthenticationService which uses Forms Authentication and thus, cookies. This is not required in Silverlight as the IE stakc stores and reapplies appends any cookies received, automatically.

To use this method, I instantiate my service client proxy and then call ServiceHelper.CallServiceMethod( () => { return proxy.SomeMethod(xyz); });

The proxy call is thus invoked within the context changes above.

Labels: , , ,

Setting-Up WCF Over SSL on IIS 7.x

Monday, July 19, 2010 / Posted by Luke Puplett / comments (1)

This is a short post is about the steps I had to take to switch an existing test WCF service over to a secure staging version that more closely mimics how it’ll be in the production environment. I hope to include some things they didn’t tell you in the instruction manual, mainly concerning the use of test certificates.

It’s stuff like this – configuring a secure web service – that makes me dislike WCF and IIS quite a lot. I liked Web Services, and Remoting, I even found raw sockets surprisingly easy but WCF is hard work. It’s the sort of thing that needs its own UI, management tools, and server, but to do this would arguably constrain its power.

  1. Add a self-signed certificate to the server by opening IIS Manager, highlighting your server name in the left pane and locating Server Certificates on the right and choosing Create Self-Signed Certificate then following the instructions.

  2. Add a new binding to your site for HTTPS and note that there’s no option for the host name.

  3. WCF cannot handle multiple bindings to the same scheme, as IIS and ASP.NET sites can, so if your WCF service is hosted downstream of your main site, such as from a virtual directory underneath your root domain and site, then add the following to your web.config which will filter the bindings so WCF sees just two:


    <system.serviceModel>
    <serviceHostingEnvironment>
    <baseAddressPrefixFilters>
    <add prefix="http://wwwdev.dom.co.uk" />
    <add prefix="https://wwwdev.dom.co.uk" />
    </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    </system.serviceModel>
  4. And now the bit that seems never to be explained and doesn’t seem to merit a proper UI in IIS, binding the certificate to the host header. Run this at a command prompt (one line):


    appcmd set site /site.name:"Main Site" /+bindings.[protocol='https',bindingInformation='*:443:wwwdev.dom.co.uk']
  5. Do not remove the original HTTPS binding. When I did, I got this error:

    An error occurred while making the HTTP request to https://wwwdev.dom.co.uk/xml/AuthenticationService.svc. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.

  6. Now, if you’re using the built-in AuthenticationService, in your web.config or web.staging.config, make the following change/addition:


    <system.web.extensions>
    <scripting>
    <webServices>
    <authenticationService enabled="true" requireSSL="true"/>
  7. Still in this document, find the binding element for the service and set it to use Transport security – the bottom lump of mine looks like this:


    <binding name="ssl">
    <security mode="Transport" />
    </binding>
    </basicHttpBinding>
    </bindings>
  8. Close and save all that and then make the same change on the client. Personally, I don’t use config files for public ‘out there’ apps so the change is made within a service client factory using the following code:


    if (withSsl)
    basicBinding.Security.Mode = BasicHttpSecurityMode.Transport;
  9. Add the following non-WCF specific code at some point in your app which essentially just accepts any certificates as valid even if they’re downright dodgy (so make sure not to let it leak into production).


    #if DEBUG || STAGING
    System.Net.ServicePointManager.ServerCertificateValidationCallback = (se, cert, chain, sslError) => { return true; };
    _log.Warn("A pre-release option has been set: server certificates are no longer being checked for validity by this client app.");
    #endif
  10. You do not need to add code that modifies the Authentication settings for the ServiceCertificate on the ClientCredentials object of a service client (ServiceBase<T>).

  11. Now test your service. You may want to use a tool like Fiddler to inspect the HTTP traffic.

Labels: , , ,

Instrumentation Insecurity

Thursday, July 09, 2009 / Posted by Luke Puplett / comments (0)

Following good practice and riddling your methods with tracing code could lead to your projects requiring the most dangerous (for want of a less sensationalist word) security permission: UnmanagedCode! (den, den, DERRR)

Last night I was using Permcalc to check the permissions on an assembly that I was preparing to ship. Before building the library for release, I needed to add the necessary declarations to rescind any permissions granted by the CLR that are surplus to requirements. How conscientious.

During the course of producing the Permcalc reports I noticed the following in the report:

<IPermission version="1" class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Flags="UnmanagedCode, ControlEvidence" /> 


I was pretty sure I’d not been calling any low-OS-level methods or parts of the Framework which do. Caveat: at some point, most of the Framework calls unmanaged code but it shields its consumers by way of having FullTrust by definition and using Assert to prevent demands looking at the caller permission set.

By adding –Stacks to the Permcalc command line, I then inspected all my methods looking for this severe security requirement, then checked their call stacks to determine if there were any calls being made that could be so demanding.

I followed the trail to an Instrumentation assembly I wrote years ago in my first months exploring .NET. I remember reading about how sprinkling tracing lines within one’s methods was a great idea and a good thing for programmers to do. So I did it.

The System.Diagnostics.Trace class MSDN documentation clearly states under the .NET Framework Security section:


  • SecurityPermission

    for operating with unmanaged code. Security action: Demand. Associated enumeration: SecurityPermissionFlag..::.UnmanagedCode



  • Of course now it turns out that be doing this I have inadvertently bound all my dependant assemblies and projects to needing permission to execute unmanaged code, which of course in .NET land is a free pass to execute whatever some malicious logic pleases.

    Because of the unexpectedly severe requirements of such an inert looking class I was roused to see if there were anymore .NET classes harbouring such devilish details.

    I ran this into Bing

    "for operating with unmanaged code" site:microsoft.com

    But the motley assortment of Framework artefacts such as Marshal and various window handling methods made Trace all the more conspicuous and somewhat ironic.

    I’m going to have to extricate myself of all that extraneous instrumentation. Ba! I’m even having difficulty saying it.

    Labels: ,

    One Service + Two Client Platforms = Misery

    Friday, May 08, 2009 / Posted by Luke Puplett / comments (0)

    Aim: I want to be able to transmit a username and password hash and see it easily from within the service.

    My idea of Hell is WCF. I liked .NET Remoting and I got on with Web Services, but the unified Windows Communication Foundation is a quagmire of configuration and complexity, not least because its half-merged with IIS, which is sort of merged but not merged with ASP.NET.

    Today, I am tackling the issue of using the same WCF Service that my Silverlight client uses, for a fat desktop client.

    Making a Meal of WCF and Cookies

    The scenario to the uninitiated might look straight-forward, after all I’m connecting two Microsoft .NET-based products to a Microsoft .NET-based SOAP service, all running in the same VS solution on one box.

    The problem is that Silverlight runs in the browser and has an authentication scheme which uses its host browser’s HTTP stack and cookies, while the other client, despite being fat, has never even seen a cookie.

    To be clear, my WCF services end uses Microsoft’s AuthenticationService to provide Forms authentication behaviour over the HTTP connection between SL client and service, which basically does the cookie creation and response so I don’t have to. This works great but I what about my non-Silverlight clients?

    While Jonas Folleso has one solution to the problem, by detaching the authentication cookie and sticking it back on to all outgoing headers, I wanted to take the ‘easier’ route: exposing another service end-point that supports some kind of authentication.

    I want to do this because I want my client to sign-in using the SSL secured AuthenticationService, set-up a session with some shared secret key and then in all subsequent requests to my other services, send over a hash of something using the shared secret.

    I’m actually writing this as I work on it, so as these words are being typed, I don’t know what to expect.

    Step One: Add a new EndPoint and connect to it

    I add a new EndPoint to the web.config of my IIS service host, using the same basic binding as the working service, just for simplicity and testing.

    <endpoint address="/vpr"
    binding="basicHttpBinding"
    contract="IUserService"
    />

    Lesson - While doing this, I learn that the <baseAddresses> section is pointless on IIS because its IIS and the base address will be wherever the .svc files are.

    I copied the chunk of XML that defines the mex endpoint, and like mex and according to MSDN, my service endpoint address will be relative to the base URL which is the svc file, I presume.


    Adding a Service Reference to any of the URLs above fails with error saying:


    The request failed with HTTP status 400: Bad Request. Metadata contains a reference that cannot be resolved: 'blah'.

    Lesson – You only need to point the Add Reference box to the .svc file and the other endpoints are read from the WSDL (you can see this because the client app.config will fill with the server endpoints).

    mex is an exception to the rule and can be referenced by putting /mex after .svc, also the discover option doesn’t see the endpoint as being a different service.

    This is all how it should be and I think endpoint addresses are actually just ID strings which help WCF route messages into the right worker queue for processing on the server but are structured as URLs to confuse you.

    Step Two: Choose a Binding

    The aim is simply to choose a binding which puts the plumbing in place for me to transmit credentials. So first up, I try just setting ClientCredentials.UserName to something useful and checking it on the server via ServiceSecurityContext.Current, but get a null ref exception.

    I also try disabling anonymous logon from the IIS console in case this is causing my username to be lost, but this causes everything to break – I can’t even connect to get the service description.

    Lesson – Ignore the bit about disabling anonymous access.

    I persist with the trusty basicHttpBinding because MSDN says:

    By default, the BasicHttpBinding class does not provide security. This binding is designed for interoperability with Web service providers that do not implement security. However, you can switch on security by setting the Mode property to any value except None. To enable transport security, set the property to Transport.

    I do as it says but I get this error upon updating my Service Reference:

    Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http].

    The problem is that I don’t want to use HTTPS. Time to try another tack: Message Security, which MSDN tells me

    means that every message includes the necessary headers and data to keep the message secure. Because the composition of the headers varies, you can include any number of credentials. This becomes a factor if you are interoperating with other services that demand a specific credential type that a transport mechanism can't supply, or if the message must be used with more than one service, where each service demands a different credential type.

    Here goes nothing.

            <binding name="vpr">
    <security mode="Message">
    <message clientCredentialType="UserName"/>
    </security>
    </binding>

    I refresh my Service References and receive:

    BasicHttp binding requires that BasicHttpBinding.Security.Message.ClientCredentialType be equivalent to the BasicHttpMessageCredentialType.Certificate credential type for secure messages. Select Transport or TransportWithMessageCredential security for UserName credentials.

    Right then. TransportWithMessageCredential it is, or at least it would be but that of course leads me right back to:

    Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http].

    An MSDN article on using the ASP.NET Membership Provider reckons I can use WSHttpBinding set to Message Security to transmit a user name, but goes on to talk about adding service behaviours for the membership provider. I will try most of it (as I don’t want to use the ASP.NET MemProv). I put

        <serviceCredentials>
    <userNameAuthentication userNamePasswordValidationMode="Custom"/>
    </serviceCredentials>

    ..in the behaviours element with this in the binding element:

        <security mode="Message">
    <message clientCredentialType="UserName"/>
    </security>

    But this gives this error when adding/updating the Service Reference:


    UserNamePasswordValidationMode.Custom requires a CustomUserNamePasswordValidator. Specify the CustomUserNamePasswordValidator property.


    I may be on to something... searching microsoft.com reveals an article entitled User Name Password Validator.

    So I’ve written a test class called CookielessCredentialValidator which extends System.IdentityModel.Selectors.UserNamePasswordValidator and just throws a NotImplementedException on the only overridable method is has, Validate() and changed my web.config:

    <userNameAuthentication
    userNamePasswordValidationMode="Custom"
    customUserNamePasswordValidatorType="App.Web.CookielessCredentialValidator"/>

    Upon updating my service reference I get:


    Could not load type ‘App.Web.CookielessCredentialValidator’ from assembly ‘System.ServiceModel, Version=3.0.0.0, Cul... etc.

    Looking back at the MSDN article I realised that I need to format the type name differently, prefixing my derived class with the name of my service class and maybe the word service after it? Not really clear and the article on customUserNamePasswordValidator provides no help:

    Looking further into this, it seems that I must create an X509 Certificate.

    Lesson – You can’t send credentials without HTTPS or some other encryption method in the .NET Framework, even if you do have you own method for encrypting the data you wish to put in the username and password properties.

    Step Three: Go back to Jonas Folleso’s Blog and do what he did

    ...and pray that Microsoft changes this nannying part of the framework before I get customers trying to use my service from a platform that can’t fiddle around with cookies.

    The End.

    P.S. Sorry about the extra space around blockquotes, the Blogger system seems to want to add breaks each and every time I place a carriage return in pure HTML - bizarre and annoying in equal measure.

    Labels: , , , ,