I decided to give the new Google Oauth2 middleware a try and it has pretty much broken everything. Here is my provider config from startup.auth.cs.. When turned on, all of the providers including the google provider get a 500 internal server on Challenge. However the details of the internal server error are not available and I cant figure out how to turn on any debugging or tracing for the Katana middleware. Seems to me like they were in a rush to get the google Oauth middleware out the door.
//// GOOGLE
var googleOptions = new GoogleOAuth2AuthenticationOptions
{
ClientId = "228",
ClientSecret = "k",
CallbackPath = new PathString("/users/epsignin")
SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = context =>
{
foreach (var x in context.User)
{
string claimType = string.Format("urn:google:{0}", x.Key);
string claimValue = x.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new Claim(claimType, claimValue, XmlSchemaString, "Google"));
}
return Task.FromResult(0);
}
}
};
app.UseGoogleAuthentication(googleOptions);
ActionMethod Code:
[AllowAnonymous]
public ActionResult ExternalProviderSignIn(string provider, string returnUrl)
{
var ctx = Request.GetOwinContext();
ctx.Authentication.Challenge(
new AuthenticationProperties
{
RedirectUri = Url.Action("EPSignIn", new { provider })
},
provider);
return new HttpUnauthorizedResult();
}
This took me hours to figure out, but the issue is the CallbackPath
as mentioned by @CrazyCoder. I realised that the CallbackPath
in public void ConfigureAuth(IAppBuilder app)
MUST be different to when it is being set in the ChallengeResult
. If they are the same a 500 error is thrown in OWIN.
My code is for ConfigureAuth(IAppBuilder app)
is
var googleOptions = new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationOptions
{
ClientId = "xxx",
ClientSecret = "yyy",
CallbackPath = new PathString("/callbacks/google"), //this is never called by MVC, but needs to be registered at your oAuth provider
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim("picture", context.User.GetValue("picture").ToString()));
context.Identity.AddClaim(new Claim("profile", context.User.GetValue("profile").ToString()));
return Task.FromResult(0);
}
}
};
googleOptions.Scope.Add("email");
app.UseGoogleAuthentication(googleOptions);
My 'callbacks' Controller code is:
// GET: /callbacks/googlereturn - callback Action
[AllowAnonymous]
public async Task<ActionResult> googlereturn()
{
return View();
}
//POST: /Account/GooglePlus
public ActionResult GooglePlus()
{
return new ChallengeResult("Google", Request.Url.GetLeftPart(UriPartial.Authority) + "/callbacks/googlereturn", null);
//Needs to be a path to an Action that will handle the oAuth Provider callback
}
private 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);
}
}
It is all working now, although would love to know exactly what is happening 'under the bonnet'
My advice, unless you have another requirement, is to let OWIN use default redirect paths and make sure you don't use them yourself.
There is no need to specify CallbackPath
in UseGoogleAuthentication
:
CallbackPath = new PathString("/Account/ExternalLoginCallback")
Just keep the Google setting for Authorized redirect URIs
as:
http(s)://yoururl:orPort/signin-google
Owin handles signin-google internally and redirects to the redirectUri as mentioned in your code for ChallengeResult class. Which is Account/ExternalLoginCallback.
Got it working vanilla from the tutorial with ONE simple change - just posting this for any nubes to this approach. I think the problems related to oauth2 in this instance are largely fleshed out in the latest templates/apis - what I mean is, if you are starting from scratch, you may be in luck - read on:
I JUST did this tutorial https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/
and referenced this also http://blogs.msdn.com/b/webdev/archive/2014/07/02/changes-to-google-oauth-2-0-and-updates-in-google-middleware-for-3-0-0-rc-release.aspx
The one change: it worked but ONLY after enabling google+ apis in the newest version of the google developer site.
(Just go to google api lib manager, sign in and search the apis directory for the google+ api).
Note: for me the Google+ api was disabled by default.
I did nothing else unique.
Cheers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With