Recently I was working on a project where by I needed to authenticate out users against their Google apps login.
That is to say, the on authentication method would be Google. And only ever Google.
Most of the examples I found offered Google as an additional or supplementary authentication mechanism. I wanted it to be the only mechanism to authenticate with our application.
Also, I wanted the users to have ‘roles’ within our application – for example ‘Admin’, ‘CustomerService’ etc…
So, to summarise the requirements:
- Users will only sign in to our application with their Google Account.
- They will not have a username / password
- Once signed in, if they had an account with our application (using ASP.net Identity) authenticate, and continue as normal.
- If not, create an account (in the sense of ASP.net Identity), then authenticate the user, and continue to our application
For this to work, you’ll need a Google application to authenticate against.
I wrote a short separate post about how to do that here:
http://www.alexjamesbrown.com/blog/development/create-a-google-application-for-authenticating-against-with-asp-net-identity/
Take special note of the Google+ API requirement, and ensure your redirect URL is set appropriately to http://localhost:<port>/signin-google if testing locally
You’ll then need to configure your authentication to use the credentials provided by the above:
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions { ClientId = “xxx.apps.googleusercontent.com", ClientSecret = “xxxxxxxxxxxx", });
Most of the code in my example follows on from the usual tutorials on the subject of ASP.net Identity with Google –
We have a ExternalLoginCallback method in our AuthenticationController, which is called by Google when authenticated.
In here, we retrieve the user information. We then check if a user exists in our database.
If it does, using our SignInManager, we sign the user in, and proceed.
If we don’t have a user, we create one, with the information we have about the successful login with the third party (in this case, Google)
Apparently, if you don’t want to have the endpoint of /signin-google as shown in the post, you can change >the redirect url value in GoogleOAuth2AuthenticationOptions:
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { //clientid client secret goes here CallbackPath = “<path>” //put your path here }
Inside our AuthenticationController is where the real magic happens
I’ve commented what’s going on below;
[AllowAnonymous] public async Task<ActionResult> ExternalLoginCallback(string returnUrl) { var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); //One potentially useful thing we could do here is throw a 403 if the authenticated user //is not part of our corporate domain //if(!loginInfo.Email.EndsWith("@mydomain.com") // throw new HttpUnauthorizedResult(); //See if the user exists in our database var user = await UserManager.FindByEmailAsync(loginInfo.Email); if (user == null) { //user doesn't exist, so the user needs to be created user = new ApplicationUser { UserName = loginInfo.Email, Email = loginInfo.Email, EmailConfirmed = true, FirstName = loginInfo.ExternalIdentity.Claims.FirstOrDefault(x => x.Type.Equals(ClaimTypes.GivenName)).Value, LastName = loginInfo.ExternalIdentity.Claims.FirstOrDefault(x => x.Type.Equals(ClaimTypes.Surname)).Value }; //create the user await UserManager.CreateAsync(user); //add the google login to the newly created user await UserManager.AddLoginAsync(user.Id, loginInfo.Login); //add user to roles if required here.... } //if user logins doesn't contain Google, then add it if (!user.Logins.Any(x => x.LoginProvider.Equals("Google"))) await UserManager.AddLoginAsync(user.Id, loginInfo.Login); //successfully authenticated with google, so sign them in to our app await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); return RedirectToLocal(returnUrl); }
For a full working example, please checkout:
https://github.com/alexjamesbrown/aspnet-google-only-authentication