Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Oauth2 support #861

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft

Oauth2 support #861

wants to merge 7 commits into from

Conversation

kickster97
Copy link
Member

@kickster97 kickster97 commented Nov 26, 2024

WHAT is this pull request doing?

This is a WIP
ConnectionFactory uses a chain of responsibility with authentication handlers to work through different authentication backends.

The idéa is that config will state the authentication backends one wishes to use.
ConnectionFactory will then initialize authentication handlers for those backends.
Those handlers will then chain the responsibility of authenticating and returning a user, or nil if no authentication method was successful

here is an example where we configure two authentication methods, basic auth and Oauth2

authhanldersexample drawio

This PR aims to adress #857 and potentially also #246

HOW can this pull request be tested?

WIP

@kickster97 kickster97 requested a review from a team as a code owner November 26, 2024 15:24
@kickster97 kickster97 marked this pull request as draft November 26, 2024 15:24
@JadeKharats
Copy link

Looking at how RabbitMQ works and with Carl's answer, I understood that you could configure a list of authentication/authorization services and the calls were made in sequence.

I had written this
`
module LavinMQ
class AuthenticationChain
@first_service : AuthenticationService?

def initialize
  @first_service = nil
end

def add_service(service : AuthenticationService)
  if first = @first_service
    current = first
    while next_service = current.next_service
      current = next_service
    end
    current.then(service)
  else
    @first_service = service
  end
  self
end

def authorize?(username : String, password : String)
  if service = @first_service
    service.authorize?(username, password)
  end
end

end
end
`

with AuthenticationService which looks like what you did with the Handler
`
module LavinMQ
abstract class AuthenticationService
property next_service : AuthenticationService?

abstract def authorize?(username : String, password : String)

def then(service : AuthenticationService) : AuthenticationService
  @next_service = service
  service
end

protected def try_next(username : String, password : String)
  if next_service = @next_service
    next_service.authorize?(username, password)
  end
end

end
end
`

@JadeKharats
Copy link

On the config side, I also followed Carl's advice by adding an auth section to have the order of the auth services and their config

private def parse_auth(settings) settings.each do |config, v| case config when /^auth_backends\.(\d+)$/ then @auth_backends[$1.to_i] = v when "auth_http.http_method" then @auth_http_method = v when "auth_http.user_path" then @auth_http_user_path = v when "auth_http.vhost_path" then @auth_http_vhost_path = v when "auth_http.resource_path" then @auth_http_resource_path = v when "auth_http.topic_path" then @auth_http_topic_path = v else STDERR.puts "WARNING: Unrecognized configuration 'auth/#{config}'" end end end

@JadeKharats
Copy link

In my opinion, the current user store should be the default if no config.
In the Rabbit configuration, the built-in user store is called 'internal', for compatibility reasons, I think we should keep this name.

@kickster97
Copy link
Member Author

@JadeKharats thanks for your comments, seems like we have similar idéas then!
if you have code for an HTTPBackendAuthHandler or similar you could make a PR into this draft and co-author with me on this :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants