在 .Net 中将 Google 帐户实施为 Open ID Connect
我正在尝试根据 google 提供的以下链接使用 .Net 实施 Google 帐户作为 Open ID Connect 身份提供商:
我在 Startup/Program.cs 中添加了以下内容:
var configurationGoogle = new OpenIdConnectConfiguration()
{
Issuer = "https://accounts.google.com",
AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth",
TokenEndpoint = "https://oauth2.googleapis.com/token",
UserInfoEndpoint = "https://openidconnect.googleapis.com/v1/userinfo",
JwksUri = "https://www.googleapis.com/oauth2/v3/certs",
RegistrationEndpoint = "https://oauth2.googleapis.com/revoke",
};
builder.Services.AddAuthentication(options =>
{
// options.DefaultSignInScheme = "Cookies";
// options.DefaultAuthenticateScheme = "Cookies";
// options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddCookie().AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme,
options =>
{
// options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
// {
// RequireExpirationTime = false,
// ValidateLifetime = false,
// RequireSignedTokens = false,
// ValidateIssuerSigningKey = false,
// ValidateAudience = false,
// ValidateIssuer = false,
// RequireAudience = false,
// };
options.ClientId = "********.apps.googleusercontent.com";
options.ClientSecret = "******";
options.Configuration = configurationGoogle;
options.SignInScheme = "Cookies";
options.CallbackPath = new PathString("/signin-google");
options.Scope.Add("openid");
options.Scope.Add("email");
options.Scope.Add("profile");
options.SaveTokens = true;
options.ResponseType = OpenIdConnectResponseType.Code;
options.Events.OnAuthorizationCodeReceived = ctx =>
{
Console.WriteLine(@"Code:{0}", ctx.ProtocolMessage.Code);
return Task.CompletedTask;
};
options.Events.OnTokenResponseReceived = ctx =>
{
Console.WriteLine("I am executing!");
Console.WriteLine(@"Access Token:{0}", ctx.TokenEndpointResponse.AccessToken);
List<AuthenticationToken> tokens = ctx.Properties!.GetTokens().ToList();
tokens.Add(new AuthenticationToken()
{
Name = "TicketCreated",
Value = DateTime.UtcNow.ToString()
});
tokens.Add(new AuthenticationToken()
{
Name = "access_token",
Value = ctx.TokenEndpointResponse.AccessToken,
});
tokens.Add(new AuthenticationToken()
{
Name = "refresh_token",
Value = ctx.TokenEndpointResponse.RefreshToken,
});
ctx!.Properties!.StoreTokens(tokens);
return Task.CompletedTask;
};
options.Events.OnUserInformationReceived = ctx =>
{
Console.WriteLine(ctx.User);
return Task.CompletedTask;
};
}
);
然后尝试挑战它,重定向后它给我以下错误:
An unhandled exception occurred while processing the request.
SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match key:
kid: 'System.String'.
Exceptions caught:
'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.
Microsoft.IdentityModel.Tokens.InternalValidators.ValidateLifetimeAndIssuerAfterSignatureNotValidatedJwt(SecurityToken securityToken, Nullable<DateTime> notBefore, Nullable<DateTime> expires, string kid, TokenValidationParameters validationParameters, StringBuilder exceptionStrings)
正如我认为的,我们在 OIDC 中使用代码并且我们不需要验证令牌(我们没有它,但我们这里有 access_token!)并且只有在 OAuth 2.0 中我们才应该验证它。但顺便说一句,它给了我错误。我在这个过程中哪里错了? 应该注意的是,我同时获得了 access_token 和 refresh_token 以及 OnTokenResponseReceived 事件中的代码,如果它没有抛出错误,我可以根据 Open ID Connect 执行我的身份验证过程,然后将它们与 Cookie 一起保留以供下次使用。我如何防止这种情况错误,我对 OpenIDConnect 的看法是否正确,我们可能不会验证令牌?!
I am trying to implement Google Account As Open ID Connect Identity Provider using .Net according following links provided by google:
I added the following in Startup/Program.cs:
var configurationGoogle = new OpenIdConnectConfiguration()
{
Issuer = "https://accounts.google.com",
AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth",
TokenEndpoint = "https://oauth2.googleapis.com/token",
UserInfoEndpoint = "https://openidconnect.googleapis.com/v1/userinfo",
JwksUri = "https://www.googleapis.com/oauth2/v3/certs",
RegistrationEndpoint = "https://oauth2.googleapis.com/revoke",
};
builder.Services.AddAuthentication(options =>
{
// options.DefaultSignInScheme = "Cookies";
// options.DefaultAuthenticateScheme = "Cookies";
// options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddCookie().AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme,
options =>
{
// options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
// {
// RequireExpirationTime = false,
// ValidateLifetime = false,
// RequireSignedTokens = false,
// ValidateIssuerSigningKey = false,
// ValidateAudience = false,
// ValidateIssuer = false,
// RequireAudience = false,
// };
options.ClientId = "********.apps.googleusercontent.com";
options.ClientSecret = "******";
options.Configuration = configurationGoogle;
options.SignInScheme = "Cookies";
options.CallbackPath = new PathString("/signin-google");
options.Scope.Add("openid");
options.Scope.Add("email");
options.Scope.Add("profile");
options.SaveTokens = true;
options.ResponseType = OpenIdConnectResponseType.Code;
options.Events.OnAuthorizationCodeReceived = ctx =>
{
Console.WriteLine(@"Code:{0}", ctx.ProtocolMessage.Code);
return Task.CompletedTask;
};
options.Events.OnTokenResponseReceived = ctx =>
{
Console.WriteLine("I am executing!");
Console.WriteLine(@"Access Token:{0}", ctx.TokenEndpointResponse.AccessToken);
List<AuthenticationToken> tokens = ctx.Properties!.GetTokens().ToList();
tokens.Add(new AuthenticationToken()
{
Name = "TicketCreated",
Value = DateTime.UtcNow.ToString()
});
tokens.Add(new AuthenticationToken()
{
Name = "access_token",
Value = ctx.TokenEndpointResponse.AccessToken,
});
tokens.Add(new AuthenticationToken()
{
Name = "refresh_token",
Value = ctx.TokenEndpointResponse.RefreshToken,
});
ctx!.Properties!.StoreTokens(tokens);
return Task.CompletedTask;
};
options.Events.OnUserInformationReceived = ctx =>
{
Console.WriteLine(ctx.User);
return Task.CompletedTask;
};
}
);
And then try to challange it and after redirection it give me following error:
An unhandled exception occurred while processing the request.
SecurityTokenSignatureKeyNotFoundException: IDX10501: Signature validation failed. Unable to match key:
kid: 'System.String'.
Exceptions caught:
'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.
Microsoft.IdentityModel.Tokens.InternalValidators.ValidateLifetimeAndIssuerAfterSignatureNotValidatedJwt(SecurityToken securityToken, Nullable<DateTime> notBefore, Nullable<DateTime> expires, string kid, TokenValidationParameters validationParameters, StringBuilder exceptionStrings)
As I think, we use code in OIDC and we do not require to verify token (which we have not it but we have access_token here instead!) and only in OAuth 2.0 we should validate it. But it gave me error by the way. Where I am wrong in this procedure here?
It should be noticed that I am getting both access_token and refresh_token and also code in OnTokenResponseReceived event and if it not throw error I can do my Authentication Procedure according to Open ID Connect and then persist them with Cookies for next use.How I can prevent this error and Does I am correct regard to OpenIDConnect that we may not verify tokens?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
OpenID Connect 有一个需要验证的 ID 令牌。根据 OpenID 规范,我们应该使用 RS256 算法对其进行验证,该算法需要来自发行者的公钥。此公钥 ID 应从 ID 令牌标头中指定的孩子的
JwksUri
获取。如果在 OIDC 选项中使用元数据,此步骤会自动执行。但是,如果像我们在这个问题中那样使用配置,我们应该在选项令牌验证参数中手动指定此键,如下所示:我们还可以在选项事件中更动态地执行此操作,如下所示:
其中
GoogleKeys
是定义如下的类:The OpenID Connect has an ID Token which requires validation. According to OpenID specification we should validate it using RS256 algorithm which requires a public key from issuer. This public key Id should get from
JwksUri
for kid specified in ID Token Header. This step do automatically in case of using metadata in OIDC options. But in case of using Configuration as we do in this question, we should specify this keys manually in Option Token Validation Parameters as below:We also can do it more dynamicly in option Events as below:
Where
GoogleKeys
is a class defined as below: