When you want to have your site support login from other services like Google, Facebook, or Microsoft, you use the Owin libraries. The base MVC template sets all this up for you, but it also has a lot of stuff that your site probably already has, like login and a user database and whatnot.
So, what’s the minimum amount of code you need to add to handle the extra login sources. You need two things: a class to initialize Owin and an MVC controller to handle the login redirect and the login response from the external site.
This is the class to initialize Owin:
Imports Microsoft.Owin Imports Microsoft.Owin.Security Imports Owin.Security.Providers ' Nuget Packages needed: ' Owin ' Microsoft.Owin ' Microsoft.Owin.Security ' Microsoft.Owin.Security.Coookies ' Microsoft.Owin.Host.SystemWeb ' Microsoft.Owin.Security.Facebook (for FB Login) ' Microsoft.Owin.Security.Google (for Google Login) ' Microsoft.Owin.Security.MicrosoftAccount (for MS Login) ' Owin.Security.Providers (for many other Logins) <Assembly: Microsoft.Owin.OwinStartup(GetType(Startup))> Public Class Startup Public Sub Configuration(app As Owin.IAppBuilder) Dim opt As Cookies.CookieAuthenticationOptions opt = New Cookies.CookieAuthenticationOptions With {.LoginPath = New PathString("/Account/Login")} Owin.CookieAuthenticationExtensions.UseCookieAuthentication(app, opt) AppBuilderSecurityExtensions.SetDefaultSignInAsAuthenticationType(app, opt.AuthenticationType) ' Google - Signup https://developers.google.com Owin.GoogleAuthenticationExtensions.UseGoogleAuthentication(app, New Google.GoogleOAuth2AuthenticationOptions With {.ClientId = "", .ClientSecret = ""}) ' Facebook - Signup https://developers.facebook.com/ Owin.FacebookAuthenticationExtensions.UseFacebookAuthentication(app, New Facebook.FacebookAuthenticationOptions With {.AppId = "", .AppSecret = ""}) ' Microsoft - Signup https://account.live.com/developers/applications/index (RedirectURL in app settings must be http://domain.com/signin-microsoft) Owin.MicrosoftAccountAuthenticationExtensions.UseMicrosoftAccountAuthentication(app, New MicrosoftAccount.MicrosoftAccountAuthenticationOptions With {.ClientId = "", .ClientSecret = ""}) ' Yahoo - Signup http://developer.yahoo.com (not working; 401 errors) Yahoo.YahooAuthenticationExtensions.UseYahooAuthentication(app, New Yahoo.YahooAuthenticationOptions With {.ConsumerKey = "", .ConsumerSecret = ""}) ' Flickr - Signup https://www.flickr.com/services/api/keys/ Flickr.FlickrAuthenticationExtensions.UseFlickrAuthentication(app, New Flickr.FlickrAuthenticationOptions With {.AppKey = "", .AppSecret = ""}) End Sub End Class
And this is the controller class to manage the logins:
Imports System.Web.Mvc Namespace Controllers Public Class OwinController Inherits Controller Function Login(provider As String, returnURL As String) As ActionResult Return New ChallengeResult(provider, Url.Action("Callback", "Owin", New With {.ReturnURL = returnURL})) End Function Function Callback(returnURL As String) Dim userID As String Dim email As String ' capture credentials With DirectCast(My.User.CurrentPrincipal.Identity, Security.Claims.ClaimsIdentity) userID = .Claims.Where(Function(x) x.Type.EndsWith("/nameidentifier")).DefaultIfEmpty(New Security.Claims.Claim("", "")).First.Value email = .Claims.Where(Function(x) x.Type.EndsWith("/emailaddress")).DefaultIfEmpty(New Security.Claims.Claim("", "")).First.Value End With Debug.WriteLine(My.User.CurrentPrincipal.Identity.Name) Return New RedirectResult(returnURL) End Function Private Class ChallengeResult Inherits HttpUnauthorizedResult Public Property LoginProvider As String Public Property RedirectURL As String Public Sub New(provider As String, url As String) Me.LoginProvider = provider Me.RedirectURL = url End Sub Public Overrides Sub ExecuteResult(context As ControllerContext) Dim prop As New Microsoft.Owin.Security.AuthenticationProperties With {.RedirectUri = Me.RedirectURL} context.HttpContext.GetOwinContext.Authentication.Challenge(prop, Me.LoginProvider) End Sub End Class End Class End Namespace
The Callback method in the OwinController is where you would look up the user by their provider/nameidentifier combination or store that info in an existing logged-in user profile or create a new user profile for the new login.
When you want to offer external logins, you call the Owin controller:
@Html.ActionLink("Google Login", "Login", "Owin", New With {.Provider = "Google", .ReturnURL = Url.Action("Secure")}, Nothing) <br /> @Html.ActionLink("Facebook Login", "Login", "Owin", New With {.Provider = "Facebook", .ReturnURL = Url.Action("Secure")}, Nothing) <br /> @Html.ActionLink("Yahoo Login", "Login", "Owin", New With {.Provider = "Yahoo", .ReturnURL = Url.Action("Secure")}, Nothing) <br /> @Html.ActionLink("Flickr Login", "Login", "Owin", New With {.Provider = "Flickr", .ReturnURL = Url.Action("Secure")}, Nothing) <br /> @Html.ActionLink("Microsoft Login", "Login", "Owin", New With {.Provider = "Microsoft", .ReturnURL = Url.Action("Secure")}, Nothing)
This assumes there is an action named “Secure” that you want to come back to.