Programmatically Authenticate via Authentik to Forward Auth Service #15466
-
So I am working on a project that uses a basic HTTP server to provide an API, this HTTP server supports Basic authentication and is configured for forward auth via Authentik. I need to consume the API of this HTTP server (Currently just using Invoke-RestMethod in PowerShell as well as CURL) and I was wondering if there is a way to specify the username and password for Authentik or perhaps an API token that would then allow access to this API? If so, would I just need to send a header to Authentik or would I need to do it some other kind of way? If it requires transmitting the username and password like Basic authentication, how would the multi factor authentication requirement fit in with this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
So the small amount of testing I’ve done, I have found I can access a forward auth protected app with an existing cookie. I was able to basically use the F12 tools in Firefox and steal the cookie from it and then in PowerShell I did: Invoke-WebRequest -URI “https://protectedapp.domain.com/“ -Headers @{cookie=“(insert cookie from Firefox here”} Which got me the HTML output of the app behind forward auth rather than the Authentik login flow. |
Beta Was this translation helpful? Give feedback.
-
So after some playing around with PowerShell, Invoke-RestMethod and slamming my head into the desk with the Authentik documentation, I have made a discovery. You can programmatically access and authenticate a user via Authentik, it takes some doing and has some caveats. You first need to create a simple authentication flow that asks for the username on page 1 and then the password on page 2. Like the following: Then in PowerShell but this also applies to other scripting/programming languages, you first need to do the following: $Response1 = Invoke-RestMethod `
-URI "https://authentik.domain.com/api/v3/flows/executor/signin-legacy/" `
-FollowRelLink `
-SessionVariable Authentik `
-Method GET In this command, we call on Authentik to execute the signin-legacy flow that we created previously to support this approach. The -FollowRelLink parameter tells PowerShell to follow the web page as it executes so any 301 or 302 redirect codes are respected and PowerShell will walk through it until getting a standard 200 response from Authentik's web server. The -SessionVariable Authentik parameter tells PowerShell to create a variable to hold the user agent, cookies and headers that have been exchanged between it and the server, most importantly, this gives you your CSRF cookie, hold onto this variable. The -Method GET parameter tells PowerShell that we are carrying out a HTTP GET method, no data should be transmitted. ![]() The output of the $Response1 variable gives us the output from Authentik and the key identifiers are the flow_designation and component properties as these tell you, you are on the right flow and the flow is waiting for your username. Next: $Response2 = Invoke-RestMethod `
-URI "https://authentik.domain.com/api/v3/flows/executor/signin-legacy/" `
-FollowRelLink `
-WebSession $Authentik `
-Method POST `
-Body (@{"component"="ak-stage-identification";"uid_field"="myusername"} | ConvertTo-Json) `
-ContentType "application/json" In this command, we call on Authentik again through the same URL to the same flow but this time telling Authentik where the flow should be in its execution and our username plus the cookies created from the previous request. As before the -FollowRelLink parameter makes PowerShell follow any 301 and 302 redirects. The -WebSession $Authentik parameter tells PowerShell to use the session variable from before with its assortment of headers, user agent, cookies, etc. The -Method POST parameter tells PowerShell that we are sending data to the server and tells the server it is receiving data. The -Body parameter contains a PowerShell hash table that contains the "component" property telling the flow where it is at in its execution, and the "uid_field" property telling the flow what username to use and converts that hashtable to a JSON object. The -ContentType "application/json" parameter, tells PowerShell to set the Content-Type header to tell the server it is receiving a JSON object. ![]() The output of the $Response2 variable gives us more output from Authentik and the flow being executed and we can see the component property has been updated to ak-stage-password, the pending_user is set to our username, the pending_user_avatar property is set to the path to our user avatar. Next: $Response3 = Invoke-RestMethod `
-URI "https://authentik.domain.com/api/v3/flows/executor/signin-legacy/" `
-FollowRelLink `
-WebSession $Authentik `
-Method POST `
-Body (@{"component"="ak-stage-password";"password"="helloworld"} | ConvertTo-Json) `
-ContentType "application/json" This command is the same as the previous one just with a slightly different -Body parameter. Here we are telling Authentik that the flow is at the "ak-stage-password" stage and requesting a password and we feed it our password, convert the hashtable to JSON and send it to Authentik. ![]() The output of the $Response3 variable gives us only one property, the component property stating "xak-flow-redirect" and its value is / (Go home) which means authentication has completed. At this point, if you examine the $Authentik variable you will see data similar to the below screenshot, examining the $Authentik.Cookies.GetAllCookies() function will show you all cookies that have been created during authentication. ![]() This variable is important to keep a hold of, because you will need it for further authentication with Authentik's API, as well as any forward authenticated applications that Authentik is in charge of protecting. For example, to subsequently authenticate and access qBitTorrent's web API and get its version which is sat behind Authentik, you would need to do the following: Invoke-RestMethod `
-URI "https://qbittorrent.domain.com/api/v2/app/version" `
-FollowRelLink `
-WebSession $Authentik `
-Method GET With the WebSession parameter set to the $Authentik variable which contains our cookies, you can access the API for qBitTorrent and get its actual value whereas if the WebSession variable was not specified, you would be redirected automatically to Authentik's logon page as we see in the below too images. ![]() ![]() Once you are done with your session, you can also logout and terminate the session by doing the following, remembering to specify your $Authentik session variable: Invoke-RestMethod `
-URI "https://authentik.domain.com/api/v3/flows/executor/signout/" `
-FollowRelLink `
-WebSession $Authentik `
-Method GET This command calls on Authentik to sign out and terminate your session, ensuring that if your $Authentik variable were nabbed, the cookies within it would be useless. When carried out you would get a response with the singular component property stating "ak-flow-redirect" and with a value of /, which means we were successful and have been logged out. Then you would dispose of your $Authentik session variable, the same way you would with any other variable within your scripting/programming language. What use would this be as opposed to just using an API token? Well this would allow you to build an app that prompts for your Authentik user credentials similar to how Adobe or Microsoft might do it. It also allows you to script and access applications behind your Authentik instance without whitelisting URLs within Authentik, so if you have an automated task that needs to talk to a REST API that sits behind Authentik you don't need to add ^/api/+? to Authentik to allow that folder to be accessed without authentication which might not be viable. Thank you for coming to my TED Talk, @BeryJu, please don't remove this functionality from Authentik. |
Beta Was this translation helpful? Give feedback.
So after some playing around with PowerShell, Invoke-RestMethod and slamming my head into the desk with the Authentik documentation, I have made a discovery. You can programmatically access and authenticate a user via Authentik, it takes some doing and has some caveats.
You first need to create a simple authentication flow that asks for the username on page 1 and then the password on page 2. Like the following:
Then in PowerShell but this also applies to other scripting/programming languages, you first need to do the following: