I have implemented IsActive
inside my custom user service and one of the steps that I do in that method is: check if the user has any roles for the requested client. If user has no roles IsActive
will return false. This works well for regular scenarios. However once I implemented impersonation workflow, I started to get infinite redirects between login
page and authorize
endpoint.
I can implement the same IsActive
check in my impersonate logic, but is there something else that I'm missing? It seems to me that I need to add something to IndentityServer so that it shows an error/not_authorized page, but I can't figure out where.
Implementation Details:
Impersonation is impelemented by retuning full AuthenticateResult
from PreAuthenticateAsync
based on custom acr_values.
var impersonate = context.SignInMessage.AcrValues.FirstOrDefault(x => x.StartsWith("impersonate"));
if (!string.IsNullOrWhiteSpace(impersonate))
{
var adminUserName = _owinContext.Authentication.User.FindFirst(Constants.ClaimTypes.Subject).Value;
var adminUser = _service.GetUser(adminUserName);
bool isAllowedImpersonation = true; //TODO:
var impersonateSplit = impersonate.Split(':');
if (impersonateSplit.Length != 2 || !isAloowedImpersonation)
{
context.AuthenticateResult = new AuthenticateResult("Invalid attempt to impersonate user");
}
var impesonateUserName = impersonateSplit[1];
var impersonateUser = _service.GetUser(impesonateUserName);
context.AuthenticateResult =
new AuthenticateResult(
impersonateUser.Username,
impersonateUser.Name,
claims: new[] { new Claim(Constants.ClaimTypes.ClientId, context.SignInMessage.ClientId) },
identityProvider: Constants.BuiltInIdentityProvider,
authenticationMethod: Constants.AuthenticationMethods.Password);
}
Logic inside IsActive
:
var user = _service.GetUser(context.Subject.GetSubjectId());
if (user == null || !user.IsActive)
return Task.FromResult(false);
var application = _service.GetApplicationByCode(context.Subject.GetClientId());
context.IsActive = _service.UserHasAccessTo(user, application.Code);
Edit
Log file snippet
2016-05-11 18:22:09.0726 user service returned a login result
2016-05-11 18:22:09.0726 Calling PostAuthenticateAsync on the user service
2016-05-11 18:22:09.0726 issuing primary signin cookie
2016-05-11 18:22:09.0726 redirecting to: http://localhost/xpo.security.tokenserver.site/connect/authorize?client_id=security_optimizer&redirect_uri=http:%2F%2Flocalhost%2Fxpo.security.optimizer%2F&response_mode=form_post&response_type=id_token&scope=openid email name roles&state=jXGforulK3bJWQs1aK5ML21s67HOcmaCX4lSpS19RWNQtaOHI98cY_lgk2KhKwGT67wyG_EdQU_HIgQe-bAGSEoFhwp5AqtQxswt3fgFMpTzsxOp12p5YbykbNhWqjacUEmZXOepBvC7hEkOiho1VcCoinZlJklCcLMGV5EOuLk&nonce=635986021053957554.MGJhYjQ4MDQtNDg4My00OTZhLWJjNzItMjJlZDNlZjNhZDg1ZmE5NjM2ZGMtOTBiNy00OTlhLTk0NTItN2E0OTQ5NzM0MjZm&acr_values=client:security_optimizer impersonate:ctest
2016-05-11 18:22:09.0726 Start authorize request
2016-05-11 18:22:09.0726 Start authorize request protocol validation
2016-05-11 18:22:09.0726 Authorize request validation success
{
"ClientId": "security_optimizer",
"ClientName": "Security Optimizer",
"RedirectUri": "http://localhost/xpo.security.optimizer/",
"AllowedRedirectUris": [
"http://localhost/xpo.security.optimizer/"
],
"SubjectId": "ctest",
"ResponseType": "id_token",
"ResponseMode": "form_post",
"Flow": "Implicit",
"RequestedScopes": "openid email name roles",
"State": "jXGforulK3bJWQs1aK5ML21s67HOcmaCX4lSpS19RWNQtaOHI98cY_lgk2KhKwGT67wyG_EdQU_HIgQe-bAGSEoFhwp5AqtQxswt3fgFMpTzsxOp12p5YbykbNhWqjacUEmZXOepBvC7hEkOiho1VcCoinZlJklCcLMGV5EOuLk",
"Nonce": "635986021053957554.MGJhYjQ4MDQtNDg4My00OTZhLWJjNzItMjJlZDNlZjNhZDg1ZmE5NjM2ZGMtOTBiNy00OTlhLTk0NTItN2E0OTQ5NzM0MjZm",
"AuthenticationContextReferenceClasses": [
"client:security_optimizer",
"impersonate:ctest"
],
"SessionId": "6f50b19f825f63426a7876c8c2d058df",
"Raw": {
"client_id": "security_optimizer",
"redirect_uri": "http://localhost/xpo.security.optimizer/",
"response_mode": "form_post",
"response_type": "id_token",
"scope": "openid email name roles",
"state": "jXGforulK3bJWQs1aK5ML21s67HOcmaCX4lSpS19RWNQtaOHI98cY_lgk2KhKwGT67wyG_EdQU_HIgQe-bAGSEoFhwp5AqtQxswt3fgFMpTzsxOp12p5YbykbNhWqjacUEmZXOepBvC7hEkOiho1VcCoinZlJklCcLMGV5EOuLk",
"nonce": "635986021053957554.MGJhYjQ4MDQtNDg4My00OTZhLWJjNzItMjJlZDNlZjNhZDg1ZmE5NjM2ZGMtOTBiNy00OTlhLTk0NTItN2E0OTQ5NzM0MjZm",
"acr_values": "client:security_optimizer impersonate:ctest"
}
}
2016-05-11 18:22:09.3603 User is not active. Redirecting to login.
2016-05-11 18:22:09.3603 End authorize request
2016-05-11 18:22:09.3603 Redirecting to login page
2016-05-11 18:22:09.3703 Login page requested
2016-05-11 18:22:09.7432 user service returned a login result
2016-05-11 18:22:09.7432 Calling PostAuthenticateAsync on the user service
2016-05-11 18:22:09.7432 issuing primary signin cookie
2016-05-11 18:22:09.7432 redirecting to: http://localhost/xpo.security.tokenserver.site/connect/authorize?client_id=security_optimizer&redirect_uri=http:%2F%2Flocalhost%2Fxpo.security.optimizer%2F&response_mode=form_post&response_type=id_token&scope=openid email name roles&state=jXGforulK3bJWQs1aK5ML21s67HOcmaCX4lSpS19RWNQtaOHI98cY_lgk2KhKwGT67wyG_EdQU_HIgQe-bAGSEoFhwp5AqtQxswt3fgFMpTzsxOp12p5YbykbNhWqjacUEmZXOepBvC7hEkOiho1VcCoinZlJklCcLMGV5EOuLk&nonce=635986021053957554.MGJhYjQ4MDQtNDg4My00OTZhLWJjNzItMjJlZDNlZjNhZDg1ZmE5NjM2ZGMtOTBiNy00OTlhLTk0NTItN2E0OTQ5NzM0MjZm&acr_values=client:security_optimizer impersonate:ctest
2016-05-11 18:22:09.7527 Start authorize request
2016-05-11 18:22:09.7527 Start authorize request protocol validation
2016-05-11 18:22:09.7527 Authorize request validation success
{
"ClientId": "security_optimizer",
"ClientName": "Security Optimizer",
"RedirectUri": "http://localhost/xpo.security.optimizer/",
"AllowedRedirectUris": [
"http://localhost/xpo.security.optimizer/"
],
"SubjectId": "ctest",
"ResponseType": "id_token",
"ResponseMode": "form_post",
"Flow": "Implicit",
"RequestedScopes": "openid email name roles",
"State": "jXGforulK3bJWQs1aK5ML21s67HOcmaCX4lSpS19RWNQtaOHI98cY_lgk2KhKwGT67wyG_EdQU_HIgQe-bAGSEoFhwp5AqtQxswt3fgFMpTzsxOp12p5YbykbNhWqjacUEmZXOepBvC7hEkOiho1VcCoinZlJklCcLMGV5EOuLk",
"Nonce": "635986021053957554.MGJhYjQ4MDQtNDg4My00OTZhLWJjNzItMjJlZDNlZjNhZDg1ZmE5NjM2ZGMtOTBiNy00OTlhLTk0NTItN2E0OTQ5NzM0MjZm",
"AuthenticationContextReferenceClasses": [
"client:security_optimizer",
"impersonate:ctest"
],
"SessionId": "fec184ed6b9d5eae0c84d36d22c59c1a",
"Raw": {
"client_id": "security_optimizer",
"redirect_uri": "http://localhost/xpo.security.optimizer/",
"response_mode": "form_post",
"response_type": "id_token",
"scope": "openid email name roles",
"state": "jXGforulK3bJWQs1aK5ML21s67HOcmaCX4lSpS19RWNQtaOHI98cY_lgk2KhKwGT67wyG_EdQU_HIgQe-bAGSEoFhwp5AqtQxswt3fgFMpTzsxOp12p5YbykbNhWqjacUEmZXOepBvC7hEkOiho1VcCoinZlJklCcLMGV5EOuLk",
"nonce": "635986021053957554.MGJhYjQ4MDQtNDg4My00OTZhLWJjNzItMjJlZDNlZjNhZDg1ZmE5NjM2ZGMtOTBiNy00OTlhLTk0NTItN2E0OTQ5NzM0MjZm",
"acr_values": "client:security_optimizer impersonate:ctest"
}
}
2016-05-11 18:22:10.4456 User is not active. Redirecting to login.
2016-05-11 18:22:10.4456 End authorize request
2016-05-11 18:22:10.4475 Redirecting to login page
2016-05-11 18:22:10.4475 Login page requested