Próbuję uaktualnić moją witrynę MVC, aby korzystać z nowego standardu OpenID Connect. Warstwa pośrednia OWIN wydaje się być dość solidna, ale niestety obsługuje tylko typ odpowiedzi "form_post" . Oznacza to, że Google nie jest kompatybilny, ponieważ zwraca wszystkie tokeny w adresie URL po "#", więc nigdy nie docierają do serwera i nigdy nie uruchamiają oprogramowania pośredniego.Sprawdzanie poprawności identyfikatora Google OpenID Connect Identyfikator JWT
Próbowałem wywołać procedury obsługi odpowiedzi w oprogramowaniu pośredniczącym, ale to w ogóle nie działa, więc mam prosty plik javascript, który analizuje zwrócone żądania i POST je do kontrolera akcja do przetworzenia.
Problem polega na tym, że nawet jeśli dostaję je po stronie serwera, nie mogę ich poprawnie przeanalizować. Błąd pojawia wygląda następująco:
IDX10500: Signature validation failed. Unable to resolve
SecurityKeyIdentifier: 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
),
token: '{
"alg":"RS256",
"kid":"073a3204ec09d050f5fd26460d7ddaf4b4ec7561"
}.
{
"iss":"accounts.google.com",
"sub":"100330116539301590598",
"azp":"1061880999501-b47blhmmeprkvhcsnqmhfc7t20gvlgfl.apps.googleusercontent.com",
"nonce":"7c8c3656118e4273a397c7d58e108eb1",
"email_verified":true,
"aud":"1061880999501-b47blhmmeprkvhcsnqmhfc7t20gvlgfl.apps.googleusercontent.com",
"iat":1429556543,"exp\":1429560143
}'."
}
Moja tokena kod weryfikacyjny następujący przykład określone przez dobrych ludzi rozwijających IdentityServer
private async Task<IEnumerable<Claim>> ValidateIdentityTokenAsync(string idToken, string state)
{
// New Stuff
var token = new JwtSecurityToken(idToken);
var jwtHandler = new JwtSecurityTokenHandler();
byte[][] certBytes = getGoogleCertBytes();
for (int i = 0; i < certBytes.Length; i++)
{
var certificate = new X509Certificate2(certBytes[i]);
var certToken = new X509SecurityToken(certificate);
// Set up token validation
var tokenValidationParameters = new TokenValidationParameters();
tokenValidationParameters.ValidAudience = googleClientId;
tokenValidationParameters.IssuerSigningToken = certToken;
tokenValidationParameters.ValidIssuer = "accounts.google.com";
try
{
// Validate
SecurityToken jwt;
var claimsPrincipal = jwtHandler.ValidateToken(idToken, tokenValidationParameters, out jwt);
if (claimsPrincipal != null)
{
// Valid
idTokenStatus = "Valid";
}
}
catch (Exception e)
{
if (idTokenStatus != "Valid")
{
// Invalid?
}
}
}
return token.Claims;
}
private byte[][] getGoogleCertBytes()
{
// The request will be made to the authentication server.
WebRequest request = WebRequest.Create(
"https://www.googleapis.com/oauth2/v1/certs"
);
StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream());
string responseFromServer = reader.ReadToEnd();
String[] split = responseFromServer.Split(':');
// There are two certificates returned from Google
byte[][] certBytes = new byte[2][];
int index = 0;
UTF8Encoding utf8 = new UTF8Encoding();
for (int i = 0; i < split.Length; i++)
{
if (split[i].IndexOf(beginCert) > 0)
{
int startSub = split[i].IndexOf(beginCert);
int endSub = split[i].IndexOf(endCert) + endCert.Length;
certBytes[index] = utf8.GetBytes(split[i].Substring(startSub, endSub).Replace("\\n", "\n"));
index++;
}
}
return certBytes;
}
wiem, że walidacja Podpis nie jest całkowicie niezbędne do JWTs ale nie mam najmniejszego pojęcia, jak to wyłączyć. Jakieś pomysły?
Gdy zorientowali się, jak to zrobić, to działało idealnie. Dzięki za pomoc. Kod wygląda tak: 'tokenValidationParameters.IssuerSigningKeyResolver = (arbitralnie, deklarowanie, te, parametry) => { zwraca nowy X509SecurityKey (certyfikat); }; ' – ReimTime
thx, dodano do odpowiedzi na kompletność –