Saturday, June 14, 2008

Google app-engine opens for all

Google app-engine opened a while back for a limited number of developers, now however they have silently opened for everyone

So now all i have to do is find a good idea to test it out, and learn Phyton ofcourse.

Automatic single sign in for web applications

While OpenID and probably other emerging technologies are good, they don't really solve the problem i have when developing applications for my employers customers.

Firstly the sign in isn't really automatic, and its not transparent. Having multiple identity providers makes no since in this scenario. This makes the sign in process easier as we know what identity server we will use.

What the new OpenID specs seems to focus a lot on, is delivering profile data from the identity provider to the website. There is a lot of research and work on standards in this field. The reason behind this is the trust issue, identity providers can't trust the website.
However when we want a single sign in on several websites, we do trust all the sites, and the user trusts the sites more than a identity provider.

I guess our problem is a lot more simple than the problems OpenId is trying to solve. All we want is that users signing in on one site, is automatically signed in when they visit one of our other sites.
Since we control all the databases we can easily share profile data with propitiatory web-services.

So the problem really comes down to setting cookies on several domains. This can be done with redirects and images.

Tuesday, June 3, 2008

MVC and OpenId

I've read a lot about mvc and openid the last months, but i haven't had the time to use it for anything yet. One of the problems with mvc as i saw it, was the dependence on the url routing module. IIS 5 and 6 don't like modules in .net, i've tried som ways to get around it, but couldn't make it good enough.

Since the routing module workes without filename extensions i assumed that it wouldn't work. I was wrong however. Just by adding a ".mvc" to the controller names, everything workes fine.

The next step was adding openid. I've been looking for better ways to log in and authenicate users on the web a long time. And openid seemes like nice system. Anyone can use it, there are many id providers, the authenication method is not on your site and even microsoft and google seems to like it.

First part getting and installing mvc preview 3 was easy. Getting it to work with iis5 wasn't as hard as i tougth.

Gave the aspnet and iusr users access to my project folder

chaged the routing to "{controller}.mvc".

           routes.MapRoute("Default", "{controller}.mvc/{action}/{id}",
               new { controller = "Home", action = "Index", id = "" }
           );

And all references to "~/*" to "~/*.mvc".

The Dotnetopenid library has an mvc sample, so maybe the task at hand wasn't that hard afterall.

added this to my config.web

<authentication mode="Forms"><forms defaultUrl="~/Home.mvc" loginUrl="~/User.mvc/Login"/></authentication>

Added the userconrtoller and views/user from the sample

To make the usercontroller work with preview 3 i had to change the "void" to "ActionResult", and change the "RenderView" to "return View("Login");" instead of the old syntax.

       public ActionResult Index()
       {
           if (!User.Identity.IsAuthenticated) Response.Redirect("~/User.mvc/Login?ReturnUrl=Index");
           return View("Index");
       }

This is everything i did to make it work, now i can log in with any of my openid accounts.

In my opinion openid by itsself isn't that usefull, the openid provider needs to give us some more information, like email and nickname the very least. The openid has two ways to do this (or dotnetopenid), we got simple registration extension and attribute exchange.

I couldn't get attribute exchange to work, maybe my providers didn't support it, or i used the api wrong.

I did manage to get som info from the myopenid.org provider with simple registration, but the blogger openid didn't want to share anything.

I'm not sure if this is the current weakness in openid, that these protocols aren't that strandarized and supported yet. I'll do some more research on this soon.

to send request for simple registration fields and recive them i changed the usercontroller.authenitcate() method a bit.

               var openid = new OpenIdRelyingParty();
 
               IAuthenticationRequest authReq = openid.CreateRequest(Request.Form["openid_identifier"]);
               ClaimsRequest fetch = new ClaimsRequest();
               fetch.Email = DemandLevel.Request;
               fetch.Nickname = DemandLevel.Request;
               fetch.TimeZone = DemandLevel.Request;
               authReq.AddExtension(fetch);
               authReq.RedirectToProvider();

requests the email,nickname and timezone data

                       ClaimsResponse fetch = openid.Response.GetExtension(typeof(ClaimsResponse)) as ClaimsResponse;
                       if (fetch != null)
                       {
                           string email = fetch.Email;
                           string nickname = fetch.Nickname;
                           string time = fetch.TimeZone;
                       }

extracts the data from the response

So what now? we have a mvc site that we can login with openID. We need a authenication and autorsation framework for our pages, so we don't have to write the same code and checks on every controller action. http://blog.wekeroad.com/ has an excelent atricle on using .net attributes in the code to regulate access to controller actions. It was really easy to get working too, all i did was copy the code for RequiresAuthenticationAttribute and decorate the actions that required an authenicatied user.

       [RequiresAuthentication]
       public ActionResult ShowSecretData()
       {
           ViewData["Title"] = "Personal information";
 
           return View();
       }
Brilliant!

links:

dotnetopenid http://code.google.com/p/dotnetopenid/ (you'll find links to all the specs here too)