Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
490 views
in Technique[技术] by (71.8m points)

asp.net mvc 4 - GoogleOauth2 Issue Getting Internal Server 500 error

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();
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
    }
}
  • callbacks/google seems to handled by OWIN
  • callbacks/googlereturn seems to handled by MVC

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...