| | | 1 | | <# |
| | | 2 | | .SYNOPSIS |
| | | 3 | | Challenges the current request to authenticate with the specified authentication scheme. |
| | | 4 | | .DESCRIPTION |
| | | 5 | | Wraps ChallengeAsync on the current HTTP context to trigger an authentication challenge. |
| | | 6 | | This is typically used to redirect users to an external identity provider (e.g., OIDC, OAuth2). |
| | | 7 | | Designed for use inside Kestrun route script blocks where $Context is available. |
| | | 8 | | .PARAMETER Scheme |
| | | 9 | | Authentication scheme to challenge (e.g., 'oidc', 'Google', 'AzureAD'). |
| | | 10 | | .PARAMETER RedirectUri |
| | | 11 | | URI to redirect to after successful authentication (default is current request path). |
| | | 12 | | .PARAMETER Properties |
| | | 13 | | Additional authentication properties to pass to the challenge. |
| | | 14 | | .PARAMETER WhatIf |
| | | 15 | | Shows what would happen if the command runs. The command is not run. |
| | | 16 | | .PARAMETER Confirm |
| | | 17 | | Prompts you for confirmation before running the command. |
| | | 18 | | .EXAMPLE |
| | | 19 | | Invoke-KrChallenge -Scheme 'oidc' -RedirectUri '/dashboard' |
| | | 20 | | |
| | | 21 | | Challenges the user to authenticate with OIDC, redirecting to /dashboard after login. |
| | | 22 | | .EXAMPLE |
| | | 23 | | Invoke-KrChallenge -Scheme 'Google' |
| | | 24 | | |
| | | 25 | | Challenges the user to authenticate with Google OAuth, redirecting back to the current page. |
| | | 26 | | .EXAMPLE |
| | | 27 | | $props = @{ |
| | | 28 | | prompt = 'login' |
| | | 29 | | login_hint = 'user@example.com' |
| | | 30 | | } |
| | | 31 | | Invoke-KrChallenge -Scheme 'oidc' -RedirectUri '/hello' -Properties $props |
| | | 32 | | |
| | | 33 | | Challenges with additional properties (forces login prompt and hints the username). |
| | | 34 | | .OUTPUTS |
| | | 35 | | None. This function initiates an authentication challenge and does not return a value. |
| | | 36 | | .NOTES |
| | | 37 | | This function must be called from within a route handler where $Context is available. |
| | | 38 | | After calling this function, the route should return immediately to allow the authentication |
| | | 39 | | middleware to complete the redirect. |
| | | 40 | | #> |
| | | 41 | | function Invoke-KrChallenge { |
| | | 42 | | [KestrunRuntimeApi('Route')] |
| | | 43 | | [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] |
| | | 44 | | [OutputType([void])] |
| | | 45 | | param( |
| | | 46 | | [Parameter(Mandatory = $true)] |
| | | 47 | | [string]$Scheme, |
| | | 48 | | |
| | | 49 | | [Parameter()] |
| | | 50 | | [string]$RedirectUri, |
| | | 51 | | |
| | | 52 | | [Parameter()] |
| | | 53 | | [hashtable]$Properties |
| | | 54 | | ) |
| | | 55 | | |
| | | 56 | | # Only works inside a route script block where $Context is available |
| | 0 | 57 | | if ($null -eq $Context -or $null -eq $KrServer) { |
| | 0 | 58 | | Write-KrOutsideRouteWarning |
| | | 59 | | return |
| | | 60 | | } |
| | | 61 | | |
| | 0 | 62 | | if ($PSCmdlet.ShouldProcess($Scheme, 'Challenge')) { |
| | 0 | 63 | | Write-KrLog -Level Information -Message 'Initiating authentication challenge for scheme {scheme}' -Values $Schem |
| | | 64 | | |
| | | 65 | | # Create AuthenticationProperties |
| | 0 | 66 | | $authProperties = [Microsoft.AspNetCore.Authentication.AuthenticationProperties]::new() |
| | | 67 | | |
| | | 68 | | # Set redirect URI |
| | 0 | 69 | | if ($RedirectUri) { |
| | 0 | 70 | | $authProperties.RedirectUri = $RedirectUri |
| | 0 | 71 | | Write-KrLog -Level Debug -Message 'Challenge redirect URI set to {uri}' -Values $RedirectUri |
| | | 72 | | } |
| | | 73 | | |
| | | 74 | | # Add any additional properties from hashtable |
| | 0 | 75 | | if ($Properties) { |
| | 0 | 76 | | foreach ($key in $Properties.Keys) { |
| | 0 | 77 | | $value = $Properties[$key] |
| | 0 | 78 | | if ($null -ne $value) { |
| | 0 | 79 | | $authProperties.Items[$key] = $value.ToString() |
| | 0 | 80 | | Write-KrLog -Level Debug -Message 'Added challenge property: {key}={value}' -Values $key, $value |
| | | 81 | | } |
| | | 82 | | } |
| | | 83 | | } |
| | | 84 | | |
| | | 85 | | # Call ChallengeAsync using the ASP.NET Core authentication extensions |
| | 0 | 86 | | $Context.Challenge($Scheme, $authProperties) |
| | 0 | 87 | | Write-KrLog -Level Information -Message 'Authentication challenge initiated for scheme {scheme}' -Values $Scheme |
| | | 88 | | |
| | | 89 | | # CRITICAL: Send a 302 status to prevent Kestrun from sending its own 200 OK response |
| | | 90 | | # The authentication handler has already set up the redirect Location header |
| | 0 | 91 | | Write-KrStatusResponse -StatusCode 302 |
| | | 92 | | } |
| | | 93 | | } |