I have 5 clients of my identity server, I need to separate the authorization of 1 client from the others. After signin to the ClientA, I switch to the ClientB already authorized, help me solve.
It is necessary for one IdentityServer to work as two?
my IdentityResourceStore:
public class IdentityResourceStore : IResourceStore {
private readonly IScopeRepository _repository;
private readonly IMemoryCache _memoryCache;
public IdentityResourceStore(IScopeRepository repository, IMemoryCache memoryCache) {
_repository = repository;
_memoryCache = memoryCache;
}
public async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(
IEnumerable<string> scopeNames) {
var resources = await GetAllResourcesAsync();
return resources.IdentityResources.Where(r => scopeNames.Contains(r.Name));
}
public async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames) {
var resources = await GetAllResourcesAsync();
return resources.ApiScopes.Where(s => scopeNames.Contains(s.Name));
}
public async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames) {
var resources = await GetAllResourcesAsync();
var apiResources = resources.ApiResources.ToList();
return apiResources.Where(x => x.Scopes.Any(y => scopeNames.Contains(y)));
}
public async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames) {
var resources = await GetAllResourcesAsync();
var apiResources = resources.ApiResources.ToList();
return apiResources.Where(x => apiResourceNames.Contains(x.Name));
}
public async Task<IdentityServer4.Models.Resources> GetAllResourcesAsync() {
var defaultResources = new List<IdentityResource> {
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
ApiScope[] apiScopes = { new ApiScope("ClientA"), new ApiScope("ClientB") };
var apiResources = new List<ApiResource>();
if (_memoryCache.TryGetValue("clients_array", out IEnumerable<string> clients_array)) {
foreach (var clientId in clients_array) {
if (!_memoryCache.TryGetValue(clientId, out FileClient client)) continue;
if (clientId == ClientIds.ClientB) {
var apiResource = new ApiResource(clientId) {
ApiSecrets = client.IdentitySeverClient.ClientSecrets,
Scopes = new [] { "ClientB" },
};
apiResources.Add(apiResource);
}
else
{
var apiResource = new ApiResource(clientId) {
ApiSecrets = client.IdentitySeverClient.ClientSecrets,
Scopes = new [] { "ClientA" },
};
apiResources.Add(apiResource);
}
}
}
return new IdentityServer4.Models.Resources(defaultResources, apiResources, apiScopes);
}
}
One of the auth endpoints in my identityServer
public async Task<IActionResult> AuthByPhonePassword([FromBody] AuthLoginPasswordDto authUserByPhoneDto) {
var result = await _authService.AuthByPhonePassword(authUserByPhoneDto);
await HttpContext.SignInAsync(new IdentityServerUser(result.Value.UserId) {
DisplayName = result.Value.UserName,
AdditionalClaims = new Claim[] { new Claim(CustomJwtClaimTypes.UserType, result.Value.UserType) }
}, null);
return result.AsHttpResult();
}
ClientA scopes: “scopes”: “openid profile employee ClientA offline_access”,
ClientB scopes: “scopes”: “openid profile ClientB”,
I attempted to separate different scopes. Tried to add a Policy on the API side, but this approach turned out to be unsuitable. It seems that my IdentityServer must be the one to indicate that a scope is not appropriate.
I noticed that after modifying resources, my JWT token began to change; the ‘aud’ list was correct (without any unnecessary clients), and the list of scopes in the token was also corrected.
Галымжан Оралбаев is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.