Monday, 30 November 2015

ASP.Net Authentication External Login Controller Actions - Step 31

> C#/.Net Samples
> .Net Authentication
> Setting up ASP.NET Identity 2 with External Logins Facebok Google Microsoft and Twitter

Step # 31

 

For other steps follow:

Setting up ASP.NET Identity 2 with External Logins Facebook Google Microsoft and Twitter


ExternalLogin




[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult ExternalLogin(string provider, string returnUrl)
        {
            // Request a redirect to the external login provider
            var challenge = new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
            return challenge;
        }
        
        // Used for XSRF protection when adding external logins
        private const string XsrfKey = "XsrfId";
        internal class ChallengeResult : HttpUnauthorizedResult
        {
            public ChallengeResult(string provider, string redirectUri)
                : this(provider, redirectUri, null)
            {
            }
 
            public ChallengeResult(string provider, string redirectUri, string userId)
            {
                LoginProvider = provider;
                RedirectUri = redirectUri;
                UserId = userId;
            }
 
            public string LoginProvider { get; set; }
            public string RedirectUri { get; set; }
            public string UserId { get; set; }
 
            public override void ExecuteResult(ControllerContext context)
            {
                var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
                if (UserId != null)
                {
                    properties.Dictionary[XsrfKey] = UserId;
                }
                context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
            }
        }
        

External Login Call Back

 
 
        [AllowAnonymous]
        public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
        {
            var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
            if (loginInfo == null)
            {
                return RedirectToAction("Login");
            }
 
            var externalFirstName = string.Empty;
            var externalLastName = string.Empty;
 
            var email = loginInfo.Email;
            var defaultUserName = loginInfo.DefaultUserName;
 
            var externalClaims = loginInfo.ExternalIdentity.Claims;
            if (loginInfo.Login.LoginProvider.ToUpperInvariant().Equals("GOOGLE") && externalClaims != null && externalClaims.Any())
            {
                foreach (var extClaim in externalClaims)
                {
                    if (extClaim.Type.ClaimType("givenname"))
                    {
                        externalFirstName = extClaim.Value;
                    }
                    if (extClaim.Type.ClaimType("surname"))
                    {
                        externalLastName = extClaim.Value;
                    }
                }
            }
            if (loginInfo.Login.LoginProvider.ToUpperInvariant().Equals("FACEBOOK") && externalClaims != null && externalClaims.Any())
            {
                var fbIdentity = AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie).Result;
                var accessToken = fbIdentity.FindFirstValue("FacebookAccessToken");
                var fb = new FacebookClient(accessToken);
                dynamic myInfo = fb.Get("/me?fields=email,birthday,first_name,gender,last_name,location"); // specify the email field
                loginInfo.Email = myInfo.email;
                loginInfo.ExternalIdentity.AddClaim(new Claim("Givenname",myInfo.first_name));
                loginInfo.ExternalIdentity.AddClaim(new Claim("Surname", myInfo.last_name));
                loginInfo.ExternalIdentity.AddClaim(new Claim("Gender", myInfo.gender));
                loginInfo.ExternalIdentity.AddClaim(new Claim("Birthday", myInfo.birthday));
 
                externalFirstName = myInfo.first_name;
                externalLastName = myInfo.last_name;
            }
            if (loginInfo.Login.LoginProvider.ToUpperInvariant().Equals("MICROSOFT") && externalClaims != null && externalClaims.Any())
            {
                var msIdentity = await HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
                var firstNameClaim = msIdentity.Claims.FirstOrDefault(c => c.Type.EndsWith("first_name"));
                externalFirstName = firstNameClaim != null ? firstNameClaim.Value : null;
                var lastNameClaim = msIdentity.Claims.FirstOrDefault(c => c.Type.EndsWith("last_name"));
                externalLastName = lastNameClaim != null ? lastNameClaim.Value : null;
            }
 
 
            var user = await UserManager.FindAsync(loginInfo.Login);
            if (user == null)
            {
                //build default user name
                var userName = loginInfo.DefaultUserName;
                if (String.IsNullOrWhiteSpace(userName) && !String.IsNullOrWhiteSpace(externalFirstName) && !String.IsNullOrWhiteSpace(externalLastName))
                {
                    userName = String.Join("{0}{1}", externalFirstName, externalLastName);
                }
                if (String.IsNullOrWhiteSpace(userName))
                {
                    userName = loginInfo.Email.RemoveSpecialCharacters();
                }
 
                //make the user name unique
                var isUniqueUserName = false;
                var userIndex = 1;
                while (!isUniqueUserName)
                {
                    var externalUser = await UserManager.FindByNameAsync(userName);
                    if (externalUser == null)
                    {
                        isUniqueUserName = true;
                    }
                    else
                    {
                        userName += userIndex;
                    }
                    userIndex++;
                }
 
                user = new ApplicationUser
                {
                    Email = loginInfo.Email,
                    UserName = userName,
                    FirstName = externalFirstName,
                    LastName = externalLastName
                };
 
 
                //create user
                var result = await UserManager.CreateAsync(user);
                if (!result.Succeeded)
                {
                    return View("Error", result.Errors);
                }
                
                //create role
                await UserManager.AddToRoleAsync(user.Id, RoleNameContants.External);
                await UserManager.AddToRoleAsync(user.Id, RoleNameContants.Users);
 
 
                result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login);
                if (!result.Succeeded)
                {
                    return View("Error", result.Errors);
                }
            }
 
            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
            identity.AddClaims(loginInfo.ExternalIdentity.Claims);
            AuthenticationManager.SignIn(new AuthenticationProperties
            {
                IsPersistent = false
            }, identity);
            return Redirect(returnUrl ?? "/");
        }
 
 
 

Simple error view model

 
@model IEnumerable<string>
@{
    ViewBag.Title = "Error";
}
 
<h2>Error</h2>
 
@foreach (var error in Model)
{
    <p>@error/p>
}

Social Media Links

External Login Basics
Google Setup
Facebook Setup
Twitter Setup
Microsoft Setup
External Login Controller Actions