Giter VIP home page Giter VIP logo

dniel / traefik-forward-auth0 Goto Github PK

View Code? Open in Web Editor NEW
85.0 2.0 15.0 2.42 MB

A backend for performing forward authentication with Auth0 using the Traefik reverse proxy.

License: GNU General Public License v3.0

Dockerfile 0.13% Kotlin 86.62% Groovy 7.32% Shell 0.65% HTML 2.10% Java 2.67% Mustache 0.50%
traefik auth0 oauth jwt kubernetes openid-connect protect-frontends kotlin spring-boot backend authorization authentication kubernetes-configuration beyondcorp external-authentication

traefik-forward-auth0's Introduction

Known Vulnerabilities Sonarcloud Status Build Status

Auth0 ForwardAuth for Traefik

This is a SpringBoot backend application written in Kotlin and Java8 for authenticating user with Auth0 in Traefik. Use the forward authentication configuration in Traefik and point it to this backend to protect frontends with Auth0 login.

The backend application supports multiple Auth0 applications and APIs based on the domainname/subdomainname of the application and will save the JWT and the Access Token received from Auth0 as a cookie in the browser. When visitors access a protected frontend configured in Traefik, a http call will be sent to this backend to validate that the user is a valid user.

Update Notes

For those that want to delay upgrade from 1.0 to 2.0 version, there is a docker image that has been tagged 1.0 that you can continue to use, but it will not get any further updates and I encourage you to upgrade to 2.0 as soon as possible.

There is some important breaking changes in version 2.0 of ForwardAuth. It is now mandatory to set an audience when requesting authorization. This change is required due to how Auth0 handles two different kinds of token formats, opaque tokens and jwt tokens, for access tokens. The only token that is possible to validate and verify is the jwt token. Therefor its from now on required to set the audience in the application config and the application will not work otherwise.

The version 2.0 configuration also has some new fields that need to be set for the application to start up. See the page Upgrade Notes for information about compatability and upgrades between versions. The Configuration page should have a update to date example for the latest version.

Features

  • Centralized Auth-host mode for easy configuration when you have lots of applications.
  • Multiple-host auth mode for more advanced SSO per. sub-domain/applications configuration
  • Very flexible configuration
  • Support for Auth0 API permissions natively to block access to services by API permissions.
  • Implement a powerfull BeyondCorp policy control using Auth0 Rules + Auth0 Auth Core with RBAC.
  • Restrict selected HTTP methods, let other methods be unrestricted.
  • Signout and userinfo endpoint for other applications to use.

Documentation

Checkout the documentation at Read The Docs

traefik-forward-auth0's People

Contributors

bigwheels16 avatar billimek avatar dniel avatar funkypenguin avatar karolisl avatar michielvangendt avatar rcjsuen avatar renovate-bot avatar renovate[bot] avatar snyk-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

traefik-forward-auth0's Issues

Deny Opaque Access Tokens because they are not possible to verify that they are valid.

After asking for help on the Auth0 community board I get the following advice.
https://community.auth0.com/t/how-to-verify-a-if-access-token/30840/2

I think its best and less error prone to just deny access to opaque tokens.
this will break backwards compatibility for some but hopefully most uses an audience to specify the API that the access token is for, which makes the access token to a verifiable jwt token.
https://community.auth0.com/t/why-is-my-access-token-not-a-jwt/31028

If you want to configure the traefik-forward-auth without using an API, create an Default API and set for the tenant to be sure that the access_token always is a verifiable jwt token

RFC: Sending anonymous information about the running version of ForwardAuth.

Add an anonymous endpoint over HTTP to send some basic meta information about the ForwardAuth application when starting. The payload of the request should be just some basic information to know which versions is in use.

The main reason is to know if a change is going to break peoples installations, or if people have already migrated to newer versions.

Sending the version information should be enabled by default, but possible to disable by a configuration flag in the application.yaml file. Something like a config flag like sendAnonymousApplicationInfo: true/false. The application should also gracefully handle situations where the remote endpoint is not available because of blocking proxies or firewalls, and just ignore if remote endpoitn is not available, perhaps with just a line in the log to inform that information was not sent.

Example payload:

{
	"build": {
		"version": "2.0-rc1-05162020-1715-33830ac-2.0-rc1-client-credentials",
		"artifact": "forwardauth",
		"name": "forwardauth",
		"group": "dniel",
		"time": 1589649305.773000000
	}
}

I would love to get feedback if anyone sees a problem with collecting such anonymous application information.

Error when running with traefik 2.1

Hello,

I'm trying to setup your forward auth on traefik using the supplied example. However, I'm getting the following error when running the application. It seems it's trying to read some kind of header which is missing.

{
"error": "Parameter specified as non-null is null: method dniel.forwardauth.infrastructure.endpoints.AuthorizeEndpoint.authorize, parameter forwardedUriHeader"
}

Any idea what the cause of this issue is?

nonceCookie is null using docker-compose example

Hi,

I've an issue running forward auth0 and didn't know how to fix it.
I'm using the example provided for Traefik v2 and docker-compose.

{ "error": "Parameter specified as non-null is null: method dniel.forwardauth.infrastructure.endpoints.SigninEndpoint.signin, parameter nonceCookie" }

Thank you in advance

Mechanism for SPA to discover auth0 login url

SPAs get HTTP 403 after token expires. This works as expected, but it would be nice if in such case, SPA could open a new window with Auth0 login page. For this to work, we need two things:

  • NONCE cookie to be set
  • Http Header (or other mechanism) to discover the login URI

Relates to #128

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update dependency org.codehaus.janino:janino to v3.1.12
  • Update dependency org.jacoco:jacoco-maven-plugin to v0.8.12
  • Update dependency font-awesome to v5.15.4
  • Update azul/zulu-openjdk-alpine Docker tag to v21
  • Update dependency com.auth0:java-jwt to v4
  • Update dependency font-awesome to v6
  • Update dependency jakarta.servlet:jakarta.servlet-api to v6
  • Update dependency org.apache.maven.plugins:maven-surefire-plugin to v3
  • Update dependency org.codehaus.gmavenplus:gmavenplus-plugin to v3
  • Update dependency org.spockframework:spock-core to v2
  • Update kotlin monorepo to v2 (major) (org.jetbrains.kotlin:kotlin-maven-allopen, org.jetbrains.kotlin:kotlin-maven-plugin, org.jetbrains.kotlin:kotlin-test, org.jetbrains.kotlin:kotlin-reflect)
  • Update slf4j monorepo to v2 (major) (org.slf4j:log4j-over-slf4j, org.slf4j:jcl-over-slf4j, org.slf4j:slf4j-api)
  • Update spring boot to v3 (major) (org.springframework.boot:spring-boot-dependencies, org.springframework.boot:spring-boot-maven-plugin)
  • Update traefik Docker tag to v3
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

docker-compose
example/traefik1/docker-compose.yml
  • traefik v1.7.34-alpine
example/traefik2/docker-compose.yml
  • traefik 2.4
dockerfile
Dockerfile
  • azul/zulu-openjdk-alpine 8
helm-values
helm/values.yaml
html
src/main/resources/templates/error.html
  • font-awesome 5.12.1
maven
pom.xml
  • org.springdoc:springdoc-openapi-core 1.1.49
  • jakarta.servlet:jakarta.servlet-api 4.0.4
  • com.fasterxml.jackson.core:jackson-databind 2.11.0
  • com.google.guava:guava 29.0-jre
  • org.codehaus.janino:janino 3.1.9
  • org.slf4j:slf4j-api 1.7.36
  • org.slf4j:jcl-over-slf4j 1.7.36
  • org.slf4j:log4j-over-slf4j 1.7.36
  • ch.qos.logback:logback-classic 1.2.13
  • com.auth0:jwks-rsa 0.11.0
  • com.auth0:java-jwt 3.10.3
  • com.mashape.unirest:unirest-java 1.4.9
  • org.jetbrains.kotlin:kotlin-stdlib 1.3.72
  • org.jetbrains.kotlin:kotlin-reflect 1.3.72
  • org.jetbrains.kotlin:kotlin-test 1.3.72
  • org.spockframework:spock-core 1.3-groovy-2.5
  • org.hamcrest:hamcrest-all 1.3
  • com.github.stateless4j:stateless4j 2.6.0
  • org.apache.maven.plugins:maven-compiler-plugin 3.8.1
  • org.springframework.boot:spring-boot-maven-plugin 2.3.0.RELEASE
  • org.jetbrains.kotlin:kotlin-maven-plugin 1.3.72
  • org.jetbrains.kotlin:kotlin-maven-allopen 1.3.72
  • org.apache.maven.plugins:maven-surefire-plugin 2.22.2
  • org.codehaus.gmavenplus:gmavenplus-plugin 1.9.0
  • org.jacoco:jacoco-maven-plugin 0.8.9
  • org.jetbrains.dokka:dokka-maven-plugin 0.10.1
  • org.springframework.boot:spring-boot-dependencies 2.3.0.RELEASE
pip_requirements
docs/requirements.txt

  • Check this box to trigger a request for Renovate to run again on this repository

New endpoint for user profile information

To be able to use ForwardAuth as a central component for other services to look up user info a new endpoint Profile/Userinfo/User should be implemented. The endpoint should parse the JWT_TOKEN and return configured claims.

Encrypt JWT_TOKEN in cookie

The JWT_TOKEN contains the user info of a user and should be protected.
It is intended to only the application that sent the client-id and client-secret and should not be passed around to other applications. To make ForwardAuth the only application able to read the session token the whole token should be encrypted. Other applications should get the needed user info from HTTP-headers set by ForwardAuth or use the User info endpoint #51

Maybe implement a feature toggle for encryption so that its easier for local development and if someone wants to use an unencrypted JWT_TOKEN anyways to pass the user profile around.

memory usage

It's probably not possible due to the nature of being java/spring, but is there any way to otherwise influence how much memory this uses? It's odd that it would need more than influxdb or prometheus, for example:

image

It looks like claim headers containing `_` are not supported by Traefik ingress controller.

Traefik doesn't forward headers with _ from forwardauth.

Consider given_name claim, and following ingress config:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: whoami
  annotations:
    ingress.kubernetes.io/auth-type: forward
    ingress.kubernetes.io/auth-url: http://forwardauth/authorize
    ingress.kubernetes.io/auth-response-headers: Authorization,X-FORWARDAUTH-GIVEN_NAME
  labels:
    app: whoami
    chart: whoami-0.1.0
    release: whoami
    heritage: Tiller
spec:
  rules:
    - host: <snip>
      http:
        paths:
          - path: /
            backend:
              serviceName: echoheaders
              servicePort: 8080

x-forwardauth-given_name is not received by echoheaders.
Traefik helm chart:

NAME           	REVISION	UPDATED                 	STATUS  	CHART            	APP VERSION  	NAMESPACE
traefik        	14      	Sun Sep 15 19:00:19 2019	DEPLOYED	traefik-1.76.1   	1.7.12       	kube-system

URL to service always shows /oauth2/signin?code=...

When I use traefik-forward-auth0, it will forward to Auth0 to login, and when it comes back it correctly shows the app I was trying to access. However, the URL still includes the code from the Authorization Grant. example: https://whoami.mydomain.com/oauth2/signin?code=JQSfySa7z-x...

That is the first problem.

I can keep refreshing the page and it will keep showing my app. However, if I remove the extra parts of the URL, (if I navigate to https://whoami.mydomain.com), it then starts another Authorization Grant all over again.

That is the second problem.

Here is the docker-compose.yml I am using:

   traefik:
     image: traefik:v1.7.9-alpine
     ports:
       - 80:80
       - 443:443
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./traefik/traefik.toml:/traefik.toml
       - ./certs:/certs
 
   whoami:
     image: containous/whoami
     labels:
       - "traefik.frontend.rule=Host:whoami.mydomain.com"
       - "traefik.enable=true"
       - "traefik.port=80"
       - "traefik.frontend.auth.forward.address=https://auth.mydomain.com/authorize"
 
   auth:
     image: dniel/forwardauth
     labels:
       - "traefik.frontend.rule=Host:auth.mydomain.com"
       - "traefik.enable=true"
       - "traefik.port=8080"
     volumes:
       - ./traefik-forward-auth0/application.yaml:/config/application.yaml

And here is the application.yaml I am using:

 domain: https://mydomain.auth0.com/
 token-endpoint: https://mydomain.auth0.com/oauth/token
 authorize-url: https://mydomain.auth0.com/authorize
 
 default:
     name: mydomain.com
     client-id: <CLIENT_ID>
     client-secret: <CLIENT_SECRET>
     audience: https://mydomain.com
     scope: "profile openid email"
     redirect-uri: https://mydomain.com/oauth2callback2
     token-cookie-domain: mydomain.com
 
 apps:
   - name: whoami.mydomain.com
     redirect-uri: https://whoami.mydomain.com/oauth2/signin
     token-cookie-domain: whoami.mydomain.com

This is the version of the app from docker that I am using:
dniel/forwardauth latest 35c6c5153576 2 days ago 246MB

Grafana behind forward-auth0:2.0-rc1 throws errors

I'm trying to run the Grafana container behind the new 2.0 middleware, but as soon as I enable that, Grafana throws the following error:

{"message":"Invalid API key"}

I assume that is because forward-auth adds the Authorization header going to Grafana.

Grafana seems to interpret this as a way to authenticate against it with an API key, which fails (because the Header created with forward-auth has nothing to do with Grafana.

This seems to be similar to issues like this: traefik/traefik#6528

Is there a way to stop the forward-auth middleware from forwarding the Authorization header to the container?

Design new, nice looking http status page for displaying messages to user.

Need a modern, nice looking design for http status code page

  • one status page that can be used for different kinds of status codes (400,401,403,404,500)
  • css, images and everything emdedded into one single html file.
  • should support both desktop and mobile screen sizes
  • build with npm into single file with embedded content into css.

Redirect users to login page on NONCE mismatch

Sometimes users get NONCE mismatch. I've seen some similar log messages:

SignInFailedNonce received=9a7ea569fe96459688ad03d51cd63678 sent=null

My hypothesis is that user mistakenly either:

  • manually old visits auth0 login page ( `https://<auth0_domain>.eu.auth0.com/login?state=&protocol=oauth2&audience=&scope=profile%20openid%20email&response_type=code&redirect_uri=https%3A%2F%2F<real_website_domain>%2Foauth2%2Fsignin
  • manually old visits /oauth2/signin ( https://<real_website_domain>/oauth2/signin?code=hgfbmMwAu5iBV8ZL&state=<snip>

The error page on <real_website_domain>/oauth2/signin (400 BAD REQUEST) confuses users and refresh doesn't mitigate the error since NONCE is still invalid.

Would it make sense to redirect users back to auth0 just like they were coming to the page for the first time (in order to set proper NONCE)?

OpenID Connect support?

Does this app currently support OpenID Connect? Or is there plans to support it in the future?

No JWT cookie being set in the browser.

Hi,

So far, I can log in using auth0; however, I am experiencing some unexpected behavior when using the traefik-forward-auth0 image.

  • No token is being set in the browser.
  • Once authenticated (in any browser) all requests are automatically authorized. I expect that when opening a private browser window, the user should no longer be authenticated.

I am using the traefik-2/ from the examples folder with the only adjustment that I moved the configurations in the files to the docker-compose.yml.

Any help would be much appreciated.

Thanks,

Youri

Create a nice looking frontend application for ForwardAuth

ForwardAuth should have a nice looking javascript frontend

  • use forwardauth rest backend as api.
  • dashboard view for status about events, s
    • display events from /events endpoint
    • display metrics from /metrics endpoint
  • userinfo view for user
    • display the info from /userinfo endpoint
    • provide logout/session link
  • session view
    • should display information from /session link
    • should display permissions and stuff
    • logout link

New endpoint Signout

Should delete Session Cookies (JWT_TOKEN and ACCESS_TOKEN) from browser to remove user session.

multiple instances?

Do you know if this will handle cookies & JWT tokens properly when running multiple replicas of the traefik-forward-auth0 deployment?

Universal Login logo not used

When using Universal Login with design and logo set, then forward auth0 is still using default login logo for auth0

Too many redirect - AuthorizeNonce cookie didnt match the nonce in authorizeState

When I use the suggested way of configuring all web apps to forward /oauth2 path to ForwardAuth (thread), the error I get is 400 Bad Request AuthorizeNonce cookie didnt match the nonce in authorizeState.., it then starts another Authorization Grant all over again, at the end Chrome will show ERR_TOO_MANY_REDIRECTS

I am currently running Traefik 2.9.6, deployed with Helm charts and the stripprefix and redirect are implemented using middlewares (thread)

This is my application.yaml

 domain: https://mydomain.auth0.com/
 token-endpoint: https://mydomain.auth0.com/oauth/token
 authorize-url: https://mydomain.auth0.com/authorize
 userinfo-endpoint: https://mydomain.auth0.com/userinfo
 logout-endpoint: https://mydomain.auth0.com/v2/logout
 
 default:
     name: mydomain.com
     client-id: <CLIENT_ID>
     client-secret: <CLIENT_SECRET>
     audience: https://mydomain.com
     scope: "profile openid email"
     redirect-uri: https://auth.preprod.mydomain.com/signin
     token-cookie-domain: mydomain.com
 
 apps:
    - name: traefik.prep.mydomain.com
      required-permissions:
        - read:traefik
    - name: epimetheus-preprod.mydomain.com
      required-permissions:
        - read:epimetheus

This is my middleware

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: oauth2-chain
  namespace: traefik
spec:
  chain:
    middlewares:
      - name: forwardauth-authorize
        namespace: traefik
      - name: oauth2-strip-prefix
        namespace: traefik
      - name: oauth2-redirect
        namespace: traefik
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: oauth2-strip-prefix
  namespace: traefik
spec:
  stripPrefix:
    prefixes:
      - /oauth2
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: oauth2-redirect
  namespace: traefik
spec:
  redirectRegex:
    regex: ^https?://epimetheus-preprod.mydomain.com/(.*)
    replacement: https://auth.preprod.mydomain.com/${1}

This is the version of docker I'm using.

NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
forwardauth     traefik         19              2024-04-10 02:04:13.347383 +0800 CST    deployed        forwardauth-2.0.13      2.0-rc1
traefik         traefik         1               2022-04-17 23:59:30.260106 +0200 +0200  deployed        traefik-10.14.1         2.6.0

Cache already verified Tokens to improve performance

After a token has been verified, it should be cached and reused.
Verification of a token cost about 50ms, and two of them takes about 100ms for each request.
After the inital verification the only part of the token that needs to be verified each time is the expiration time of the token.

Adding cache to already verified tokens would improve perfomance alot.

How to handle Authorization

Currently I have several apps running behind Apache using the mod_auth_openidc module that is configured to delegate authentication to Auth0, which is configured to delegate to Google. So technically anybody with a Google account can successfully authenticate. However, there are only a few users that should actually be able to access these apps. The mod_auth_openidc module I am using lets me restrict access to only users that have specific claims in their id token, and using Auth0 rules (I am using the Auth0 authorization plugin) I can make sure those claims are only added for the users that I want to allow access.

Does this project have a way to achieve something similar to that? Or any plan or desire to add that?

I am not necessarily looking for the same mechanism that the Apache module uses, but just some way to centrally manage and control authorization to services behind Traefik on a per-service and per-user basis.

Dont redirect to authorization url if accept type is application/json.

To stop redirecting to the login page of Auth0 when rest ajax clients does requests, check if the accept type of the request is application/json and just deny access instead of redirecting to html-page.

A ajax javascript client will not manage to do anything useful with the login page of Auth0.
Its better just to stop accepting and wait for better times.

Some helpful libraries also set x-requested-with to XMLHttpRequest to indicate that its a ajax call from a library.

`aarch64` Support

Thanks for the project, this seems awesome!
Unfortunately this does not work on my Rock Pi cluster due to lack of aarch64 support.

Is support for other architectures planned?

Handle error=unauthorized & error_description=Access denied response

Implement error handling so that unauthorized responses is handled correctly by ForwardAuth.
Now it just print the error message with the generic error json printer.
It should show an better unauthorized error page, maybe just report 401 and let Traefik route it to correct webapp to handle 401 status messages.

https://redacted/oauth2/signin?error=unauthorized&error_description=Access%20denied.&state=eyJvcmlnaW5VcmwiOnsicHJvdG9jb2wiOiJodHRwcyIsImhvc3QiOiJ0cmFlZmlrLmRuaWVsLnNlIiwidXJpIjoiL2Rhc2hib2FyZC8ifSwibm9uY2UiOnsidmFsdWUiOiJmODE2NmNkNGFlYTc0ZTNlYjEzZGI2Y2M1Y2UyNjk0ZiJ9fQ%3D%3D

Add page to documentation for "Common/FAQ/Potential Issues"

To help people figure out common configuration errors both on their own server setup, docker setup,application config and traefik config it would be helpful to create a page that describes most common pitfalls when trying to configure an environment to use ForwardAuth and Auth0.

Option to toggle passing AccessToken vs idToken to backend

Currently AccessToken is passed as the Authorization header to the backend, but applications like Kubernetes Dashboard will work OOB with an idToken. Is there a way to toggle (on a per-app basis) which JWT is passed to the backend?

Support "Connection" property

Per Auth0 Docs, it looks like there's a "Connection" property, that could allow one to throw straight to an expected social provider. It seems like it should be straightforward to map a configuration to provide this if specified.

Would be happy to contribute a PR if this sounds viable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.