这里发生了一件奇怪的事情。
我已经建立了一个ASP.NET MVC5网站,并通过ASP.NET Identity使本地帐户运行良好。
我现在正在尝试启用外部身份验证,但发生了一些奇怪的事情。
我确信我已经采取了正确的步骤。我的Startup.Auth.cs:中有这个
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
// Use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Uncomment the following lines to enable logging in with third party login providers
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: "");
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
app.UseGoogleAuthentication();
}
当用户点击链接登录谷歌时,ExternalLogin方法被调用:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
我已经通过调试验证了它进入ChallengeResult类的ExecuteResult方法:
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);
}
但是,在浏览器中,什么也没发生。我只是得到一个空白页面,我希望重定向到谷歌登录页面。
没有任何错误报告。
另一件有趣的事情是,我试图创建另一个MVC5应用程序,但我在VS2013中弹出了一个"Object reference not set to a instance of a Object"(对象引用未设置为对象实例)的弹出窗口,结果项目缺少默认情况下通常存在的Account控制器。
我修复了VS2013的安装,重新安装了Update 1,还更新了解决方案中的所有Nuget包。
我已经没有下一步该去哪里的想法了。
更新1考虑到这可能与我的电脑有关,我已将网站部署到Azure,但问题仍然存在。这是否意味着它可能与丢失的程序集有关,并且没有正确报告?我运行过fusionlog,但没有发现绑定失败。
用干净的Windows8和VS2013安装一个新的虚拟机,看看我是否能在那里完成一个新项目。
更新2好的,刚刚运行了另一轮"网络"捕获,当用户选择外部提供商时,它确实会发布到ExternalLogin操作,但响应是401 Unauthorized。是什么原因造成的?
好的,
我弄清楚了问题的(重要部分)是什么。
首先,我仍然不知道为什么当我创建MVC项目时,我没有得到一个脚手架式的AccountController类。
然而,我的问题似乎是我的登录按钮通过了"谷歌"而不是"谷歌"作为提供商。
说真的!?我有点惊讶,大小写与提供商的名称有关,但你可以这样做了。
这不是你问题的答案,但它回应了一个非常相似的问题
如果你有Owin 2.0,并且你迁移到2.1
_ExternalLoginsListPartial需要从此更改:
<button type="submit" class="btn btn-default" id="@p.AuthenticationType" name="Partner" value="@p.AuthenticationType" title="Log in using your @p.Caption account">@p.AuthenticationType</button>
到这个
<button type="submit" class="btn btn-default" id="@p.AuthenticationType" name="provider" value="@p.AuthenticationType" title="Log in using your @p.Caption account">@p.AuthenticationType</button>
唯一改变的是按钮的名称,但这可能会让你像我一样头疼,并花费我2天的时间来找到问题。
也许这在新的Owin版本中得到了解释,如果不是的话,一定要用大写字母来说明。
我的ASP.Net WebAPI服务器刚刚遇到了同样的问题。我将正确的AuthenticationType传递到质询方法中,但仍然得到一个空白页。
事实证明,问题在于我在启动时将OAuth提供程序添加到OWIN管道中的顺序。大致是我的工作订单:
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
var authServerOptions = new OAuthAuthorizationServerOptions
{
...
};
// Token Generation
app.UseOAuthAuthorizationServer(authServerOptions);
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
// Configure Google External Login
GoogleAuthOptions = new GoogleOAuth2AuthenticationOptions()
{
ClientId = xxxx,
ClientSecret = xxxx,
Provider = new GoogleAuthProvider()
};
app.UseGoogleAuthentication(GoogleAuthOptions);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
之前我在UseGoogleAuthentication方法之前添加了UseCors+UseWebApi方法。
我发现这篇文章也很有用:http://coding.abel.nu/2014/06/understanding-the-owin-external-authentication-pipeline/