Single Sign On (SSO) Implementation in ASP.NET MVC

What is Single Sign On (SSO)?

To access any secured page in a web application, the user needs to authenticate and if the user want to access multiple web applications then the user has to login for each of those applications individually. Logging in multiple times can be eliminated with Single Sign On i.e. user has to login only once and can access web multiple applications.

<machineKey validationKey="<MachineKey>"
                decryptionKey="<DecryptionKey>" validation="<CryptoAlgorithm>" decryption="<CryptoAlgorithm>" />
    <authentication mode="Forms">
      <forms name="SingleSignOn" loginUrl="<SSOLoginURL>" timeout="480" slidingExpiration="true">
       </forms>
    </authentication>

How to enable Single Sign On?


The key for enabling Single Sign On is machineKey and authentication (forms). All the Web Applications should have the same configuration to make it work.

How to implement Single Sign On in ASP.NET MVC?

Implementing SSO in ASP.NET MVC is very simple. Below is the step by step approach to implement it.
1. Open visual studio, create a blank solution (I always like to start off with a blank solution).


2. Now add three empty ASP.NET MVC Web Applications (SSO, WebApp-1 &WebApp-2) to the solution with MVC template, Add folder and core references for MVC & No Authentication.




3. The solution should look something like below.

4. Add an AccountController in SSO, this should contain the code for login and Write some simple forms authentication code like the below in the AccountController. For the demo purpose I am using FormsAuthentication.Authenticate method which will simple check the credentials stored in web.config and authenticates if username and the password are valid, you can also validate username and password stored in sql sever database.

using System.Web.Mvc;
using System.Web.Security;
namespace SSO.Controllers
{
    public class AccountController : Controller
    {
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            if (Request.IsAuthenticated)
            {
                return RedirectToAction("Index", "Home");
            }

            ViewBag.ReturnUrl = returnUrl;
            return View();
        }

        [AllowAnonymous]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(string username, string password, string returnUrl)
        {
            //Convert your password into hash for web.config file
            //string ns = FormsAuthentication.HashPasswordForStoringInConfigFile("saurabh",                       "SHA1");

            if (FormsAuthentication.Authenticate(username, password))
            {
                FormsAuthentication.SetAuthCookie(username, false);
                if (!string.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login details");
                ViewBag.ReturnUrl = returnUrl;
                return View();
            }
        }
    }
}

5. Now we need to add a cshtml page as Login.cshtml in the Views/Account folder for the users to login and replace code with below one.

@{
    ViewBag.Title = "Login";
}

<div class="jumbotron">
    <h3>SSO Implementation Login page</h3>
</div>
<div class="row">
    <div class="text-center">
        @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
        {
            @Html.ValidationSummary()
            @Html.AntiForgeryToken()
            <div class="form-group">
                @Html.Label("Username")
                @Html.Editor("UserName")
            </div>
            <div class="form-group">
                @Html.LabelForModel("Password")
                @Html.Password("Password")
            </div>
            <input class="btn btn-primary" type="submit" value="Login" />
        }
    </div>

</div>


6. Add machineKey to web.config of SSO, WebApp-1 and WebApp-2. You can create your own machine keys by IIS and change accordingly

<system.web>
    <machineKey validationKey="04B98522FF5F0A5C92DF13E3DF412226AA29378F7E2564CAA6BFF4C4676CAFF04F4994BBAB86E78013C9C42BE5769986E28763164B5D5787D04D6D9888262E80"
                decryptionKey="691FA8AEE1BA7EEF3AAD7D59DAEAFCBD672B51F344C55013" validation="HMACSHA256" decryption="AES" />
    <authentication mode="Forms">
      <forms name="SingleSignOn" loginUrl="http://localhost:59019/Views/Account/Login" timeout="20" slidingExpiration="true">
        <credentials passwordFormat="SHA1">
          <user name="saurabh" password="BCD7ED50B563770CA2428EF4D00B0EB1D7EF83B8"/>
        </credentials>
      </forms>

    </authentication>

 

Use below code to get hash password:

//Convert your password into hash for web.config file

            //string ns = FormsAuthentication.HashPasswordForStoringInConfigFile("saurabh", "SHA1");


See below screen shot to change machine keys




Unchecked automatically generate at runtime checkbox , Make selection accordingly and click on Generate Keys button seeing in right panel. After click you will get new validation key and decryption key.


7. Change default route of SSO aplication

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace SSO
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
            );
        }
    }

}

 

8. Add Index view for the HomeController in both WebApp-1 and WebApp-2 respectively.
And replace code accordingly.
WebApp-1/Home/Index.cshtml

@{
    ViewBag.Title = "Home Page";
}

<div class="jumbotron">
    <h1>My WebApp-1</h1>
</div>

<div class="row">
    <div class="text-center">
        User is authenticated successfully & logged in as <b>@User.Identity.Name</b>
    </div>
</div>
WebApp-2/Home/Index.cshtml
@{
    ViewBag.Title = "Home Page";
}

<div class="jumbotron">
    <h1>WebApp-2</h1>
</div>

<div class="row">
    <div class="text-center">
        User is authenticated successfully & logged in as <b>@User.Identity.Name</b>
    </div>
</div>

8. Now make SSO set as StartUp Project and run application and login.


Use below credentials and open all three web application , After loggedIn with SSO , another two will automatically loggedIn.

    UserName : saurabh,

    Password : Saurabh 





Comments

Popular posts from this blog

Setup Angular 4.2.4 with Visual studio 2015 And Run by Using F5