Class: Rack::ForwardAuth::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/forward_auth/middleware.rb

Overview

Production middleware that reads forward-auth headers set by a reverse proxy (Authelia, Authentik, Caddy, Traefik, etc.) and exposes parsed user attributes in the Rack env.

By default, attributes are stored in env as a Hash:

{ uid: "nathan", email: "[email protected]",
  display_name: "Nathan", groups: ["admin", "users"] }

You can provide an optional on_user callback (proc/lambda) that receives the attributes hash and returns whatever object you want stored in the env key. This is how the host app hooks in its own User model upsert logic:

use Rack::ForwardAuth::Middleware, on_user: ->(attrs) {
  User.find_or_initialize_by(uid: attrs[:uid]).tap { |u|
    u.assign_attributes(attrs.except(:uid))
    u.save! if u.changed?
  }
}

Instance Method Summary collapse

Constructor Details

#initialize(app, env_key: ForwardAuth::ENV_KEY, on_user: nil) ⇒ Middleware

Returns a new instance of Middleware.



27
28
29
30
31
# File 'lib/rack/forward_auth/middleware.rb', line 27

def initialize(app, env_key: ForwardAuth::ENV_KEY, on_user: nil)
  @app     = app
  @env_key = env_key
  @on_user = on_user
end

Instance Method Details

#call(env) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rack/forward_auth/middleware.rb', line 33

def call(env)
  uid = env[ForwardAuth::REMOTE_USER]

  if uid && !uid.empty?
    attrs = {
      uid:          uid,
      email:        env[ForwardAuth::REMOTE_EMAIL],
      display_name: env[ForwardAuth::REMOTE_NAME],
      groups:       parse_groups(env[ForwardAuth::REMOTE_GROUPS]),
    }

    env[@env_key] = @on_user ? @on_user.call(attrs) : attrs
  end

  # Also set under the legacy key for backwards compat
  env["authelia.user"] = env[@env_key] if @env_key != "authelia.user"

  @app.call(env)
end