In Memory

The Simple Way To Keep Thoughts

I'm @sstude, I'm a software developer. This is my blog where I post (sometimes :) notes about my dev life. Follow me on Twitter and don't hesitate to ask any questions or share any interesting ideas!

Blog Projects Twitter Github

Web applications today need to restrict an access to the parts (or maybe the whole) web pages. There are many reasons for this. And from time to time we are involved to the process where we need to implement it. Any time we want to implement this in our applications we meet a lot of questions about authentication and authorisation aspects. I can recall a lot of comments that storing login/password on another website is bad, we need use all existing social networks and OpenID providers to authenticate to the websites and web applications. All sites like Google, Twitter, Facebook, Yahoo, LinkedIn etc. could be used for this.

Let's see how can we implement this in the ASP.NET MVC (WebForms also) application by using Google for this example.

First of all here is the documentation from Google about using it as a auth. provider - Federated Login for Google Account Users.

If you want your own implementation of the login process - you are welcome :) BTW, before I found the way I will describe in this post, I was looking to this implementation, that looks really good to use it - https://github.com/PureKrome/WorldDomination.Web.Authentication

MSFT went through the process and had implemented some helpers to make it really easy to use OAuth and OpenID providers in ASP.NET.

Let's start with Empty ASP.NET MVC Application.

First of all we need setup our web.config to use Forms authentication for our app.

<authentication mode="Forms">
    <forms loginUrl="~/Account/Login" timeout="300" />
</authentication>

{%img left /images/ASPNETGOOGLOGIN/controllers.png New Controllers%} Let's create several controllers next. HomeController is the default one we visit in our app. SecureController has Index action - the secret content we should be able to see only if we are authenticated. And AccountController - to handle the login process.

[Authorize]
public class SecureController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

Now, when we will go to http://localhost/Secure we will be redirected to our loginUrl from web.config.

To be able to login with Google we need to create a link in our Login.cshtml view:

<h2>Login</h2>

@Html.ActionLink("Login with Google", "ExternalLogin", "Account", new { provider = "google" }, null)

This snippet tell us that when we click to this link we go to the ExternalLogin action method and pass it the provider name, 'google' in this example.

It's time to implement the login process. To make this we need to install NuGet package first of all.

PM> Install-Package Microsoft.AspNet.WebPages.OAuth

This is the package where we can get all helpers to be able to work with OpenID and OAuth. In all the dependencies it will install you can see the DotNetOpenAuth.* assemblies. All helpers are based on these libraries, and you can find more information at http://www.dotnetopenauth.net/.

After all this done, we need to register our clients. Clients are the providers we want use in the authentication process (Google, Twitter, Facebook, Microsoft, etc.). We need to add one more line in our Global.asax Application_Start method to register Google as the client.

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    // this is what we need
    OAuthConfig.RegisterProviders();
}

And the OAuthConfig.cs:

public class OAuthConfig
{
    public static void RegisterProviders()
    {
        OAuthWebSecurity.RegisterGoogleClient(); // that's all :)
    } 
}

Time to see the ExternalLogin method code:

public void ExternalLogin(string provider)
{
    // just pass a provider to make it work
    OAuthWebSecurity.RequestAuthentication(provider, Url.Action("ExternalLoginCallback"));
}

ExternalLoginCallback is also an action inside AccountController we should implement:

public ActionResult ExternalLoginCallback()
{
    var result = OAuthWebSecurity.VerifyAuthentication();

    if (result.IsSuccessful == false)
    {
        return RedirectToAction("Error", "Account");
    }

    // this is just demo. Make all things you need before setting cookies
    FormsAuthentication.SetAuthCookie(result.UserName, false);

    // We need to get the url user has entered to the browser to use it in the redirect. 
    // This is just demo.
    return Redirect(Url.Action("Index", "Secure"));
}

OAuthWebSecurity.RequestAuthentication - this is the API to make call to our provider to login. We pass provider's name and the callback url to handle the result.

OAuthWebSecurity.VerifyAuthentication - this API validates the login and returns result from our provider. We can check the result by verivying it's IsSuccessful property.

FormsAuthentication.SetAuthCookie - in case if everything is OK, we can make all things we need to do and then write cookies to pass the authentication.

That's all. It's pretty simple and no need to deal with all these OpenID parameters commands and urls - just use the helpers and make it ease to login to your application.

Additional posts will cover some deeper cases. Stay tuned.

Read more