我正在 ASP .NET Core 5 上使用 Google Auth 设置 Web 应用程序。我希望能够使用授权属性标记某些页面,以仅允许具有给定角色的用户访问。 Google 发送的访问令牌仅包含姓名和电子邮件,而不包含用户分配到的组或角色。所以我尝试通过调用 API 来获取角色,但我该怎么做?
这是我的 Startup.cs
public class Startup
{
private IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddGoogleOpenIdConnect (async options =>
{
var googleAuthenticationSection = Configuration.GetSection("Authentication:Google");
options.ClientId = googleAuthenticationSection["ClientId"];
options.ClientSecret = googleAuthenticationSection["ClientSecret"];
options.CallbackPath = new("/signin-oidc");
options.Scope.Add("https://www.googleapis.com/auth/admin.directory.group.readonly");
options.Scope.Add("https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly");
options.Scope.Add("https://www.googleapis.com/auth/admin.directory.user.readonly");
options.ClaimActions.MapJsonKey(ClaimTypes.Role, "role", "string");
options.Events = new OpenIdConnectEvents
{
OnMessageReceived = context =>
{
if (!string.IsNullOrEmpty(context.ProtocolMessage?.Error))
{
context.Response.Redirect($"/AccessDenied?error={context.ProtocolMessage.Error}&error_description={context.ProtocolMessage.ErrorDescription}");
context.HandleResponse();
}
return Task.CompletedTask;
}
};
// start of attempt to retrieve Role from Google Directory API
var credential = await GoogleAuthProvider.GetCredentialAsync();
var googleApiService = new DirectoryService(new BaseClientService.Initializer { HttpClientInitializer = credential });
var getRole = new RolesResource.GetRequest(googleApiService, "Zvi", "Owner");
var role = await getRole.ExecuteAsync();
// end of attempt to retrieve Role
})
.AddCookie();
services.
AddAuthorization(options =>
{
options.AddPolicy("WriteAccess", x => x.RequireClaim(ClaimTypes.Role, "Owner"));
});
问题是 GoogleAuthProvider 没有注入到 Startup 类中,所以我无法使用它。我想将其放在这里,以便在检索到该值后可以插入具有该值的新声明。
当然,如果有人有更好的方法来获取用户的角色(或组)而不进行 API 调用那就更好了。
尝试使用OnUserInformationReceived。从 UserInfoEndpoint 检索用户信息时调用。
您可以从 UserInformationReceivedContext.User 获取或设置用户信息负载。 :
options.Events = new OpenIdConnectEvents
{
OnUserInformationReceived = context =>
{
// If your authentication logic is based on users then add your logic here
return Task.CompletedTask;
}
}