需要帮助解决 redirect_uri_mismatch 错误
Need help resolving redirect_uri_mismatch error
我在 ASP.NET MVC 5 网站上使用 Google/Facebook/LinkedIn 身份验证。出于某种原因,每隔一段时间,一些用户抱怨无法登录,因为他们收到 redirect_uri_mismatch 错误。
正如我所说,奇怪的是错误似乎间歇性地发生并且只发生在某些用户身上。我在下面包含了我的代码,以便您指出我做错了什么。
这是Startup.cs文件代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Web;
using Owin;
using Owin.Security.Providers.LinkedIn;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;
namespace myWebSite
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Set up app to use cookies for authentication
var cookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieSecure = CookieSecureOption.SameAsRequest,
ExpireTimeSpan = TimeSpan.FromMinutes(60),
SlidingExpiration = true,
LoginPath = new Microsoft.Owin.PathString("/Account/Login")
};
app.UseCookieAuthentication(cookieOptions);
// Set up external authentication
var externalCookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = "ExternalCookie",
CookieSecure = CookieSecureOption.SameAsRequest,
ExpireTimeSpan = TimeSpan.FromMinutes(10),
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
CookieManager = new Helpers.SystemWebCookieManager()
};
app.UseCookieAuthentication(externalCookieOptions);
#region Facebook Authentication
var fbOptions = new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
AppId = "myFacebookAppIdGoesHere",
AppSecret = "myFacebookAppSecretGoesHere",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async ctx =>
{
var token = ctx.AccessToken;
var id = ctx.Id;
var firstName = ctx.User["first_name"];
var middleName = ctx.User["middle_name"];
var lastName = ctx.User["last_name"];
var gender = ctx.User["gender"];
var birthday = ctx.User["birthday"];
var email = ctx.User["email"];
var username = ctx.User["username"];
ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "1", ClaimValueTypes.String, "Facebook"));
if (id != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (firstName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (middleName != null)
{
ctx.Identity.AddClaim(new Claim("urn:facebook:middle_name", middleName.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (lastName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (gender != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (birthday != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (email != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Facebook"));
}
ctx.Identity.AddClaim(new Claim("fb.token", token));
},
OnReturnEndpoint = async ctx =>
{
if (ctx.Identity == null)
{
// User is not authenticated
throw new HttpException(403, "Unable to authenticate with Facebook...");
}
else
{
if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
{
ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
}
}
}
}
};
fbOptions.Scope.Add("user_birthday");
fbOptions.Scope.Add("email");
app.UseFacebookAuthentication(fbOptions);
#endregion
#region Google Authentication
var googleOptions = new GoogleOAuth2AuthenticationOptions
{
AuthenticationType = "Google",
ClientId = "myGoogleClientIdGoesHere",
ClientSecret = "myGoogleClientSecretGoesHere",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = async ctx =>
{
var token = ctx.AccessToken;
var id = ctx.Id;
var firstName = ctx.GivenName;
var middleName = ctx.User["middle_name"];
var lastName = ctx.FamilyName;
var gender = ctx.User["gender"];
var birthday = ctx.User["birthday"];
var email = ctx.Email;
var username = ctx.User["username"];
ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "3", ClaimValueTypes.String, "Google"));
if (id != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Google"));
}
if (firstName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Google"));
}
if (middleName != null)
{
ctx.Identity.AddClaim(new Claim("urn:google:middle_name", middleName.ToString(), ClaimValueTypes.String, "Google"));
}
if (lastName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Google"));
}
if (gender != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Google"));
}
if (birthday != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Google"));
}
if (email != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Google"));
}
ctx.Identity.AddClaim(new Claim("google.token", token));
},
OnReturnEndpoint = async ctx =>
{
if (ctx.Identity == null)
{
// User is not authenticated
throw new HttpException(403, "Unable to authenticate with Google...");
}
else
{
if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
{
ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
}
}
}
}
};
googleOptions.Scope.Add("openid");
googleOptions.Scope.Add("email");
googleOptions.Scope.Add("profile");
app.UseGoogleAuthentication(googleOptions);
#endregion
#region LinkedIn Authentication
var linkedInOptions = new LinkedInAuthenticationOptions
{
AuthenticationType = "LinkedIn",
ClientId = "myLinkedInClientIdGoesHere",
ClientSecret = "myLinkedInClientSecretGoesHere",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new LinkedInAuthenticationProvider
{
OnAuthenticated = async ctx =>
{
var token = ctx.AccessToken;
var id = ctx.Id;
var firstName = ctx.User["first_name"];
var middleName = ctx.User["middle_name"];
var lastName = ctx.User["last_name"];
var gender = ctx.User["gender"];
var birthday = ctx.User["birthday"];
var email = ctx.Email;
var username = ctx.User["username"];
ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "4", ClaimValueTypes.String, "LinkedIn"));
if (id != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (firstName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (middleName != null)
{
ctx.Identity.AddClaim(new Claim("urn:linkedin:middle_name", middleName.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (lastName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (gender != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (birthday != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (email != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
ctx.Identity.AddClaim(new Claim("linkedin.token", token));
},
OnReturnEndpoint = async ctx =>
{
if (ctx.Identity == null)
{
// User is not authenticated
throw new HttpException(403, "Unable to authenticate with LinkedIn...");
}
else
{
if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
{
ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
}
}
}
}
};
app.UseLinkedInAuthentication(linkedInOptions);
#endregion
}
}
}
在我的 Google、Facebook 和 LinkedIn 设置中,我只有 http://www.yourdomain.com/signin-{socialsite} as the redirect uri. When I also added http://yourdomain.com/signin-{socialsite},它解决了这个问题。如果您遇到此问题,请确保您的 return uri 带有和不带 "www".
我在 ASP.NET MVC 5 网站上使用 Google/Facebook/LinkedIn 身份验证。出于某种原因,每隔一段时间,一些用户抱怨无法登录,因为他们收到 redirect_uri_mismatch 错误。
正如我所说,奇怪的是错误似乎间歇性地发生并且只发生在某些用户身上。我在下面包含了我的代码,以便您指出我做错了什么。
这是Startup.cs文件代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Web;
using Owin;
using Owin.Security.Providers.LinkedIn;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;
namespace myWebSite
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Set up app to use cookies for authentication
var cookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieSecure = CookieSecureOption.SameAsRequest,
ExpireTimeSpan = TimeSpan.FromMinutes(60),
SlidingExpiration = true,
LoginPath = new Microsoft.Owin.PathString("/Account/Login")
};
app.UseCookieAuthentication(cookieOptions);
// Set up external authentication
var externalCookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = "ExternalCookie",
CookieSecure = CookieSecureOption.SameAsRequest,
ExpireTimeSpan = TimeSpan.FromMinutes(10),
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
CookieManager = new Helpers.SystemWebCookieManager()
};
app.UseCookieAuthentication(externalCookieOptions);
#region Facebook Authentication
var fbOptions = new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
AppId = "myFacebookAppIdGoesHere",
AppSecret = "myFacebookAppSecretGoesHere",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = async ctx =>
{
var token = ctx.AccessToken;
var id = ctx.Id;
var firstName = ctx.User["first_name"];
var middleName = ctx.User["middle_name"];
var lastName = ctx.User["last_name"];
var gender = ctx.User["gender"];
var birthday = ctx.User["birthday"];
var email = ctx.User["email"];
var username = ctx.User["username"];
ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "1", ClaimValueTypes.String, "Facebook"));
if (id != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (firstName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (middleName != null)
{
ctx.Identity.AddClaim(new Claim("urn:facebook:middle_name", middleName.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (lastName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (gender != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (birthday != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Facebook"));
}
if (email != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Facebook"));
}
ctx.Identity.AddClaim(new Claim("fb.token", token));
},
OnReturnEndpoint = async ctx =>
{
if (ctx.Identity == null)
{
// User is not authenticated
throw new HttpException(403, "Unable to authenticate with Facebook...");
}
else
{
if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
{
ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
}
}
}
}
};
fbOptions.Scope.Add("user_birthday");
fbOptions.Scope.Add("email");
app.UseFacebookAuthentication(fbOptions);
#endregion
#region Google Authentication
var googleOptions = new GoogleOAuth2AuthenticationOptions
{
AuthenticationType = "Google",
ClientId = "myGoogleClientIdGoesHere",
ClientSecret = "myGoogleClientSecretGoesHere",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = async ctx =>
{
var token = ctx.AccessToken;
var id = ctx.Id;
var firstName = ctx.GivenName;
var middleName = ctx.User["middle_name"];
var lastName = ctx.FamilyName;
var gender = ctx.User["gender"];
var birthday = ctx.User["birthday"];
var email = ctx.Email;
var username = ctx.User["username"];
ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "3", ClaimValueTypes.String, "Google"));
if (id != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Google"));
}
if (firstName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Google"));
}
if (middleName != null)
{
ctx.Identity.AddClaim(new Claim("urn:google:middle_name", middleName.ToString(), ClaimValueTypes.String, "Google"));
}
if (lastName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Google"));
}
if (gender != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Google"));
}
if (birthday != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Google"));
}
if (email != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Google"));
}
ctx.Identity.AddClaim(new Claim("google.token", token));
},
OnReturnEndpoint = async ctx =>
{
if (ctx.Identity == null)
{
// User is not authenticated
throw new HttpException(403, "Unable to authenticate with Google...");
}
else
{
if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
{
ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
}
}
}
}
};
googleOptions.Scope.Add("openid");
googleOptions.Scope.Add("email");
googleOptions.Scope.Add("profile");
app.UseGoogleAuthentication(googleOptions);
#endregion
#region LinkedIn Authentication
var linkedInOptions = new LinkedInAuthenticationOptions
{
AuthenticationType = "LinkedIn",
ClientId = "myLinkedInClientIdGoesHere",
ClientSecret = "myLinkedInClientSecretGoesHere",
SignInAsAuthenticationType = "ExternalCookie",
Provider = new LinkedInAuthenticationProvider
{
OnAuthenticated = async ctx =>
{
var token = ctx.AccessToken;
var id = ctx.Id;
var firstName = ctx.User["first_name"];
var middleName = ctx.User["middle_name"];
var lastName = ctx.User["last_name"];
var gender = ctx.User["gender"];
var birthday = ctx.User["birthday"];
var email = ctx.Email;
var username = ctx.User["username"];
ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "4", ClaimValueTypes.String, "LinkedIn"));
if (id != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (firstName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (middleName != null)
{
ctx.Identity.AddClaim(new Claim("urn:linkedin:middle_name", middleName.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (lastName != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (gender != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (birthday != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
if (email != null)
{
ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "LinkedIn"));
}
ctx.Identity.AddClaim(new Claim("linkedin.token", token));
},
OnReturnEndpoint = async ctx =>
{
if (ctx.Identity == null)
{
// User is not authenticated
throw new HttpException(403, "Unable to authenticate with LinkedIn...");
}
else
{
if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
{
ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
}
}
}
}
};
app.UseLinkedInAuthentication(linkedInOptions);
#endregion
}
}
}
在我的 Google、Facebook 和 LinkedIn 设置中,我只有 http://www.yourdomain.com/signin-{socialsite} as the redirect uri. When I also added http://yourdomain.com/signin-{socialsite},它解决了这个问题。如果您遇到此问题,请确保您的 return uri 带有和不带 "www".