c# - How to validate if user exist inside IdentityServer4 after being authenticated from External Provider?
问题描述
I'm trying to find a proper way where I can inject a service to validate if user exists or registered in my application after being successfully authenticated from an external identity provider like Azure Active Directory. What I want to do is to redirect user to a custom error page or display an Unauthorized message if his account is not yet registered in my application.
I tried utilizing the IProfileService interface but it seems not the right way to go.
Here is my Startup.cs setup:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services
.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddTestUsers(Config.GetUsers())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients()) // Client was configured with RequireConsent = false, EnableLocalLogin = false,
.AddProfileService<ProfileService>()
.Services.AddTransient<IUserRepository,UserRepository>();
services.AddAuthentication()
.AddOpenIdConnect("AAD", "Azure Active Directory", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.SignOutScheme = IdentityServerConstants.SignoutScheme;
options.Authority = "https://login.microsoftonline.com/MyTenant";
options.ClientId = "MyClientId";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false
};
options.GetClaimsFromUserInfoEndpoint = true;
});
}
public class ProfileService : IProfileService
{
private readonly IUserRepository _userRepository;
public ProfileService(IUserRepository userRepository)
{
_userRepository = userRepository
}
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var user = _userRepository.FindByUser(context.Subject.Identity.Name);
// This will display HTTP 500 instead of 401
if(user == null) throw new UnauthorizedAccessException("You're not registered");
// I add custom claims here
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context) => Task.FromResult(0);
}
Is there any available service or interface I can use where I can inject my user validation as well as allowing me to inject my user repository in that service? Is it possible to inject this kind of process inside IdentityServer4? Can someone point me in the right direction to accomplish my goal using IdentityServer4?
Note: Lets assume I have SPA web app and I have my own separate registration mechanism. I don't want to redirect back to my SPA if user doesn't exist and handle it inside IdentityServer4 instead. Btw, some of the code above are not included for brevity.
解决方案
IdentityServer4 QuickStart UI 配置为在通过外部提供商登录时自动配置本地用户帐户。这一切都在处理ExternalController.Callback
:
// lookup our user and external provider info
var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
if (user == null)
{
// this might be where you might initiate a custom workflow for user registration
// in this sample we don't show how that would be done, as our sample implementation
// simply auto-provisions new external user
user = AutoProvisionUser(provider, providerUserId, claims);
}
在您的情况下,您可以执行您需要执行的任何逻辑,而不是调用AutoProvisionUser
. 由于这是正在执行的常规 MVC 操作,因此您可以将自己的类注入到ExternalController
的构造函数中或注入到Callback
自身中(使用[FromServices]
)。以下是您可能想要进行的更改的粗略想法:
public async Task<IActionResult> Callback([FromServices] IUserRepository userRepository)
{
...
// lookup our user and external provider info
var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
if (user == null)
{
// We don't have a local user.
return RedirectToAction("SomeAction", "SomeController");
}
...
}
推荐阅读
- javascript - 使用 dropzone.js,我想发送自定义 formData
- android - 有没有办法在 android 上使用开放的街道地图生成地理围栏?
- visual-studio-code - 创建了我自己的viewsContainer - 我可以包含来自其他viewsContainers 的视图吗?
- node.js - 在控制台上获得响应而对 agent.add() 没有响应
- javascript - 一个简单的for循环出现意外的令牌错误?
- excel - Excel:SMALL()、IF() 和 ROW() 使用多个条件查找值的行号 - AND() 不起作用
- php - Excel文件创建速度很慢
- r - 如何基于另一个对称数据框在 R 中创建对称数据框
- python - 用excel中的(x,y)系列确定范德华方程中的a和b
- android - 遍历具有用户 ID 的 firebase 节点,以显示特定的子节点并将值存储在数组中