使用 Owin + OAuth + Google 在 ExternalLogin 上从 HTTP 重定向到 HTTPS
Redirect from HTTP to HTTPS on ExternalLogin with Owin + OAuth + Google
我的应用程序托管使用 ARR 将所有页面重定向到 HTTPS。
问题在于它的配置方式,ASP.Net MVC 理解请求是 HTTP,甚至是 HTTPS。
当我检查进入 google 身份验证的 URL 时,它是这样的:
&redirect_uri=http%3A%2F%mydomain.com\signing-google
我正在尝试重定向到 google 并将 "manually" 更改为 HTTPS。
我试过这个:
public class ChallengeResult : HttpUnauthorizedResult
{
...
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
properties.Dictionary[XsrfKey] = UserId;
var owin = context.HttpContext.GetOwinContext();
owin.Request.Scheme = "https"; //hotfix
owin.Authentication.Challenge(properties, LoginProvider);
}
}
还有这个:
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = Secrets.GoogleClientId,
ClientSecret = Secrets.GoogleClientSecret,
Provider = new GoogleOAuth2AuthenticationProvider()
{
OnApplyRedirect = async context =>
{
string redirect = context.RedirectUri;
redirect = redirect.Replace("redirect_uri=http", "redirect_uri=https");
context.Response.Redirect(redirect);
}
}
});
这两种方式都很有效,google 可以再次重定向到我的应用程序,但是,当我尝试获取 loginInfo
时,数据为空。
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
if (string.IsNullOrEmpty(returnUrl))
returnUrl = "~/";
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
//always return null, if I change from HTTP to HTTPS manually
}
我试图查看 GetExternalLoginInfoAsync()
实现,但没有找到,因为当我执行此解决方法时它总是 return null。
在您的 Google 开发者控制台中,您配置了 "Authorized redirect URIs."
您的 URI 应该是“https://[您的域]/signin-google”
如果不是 https,您的站点可能会丢失从 Google 传回的凭据信息,因为您在 AccountController ExternalLoginCallback 代码 运行 之前重定向到 https。
在查看同一问题的不同变体后,我找到了解决方案,至少在我的特定情况下是这样。
MVC 托管在带有负载均衡器的 AWS EB 上。
public void ConfigureAuth(IAppBuilder app)
{
app.Use((ctx, next) =>
{
ctx.Request.Scheme = "https";
return next();
});
// your other middleware configuration
// app.UseFacebookAuthentication();
// app.UseGoogleAuthentication();
// other providers
}
我将 Use() 函数放在所有其他配置之前,可能只需要将它放在 OAuth 提供程序配置之上。
我的猜测是直接操纵 redirect_uri
导致回调数据的签名出现问题。
我的应用程序托管使用 ARR 将所有页面重定向到 HTTPS。
问题在于它的配置方式,ASP.Net MVC 理解请求是 HTTP,甚至是 HTTPS。
当我检查进入 google 身份验证的 URL 时,它是这样的:
&redirect_uri=http%3A%2F%mydomain.com\signing-google
我正在尝试重定向到 google 并将 "manually" 更改为 HTTPS。
我试过这个:
public class ChallengeResult : HttpUnauthorizedResult
{
...
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties { RedirectUri = RedirectUri };
if (UserId != null)
properties.Dictionary[XsrfKey] = UserId;
var owin = context.HttpContext.GetOwinContext();
owin.Request.Scheme = "https"; //hotfix
owin.Authentication.Challenge(properties, LoginProvider);
}
}
还有这个:
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = Secrets.GoogleClientId,
ClientSecret = Secrets.GoogleClientSecret,
Provider = new GoogleOAuth2AuthenticationProvider()
{
OnApplyRedirect = async context =>
{
string redirect = context.RedirectUri;
redirect = redirect.Replace("redirect_uri=http", "redirect_uri=https");
context.Response.Redirect(redirect);
}
}
});
这两种方式都很有效,google 可以再次重定向到我的应用程序,但是,当我尝试获取 loginInfo
时,数据为空。
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
if (string.IsNullOrEmpty(returnUrl))
returnUrl = "~/";
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
//always return null, if I change from HTTP to HTTPS manually
}
我试图查看 GetExternalLoginInfoAsync()
实现,但没有找到,因为当我执行此解决方法时它总是 return null。
在您的 Google 开发者控制台中,您配置了 "Authorized redirect URIs."
您的 URI 应该是“https://[您的域]/signin-google”
如果不是 https,您的站点可能会丢失从 Google 传回的凭据信息,因为您在 AccountController ExternalLoginCallback 代码 运行 之前重定向到 https。
在查看同一问题的不同变体后,我找到了解决方案,至少在我的特定情况下是这样。
MVC 托管在带有负载均衡器的 AWS EB 上。
public void ConfigureAuth(IAppBuilder app)
{
app.Use((ctx, next) =>
{
ctx.Request.Scheme = "https";
return next();
});
// your other middleware configuration
// app.UseFacebookAuthentication();
// app.UseGoogleAuthentication();
// other providers
}
我将 Use() 函数放在所有其他配置之前,可能只需要将它放在 OAuth 提供程序配置之上。
我的猜测是直接操纵 redirect_uri
导致回调数据的签名出现问题。