pomerium
pomerium copied to clipboard
Use a user context creator URL
Is your feature request related to a problem? Please describe.
I use often Pomerium to secure legacy applications that do not support OIDC features and in the majority of cases (php apps for exemple), these apps use a username/password forms to authenticate users.
If we use Pomerium, we need always to authenticate twice : the first time using SSO provider and the second time using these legacy forms.
Describe the solution you'd like
For one of these applications, I coded a flask webservice that does the following:
- The service authenticate against the legacy application using an admin account
- Given a valid authentication context (token + user claims ...):
- The service will update the user password with a temporary generated one (very secure)
- The service will authenticate with username / password
- The service will return the generated cookies (Set-Cookie headers)
Now, I would like to use that service to create a user context session using Pomerium:
routes:
- from: https://my-legacy-app-secured.domain
to: http://my-legacy-app/
allow_any_authenticated_user: true
upstream_authentication:
login_url: http://my-flask-authentication-service:8000/legacy-auth
auth_check: *[optional]* http://my-flask-authentication-service:8000/legacy-auth-check
method: GET
set_authorization_header: pass_through
pass_identity_headers: true
resulting_cookies:
- PHPSESSID
In this example, IF there is no pomerium session and we're forwarded to OIDC authentication, right after the authentication, an upstream_authentication is performed using a third-party service (login_url) which will generate app-specific cookies (restricted by resulting_cookies param to avoid conflicts).
If specified, auth_check verifies if app-specific session is always active. If not, restart an upstream_authentication
Describe alternatives you've considered
*Alternative 1: *
Using 2x proxifications:
routes:
- from: https://my-legacy-app-secured.domain
to: http://my-flask-authentication-service:8000
allow_any_authenticated_user: true
pass_identity_headers: true
Pomerium ==PROXY==> my-flask-authentication layer ==PROXY==> legacy-app
*Disadvantages: *
- We need to code a reverse proxy application
- Add an additionnal layer of proxification
*Alternative 2: * Which I'm using for now
Using a nginx based Pomerium-like altenative with some tweaks. In this configuration, we check if legacy app session is always active (using http://my-flask-authentication-service:8000/legacy-auth-check). If yes => forwarding, If not, redirect to /oidc/login which is handled by my flask service (that need to handle oidc client features).
server {
server_name my-legacy-app-secured.domain;
include /etc/nginx/common/default_service.conf;
# Internal access check route
location = /access_check {
internal;
proxy_pass http://my-flask-authentication-service:8000/legacy-auth-check;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /oidc/ {
proxy_pass http://my-flask-authentication-service:8000/oidc;
include /etc/nginx/common/default_proxy_params.conf;
}
location / {
auth_request /access_check;
auth_request_set $auth_status $upstream_status;
error_page 401 = /oidc/login;
proxy_pass http://my-legacy-app/;
include /etc/nginx/common/default_proxy_params.conf;
}
}
*Disadvantages: *
- Using a tricky nginx configuration
- Need to implement an OIDC management routes (authorize, callback and so on)
- Don't benefit from Pomerium policy rules
Explain any additional use-cases
None
Additional context
None
If any more details are needed, I'll be happy to explain.