在外部验证后如何从用户收集更多信息?

时间:2016-07-14 21:40:42

标签: c# asp.net-core google-authentication

我正在使用Microsoft.AspNetCore.Authentication.Google包。如果我允许用​​户通过Google进行身份验证,那么我应该在哪里注入自己的表单来收集Google无法访问的更多信息(例如自定义标识符)。

  1. 我是否应该提交表格,预先收集数据并将其存储在会话或其他内容中,以便他们下去授权登录?

  2. 我应该让他们去授权登录,然后在调用回调网址时,在那里显示表单吗?

  3. 通过中间件公开了四个事件:

    1. OnTicketReceived
    2. OnCreatingTicket
    3. OnRedirectToAuthorizationEndpoint
    4. OnRemoteFailure
    5. 在任何地方都有这样的例子吗?我似乎找不到任何东西。

1 个答案:

答案 0 :(得分:3)

我用Cookie中间件完成了它。我添加了'临时'cookie中间件来抓住ClaimsPrincipal登录谷歌,然后我登录到'真正'的Cookie中间件来保持丰富的ClaimsPrincipal。 StartUp类的Configure方法中的相关代码:

        app.UseCookieAuthentication(
        new CookieAuthenticationOptions()
        {
            AuthenticationScheme = "Cookie",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            LoginPath = new PathString(@"/account/login"),
            AccessDeniedPath = new PathString(@"/account/accessdenied")
        });

    app.UseCookieAuthentication(
        new CookieAuthenticationOptions()
        {
            AuthenticationScheme = "Temp",
            AutomaticAuthenticate = false
        });

    var googleOptions = new GoogleOptions()
    {
        AuthenticationScheme = "Google",
        SignInScheme = "Temp",
        AppId = "yourappidhere",
        AppSecret = "yourappsecrethere"
    };
    googleOptions.Scope.Add("scopesyouneed");

    app.UseGoogleAuthentication(googleOptions);

请注意googleOptions的SignInScheme是“Temp”,而'temp'Cookie中间件的选项是否将AutomaticAuthenticate设置为false(因为您不希望自动将ClaimsPrinciple保存在临时Cookie中,而是丰富了所有在真正的一个叫做“Cookie”的地方)。

然后我的控制器中的相关方法如下:

    public async Task<IActionResult> Register(string returnUrl = null)
{
    var externalPrincipal = await HttpContext.Authentication.AuthenticateAsync("Temp");

    //TODO Check external principal and retrieve claims from db or whatever needs to be done here.

    var claims = new List<Claim>()
        {
            new Claim("email", externalPrincipal.FindFirst(ClaimTypes.Email).Value)
        };
    var id = new ClaimsIdentity(claims, "password");
    await HttpContext.Authentication.SignInAsync("Cookie", new ClaimsPrincipal(id));
    await HttpContext.Authentication.SignOutAsync("Temp");

    return Redirect(returnUrl);
}

public async Task<IActionResult> LogInGoogle(string returnUrl = null)
{
    var queryString = !string.IsNullOrWhiteSpace(returnUrl) ? $"?returnUrl={returnUrl}" : string.Empty;
    var props = new AuthenticationProperties() { RedirectUri = $@"Account/Register{queryString}" }; //new PathString(returnUrl)

    return await Task.Run<ChallengeResult>(() => new ChallengeResult("Google", props));

}

请注意如何通过您网页上的链接调用LoginGoogle。请记住,此时GoogleMiddleware的SignInScheme是“Temp”。它被重定向到“注册”操作方法。在那里,您使用代码

从Google中提取ClaimsPrinciple

var externalPrincipal = await HttpContext.Authentication.AuthenticateAsync(“Temp”);

此时,您可以执行索赔所需的任何操作。我可以看到,我提取了电子邮件声明。然后我使用我的“Cookie”登录方案登录,将ClaimsPrinciple保存在cookie中。但您也可以使用您向用户请求更多信息的表单重定向到视图。