/// <summary> /// Logs a success result. /// </summary> /// <param name="request"></param> protected virtual void LogSuccess(ValidatedEndSessionRequest request) { foreach (var cid in request.ClientIds) { Logger.LogDebug("End session request validation success" + Environment.NewLine + $"{cid}"); } }
/// <summary> /// Creates a result that indicates an error. /// </summary> /// <param name="message"></param> /// <param name="request"></param> /// <returns></returns> protected virtual EndSessionValidationResult Invalid(string message, ValidatedEndSessionRequest request = null) { message = "End session request validation failure: " + message; if (request != null) { var log = new EndSessionRequestValidationLog(request); Logger.LogInformation(message + Environment.NewLine + "{@details}", log); } else { Logger.LogInformation(message); } return(new EndSessionValidationResult { IsError = true, Error = "Invalid request", ErrorDescription = message }); }
/// <summary> /// Creates a result that indicates an error. /// </summary> /// <param name="message"></param> /// <param name="request"></param> /// <returns></returns> protected virtual EndSessionValidationResult Invalid(string message, ValidatedEndSessionRequest request = null) { message = "End session request validation failure: " + message; if (request != null) { foreach (var cid in request.ClientIds) { Logger.LogDebug(message + Environment.NewLine + $"{cid}"); } } else { Logger.LogInformation(message); } return(new EndSessionValidationResult { IsError = true, Error = "Invalid request", ErrorDescription = message }); }
/// <summary> /// Logs a success result. /// </summary> /// <param name="request"></param> protected virtual void LogSuccess(ValidatedEndSessionRequest request) { var log = new EndSessionRequestValidationLog(request); Logger.LogInformation("End session request validation success" + Environment.NewLine + "{@details}", log); }
/// <inheritdoc /> public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject) { Logger.LogDebug("Start end session request validation"); var isAuthenticated = subject.IsAuthenticated(); if (!isAuthenticated && Options.Authentication.RequireAuthenticatedUserForSignOutMessage) { return(Invalid("User is anonymous. Ignoring end session parameters")); } var validatedRequest = new ValidatedEndSessionRequest { Raw = parameters }; var idTokenHint = parameters.Get(OidcConstants.EndSessionRequest.IdTokenHint); if (idTokenHint.IsPresent()) { // validate id_token - no need to validate token life time // todo: consider passing a flag to not call IsActive on the profile service? #3470 var tokenValidationResult = await TokenValidator.ValidateIdentityTokenAsync(idTokenHint, null, false); if (tokenValidationResult.IsError) { return(Invalid("Error validating id token hint", validatedRequest)); } validatedRequest.Client = tokenValidationResult.Client; // validate sub claim against currently logged on user var subClaim = tokenValidationResult.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject); if (subClaim != null && isAuthenticated) { if (subject.GetSubjectId() != subClaim.Value) { // todo: consider not failing here and continue processing and check post logout redirect uri // this would mean a change to how that's validated (and not require client validated via id_token_hint) return(Invalid("Current user does not match identity token", validatedRequest)); } validatedRequest.Subject = subject; validatedRequest.SessionId = await UserSession.GetSessionIdAsync(); validatedRequest.ClientIds = await UserSession.GetClientListAsync(); } var redirectUri = parameters.Get(OidcConstants.EndSessionRequest.PostLogoutRedirectUri); if (redirectUri.IsPresent()) { if (await UriValidator.IsPostLogoutRedirectUriValidAsync(redirectUri, validatedRequest.Client)) { validatedRequest.PostLogOutUri = redirectUri; //return Invalid("Invalid post logout URI", validatedRequest); } else { Logger.LogWarning("Invalid PostLogoutRedirectUri: {postLogoutRedirectUri}", redirectUri); } } else if (validatedRequest.Client.PostLogoutRedirectUris.Count == 1) { // todo: reconsider/remove? validatedRequest.PostLogOutUri = validatedRequest.Client.PostLogoutRedirectUris.First(); } if (validatedRequest.PostLogOutUri != null) { var state = parameters.Get(OidcConstants.EndSessionRequest.State); if (state.IsPresent()) { validatedRequest.State = state; } } } else { // no id_token to authenticate the client, but we do have a user and a user session validatedRequest.Subject = subject; validatedRequest.SessionId = await UserSession.GetSessionIdAsync(); validatedRequest.ClientIds = await UserSession.GetClientListAsync(); } LogSuccess(validatedRequest); return(new EndSessionValidationResult { ValidatedRequest = validatedRequest, IsError = false }); }
public async Task <EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject) { _logger.LogDebug("Start end session request validation"); var isAuthenticated = subject != null && subject.Identity != null && subject.Identity.IsAuthenticated; if (!isAuthenticated && _options.AuthenticationOptions.RequireAuthenticatedUserForSignOutMessage) { return(Invalid("User is anonymous. Ignoring end session parameters")); } var validatedRequest = new ValidatedEndSessionRequest() { Raw = parameters, }; var idTokenHint = parameters.Get(OidcConstants.EndSessionRequest.IdTokenHint); if (idTokenHint.IsPresent()) { // validate id_token - no need to validate token life time var tokenValidationResult = await _tokenValidator.ValidateIdentityTokenAsync(idTokenHint, null, false); if (tokenValidationResult.IsError) { return(Invalid("Error validating id token hint", validatedRequest)); } validatedRequest.Client = tokenValidationResult.Client; // validate sub claim against currently logged on user var subClaim = tokenValidationResult.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject); if (subClaim != null && isAuthenticated) { if (subject.GetSubjectId() != subClaim.Value) { return(Invalid("Current user does not match identity token", validatedRequest)); } validatedRequest.Subject = subject; } var redirectUri = parameters.Get(OidcConstants.EndSessionRequest.PostLogoutRedirectUri); if (redirectUri.IsPresent()) { if (await _uriValidator.IsPostLogoutRedirectUriValidAsync(redirectUri, validatedRequest.Client) == false) { return(Invalid("Invalid post logout URI", validatedRequest)); } validatedRequest.PostLogOutUri = redirectUri; } else if (validatedRequest.Client.PostLogoutRedirectUris.Count == 1) { validatedRequest.PostLogOutUri = validatedRequest.Client.PostLogoutRedirectUris.First(); } if (validatedRequest.PostLogOutUri != null) { var state = parameters.Get(OidcConstants.EndSessionRequest.State); if (state.IsPresent()) { validatedRequest.State = state; } } } LogSuccess(validatedRequest); return(new EndSessionValidationResult() { ValidatedRequest = validatedRequest, IsError = false }); }
private void LogSuccess(ValidatedEndSessionRequest request) { var log = new EndSessionRequestValidationLog(request); _logger.LogInformation("End session request validation success\n{details}", log); }
private void LogWarning(ValidatedEndSessionRequest request, string message) { var log = new EndSessionRequestValidationLog(request); _logger.LogWarning(message + "\n{details}", log); }