ASP.NET身份OWIN中间件Google OAuth2 AuthenticationManager SignIn无法正常工作

Osc*_*rin 3 c# asp.net asp.net-mvc asp.net-mvc-4

我创建了一个简单的ASP.NET MVC4网站来测试新的OWIN身份验证中间件,我决定从谷歌OAuth2开始,我已经在配置方面做了很多努力,但我已经设法让谷歌授权用户,我现在面临的问题是OWIN没有对用户进行身份验证.

我想我在网络配置中有适当的设置

<system.web>
     <authentication mode="None" />
</system.web>
<system.webServer>
     <modules>
        <remove name="FormsAuthenticationModule" />
     </modules>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

然后我在Startup类中有一个非常简单的配置

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
        // Enable the External Sign In Cookie.
        app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ExternalCookie);
        // Enable Google authentication.
        app.UseGoogleAuthentication(GetGoogleOptions());
    }

    private static GoogleOAuth2AuthenticationOptions GetGoogleOptions()
    {
        var reader = new KeyReader();
        var keys = reader.GetKey("google");
        var options = new GoogleOAuth2AuthenticationOptions()
        {
            ClientId = keys.Public,
            ClientSecret = keys.Private
        };
        return options;
    }
}
Run Code Online (Sandbox Code Playgroud)

AccountController我已经按照以下方式对动作进行编码,这又是非常简单但它应该有效.

[AllowAnonymous, HttpPost, ValidateAntiForgeryToken]
    public ActionResult ExternalLogin(string provider, string returnUrl)
    {
        return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
    }

    [AllowAnonymous, HttpGet]
    public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null || !loginInfo.ExternalIdentity.IsAuthenticated)
        {
            return RedirectToAction("Login");
        }

        var identity = new ClaimsIdentity(new[] {
            new Claim(ClaimTypes.Name, loginInfo.DefaultUserName),
            new Claim(ClaimTypes.Email, loginInfo.Email)
        }, DefaultAuthenticationTypes.ExternalCookie);

        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

        AuthenticationManager.SignIn(new AuthenticationProperties
                {
                    IsPersistent = false
                }, identity);

        return RedirectToLocal(returnUrl);
    }
Run Code Online (Sandbox Code Playgroud)

我遇到的主要问题是AuthenticationManager.SignIn,当用户被重定向到我拥有以下代码的主页时,即使Google正在授予对请求的访问权限,对方法的调用似乎也没有做任何事情.

@using Microsoft.AspNet.Identity
@{
    Layout = "~/Views/Shared/_Main.cshtml";
}
<h2>Welcome</h2>
@{
    if (Request.IsAuthenticated)
    {
        <p>Welcome @User.Identity.GetUserName()</p>
    }
    else
    {
        @Html.ActionLink("Login", "Login", "Account") 
    }
}
Run Code Online (Sandbox Code Playgroud)

价值Request.IsAuthenticated总是假的,任何人都知道我在这里错过了什么?从我在网上看到的这应该是有效的.

我在我的浏览器和其他Google OAuth样本中启用了Cookie,这些样本依赖于UserManager课堂作业,但是这个简单的实现我没有工作

Osc*_*rin 6

在网上阅读了无数个小时的答案后,我决定调试OWIN源代码以找到解决这个问题的方法,而调试会话我在AuthenticationHandler课堂上遇到了这个宝石

if (BaseOptions.AuthenticationMode == AuthenticationMode.Active)
        {
            AuthenticationTicket ticket = await AuthenticateAsync();
            if (ticket != null && ticket.Identity != null)
            {
                Helper.AddUserIdentity(ticket.Identity);
            }
        }
Run Code Online (Sandbox Code Playgroud)

在我的原始Startup课程中,我使用此方法启用外部登录cookie

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
Run Code Online (Sandbox Code Playgroud)

这个方法使用了一个默认CookieAuthenticationOptions实例,AuthenticationMode = AuthenticationMode.Passive这样就阻止了类读取存储在cookie中的信息,这样每个新请求上OwinContext都没有加载经过身份验证的身份,结果就是Request.IsAuthenticated

在我意识到这一点后,我所做的就是改变app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);这一点

app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationMode = AuthenticationMode.Passive,
                AuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
                ExpireTimeSpan = TimeSpan.FromMinutes(30)
            });
Run Code Online (Sandbox Code Playgroud)

一切都很美妙


Mit*_*nik 6

我遇到了同样的问题,但我需要做的就是在Google开发者控制台中将"Google + API"添加到我的APIS列表中.之后,一切正常.