public override async Task <bool> HandleRequestAsync() { // Check SignInAs identity for authentication update if (Context.User.Identity.IsAuthenticated) { await ValidateSignInAsIdentities(); } var currUri = new Uri(CurrentUri); // Check for valid callback URI var callbackUri = await KeycloakIdentity.GenerateLoginCallbackUriAsync(Options, currUri); if (!Options.ForceBearerTokenAuth && currUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.Unescaped) == callbackUri.ToString()) { // Create authorization result from query var authResult = new AuthorizationResponse(currUri.Query); try { // Validate passed state var stateData = ReturnState(authResult.State); if (stateData == null) { throw new Exception("Invalid state: Please reattempt the request"); } // Parse properties from state data AuthenticationProperties properties; if (stateData.TryGetValue(Constants.CacheTypes.AuthenticationProperties, out object authpprop)) { properties = authpprop as AuthenticationProperties ?? new AuthenticationProperties(); } else { properties = new AuthenticationProperties(); } // Process response var kcIdentity = await KeycloakIdentity.ConvertFromAuthResponseAsync(Options, authResult, currUri); var identity = await kcIdentity.ToClaimsIdentityAsync(); Context.User.AddIdentity(identity); SignInAsAuthentication(identity, properties, Options.SignInAsAuthenticationSchema); // Redirect back to the original secured resource, if any if (!string.IsNullOrWhiteSpace(properties.RedirectUri) && Uri.IsWellFormedUriString(properties.RedirectUri, UriKind.Absolute)) { Response.Redirect(properties.RedirectUri); return(true); } } catch (Exception exception) { await GenerateErrorResponseAsync(HttpStatusCode.BadRequest, "Bad Request", exception.Message); return(true); } } return(false); }
public override async Task <bool> InvokeAsync() { // Check SignInAs identity for authentication update if (Context.Authentication.User.Identity.IsAuthenticated) { await ValidateSignInAsIdentities(); } // Check for valid callback URI var callbackUri = await KeycloakIdentity.GenerateLoginCallbackUriAsync(Options, Request.Uri); if (!Options.ForceBearerTokenAuth && Request.Uri.GetLeftPart(UriPartial.Path) == callbackUri.ToString()) { // Create authorization result from query var authResult = new AuthorizationResponse(Request.Uri.Query); try { // Validate passed state var stateData = Global.StateCache.ReturnState(authResult.State); if (stateData == null) { throw new BadRequestException("Invalid state: Please reattempt the request"); } // Parse properties from state data var properties = stateData[Constants.CacheTypes.AuthenticationProperties] as AuthenticationProperties ?? new AuthenticationProperties(); // Process response var kcIdentity = await KeycloakIdentity.ConvertFromAuthResponseAsync(Options, authResult, Request.Uri); var identity = await kcIdentity.ToClaimsIdentityAsync(); Context.Authentication.User.AddIdentity(identity); SignInAsAuthentication(identity, properties, Options.SignInAsAuthenticationType); // Redirect back to the original secured resource, if any if (!string.IsNullOrWhiteSpace(properties.RedirectUri) && Uri.IsWellFormedUriString(properties.RedirectUri, UriKind.Absolute)) { Response.Redirect(properties.RedirectUri); return(true); } } catch (BadRequestException exception) { await GenerateErrorResponseAsync(HttpStatusCode.BadRequest, "Bad Request", exception.Message); return(true); } } return(false); }
public override async Task <bool> InvokeAsync() { // Check SignInAs identity for authentication update if (Context.Authentication.User.Identity.IsAuthenticated) { await ValidateSignInAsIdentities(); } // Check for valid callback URI var callbackUri = await KeycloakIdentity.GenerateLoginCallbackUriAsync(Options, Request.Uri); if (!Options.ForceBearerTokenAuth && Request.Uri.GetLeftPart(UriPartial.Path) == callbackUri.ToString()) { // Create authorization result from query var authResult = new AuthorizationResponse(Request.Uri.Query); _logger.Debug($"Request from {Request.Uri}"); // If the authorization response returned a "error" query parameter (instead of "code" + "state"), redirect to a configured URL. // This could occur if the login is aborted by the user. if (!authResult.IsSuccessfulResponse()) { HandleAuthError(authResult); return(true); } try { // Validate passed state var stateData = Global.StateCache.ReturnState(authResult.State) ?? new Dictionary <string, object>(); //throw new BadRequestException("Invalid state: Please reattempt the request"); // Process response and gather claims. If No state is found in cache we will log out the user from Keycloak and redirect him //again for login. StateData must exist and match the oidc_state received from request var kcIdentity = await KeycloakIdentity.ConvertFromAuthResponseAsync(Options, authResult, Request.Uri); var identity = await kcIdentity.ToClaimsIdentityAsync(); if (!stateData.ContainsKey(Constants.CacheTypes.AuthenticationProperties)) { await ForceLogoutRedirectAsync(identity); _logger.Debug($"State data is null.Logging out user and redirecting"); return(true); } // Parse properties from state data var properties = stateData[Constants.CacheTypes.AuthenticationProperties] as AuthenticationProperties; //everything is ok until here, sign in the user Context.Authentication.User = new ClaimsPrincipal(identity); SignInAsAuthentication(identity, properties, Options.SignInAsAuthenticationType); _logger.Debug($"Signed in user {identity.Name} with state data."); // Trigger OnAuthenticated? var eventArgs = new OnAuthenticatedEventArgs { RedirectUri = properties?.RedirectUri }; Options.OnAuthenticated?.Invoke(Context, eventArgs); // Redirect back to the original secured resource, if any if (!string.IsNullOrWhiteSpace(eventArgs.RedirectUri) && Uri.IsWellFormedUriString(eventArgs.RedirectUri, UriKind.Absolute)) { Response.Redirect(eventArgs.RedirectUri); return(true); } } catch (Exception exception) { _logger.Debug($"Returning false for {exception.Message} {exception.StackTrace}"); await GenerateErrorResponseAsync(HttpStatusCode.InternalServerError, "Internal Server Error", exception.Message); return(false); } } return(false); }