外部身份验证后如何从用户那里收集更多信息?
How do I collect more information from a user after authenticating externally?
我正在使用 Microsoft.AspNetCore.Authentication.Google
包。如果我允许用户使用 Google 进行身份验证,我应该在哪里注入自己的表单以收集更多 Google 无法访问的信息(例如自定义标识符)。
我是否应该提供一个表单,预先收集数据并将其存储在会话中,或者在他们去授权登录时进行其他操作?
我是否应该让他们去授权登录,然后在回调 URL 被调用时,在那里显示表单?
通过中间件公开了四个事件:
OnTicketReceived
OnCreatingTicket
OnRedirectToAuthorizationEndpoint
OnRemoteFailure
有没有任何地方正在这样做的例子?我似乎找不到任何东西。
我用Cookie中间件做到了。我添加了 'temp' cookie 中间件以捕获 ClaimsPrincipal 登录到 Google,然后我登录到 'real' Cookie 中间件以保留丰富的 ClaimsPrincipal。 StartUp的Configure方法中的相关代码class:
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));
}
请注意如何通过您页面上的 link 或其他内容调用 LoginGoogle。记住此时 GoogleMiddleware 的 SignInScheme 是如何 "Temp" 的。它被重定向到 "Register" 操作方法。在那里,您使用以下代码从 Google 中提取 ClaimsPrinciple:
var externalPrincipal = await HttpContext.Authentication.AuthenticateAsync("Temp");
此时您可以对索赔做任何您需要做的事情。如您所见,我提取了电子邮件声明。我使用我的 "Cookie" 登录方案登录,以将 ClaimsPrinciple 保留在 cookie 中。但是您也可以使用您向用户请求更多信息的表单重定向到视图。
我正在使用 Microsoft.AspNetCore.Authentication.Google
包。如果我允许用户使用 Google 进行身份验证,我应该在哪里注入自己的表单以收集更多 Google 无法访问的信息(例如自定义标识符)。
我是否应该提供一个表单,预先收集数据并将其存储在会话中,或者在他们去授权登录时进行其他操作?
我是否应该让他们去授权登录,然后在回调 URL 被调用时,在那里显示表单?
通过中间件公开了四个事件:
OnTicketReceived
OnCreatingTicket
OnRedirectToAuthorizationEndpoint
OnRemoteFailure
有没有任何地方正在这样做的例子?我似乎找不到任何东西。
我用Cookie中间件做到了。我添加了 'temp' cookie 中间件以捕获 ClaimsPrincipal 登录到 Google,然后我登录到 'real' Cookie 中间件以保留丰富的 ClaimsPrincipal。 StartUp的Configure方法中的相关代码class:
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));
}
请注意如何通过您页面上的 link 或其他内容调用 LoginGoogle。记住此时 GoogleMiddleware 的 SignInScheme 是如何 "Temp" 的。它被重定向到 "Register" 操作方法。在那里,您使用以下代码从 Google 中提取 ClaimsPrinciple:
var externalPrincipal = await HttpContext.Authentication.AuthenticateAsync("Temp");
此时您可以对索赔做任何您需要做的事情。如您所见,我提取了电子邮件声明。我使用我的 "Cookie" 登录方案登录,以将 ClaimsPrinciple 保留在 cookie 中。但是您也可以使用您向用户请求更多信息的表单重定向到视图。