RabbitMQ HTTP Auth Backend in Go
Package and example service to build a RabbitMQ HTTP Auth service for use with the RabbitMQ "HTTP Auth Backend" (actually it is an AuthN/AuthZ backend).
For details see https://github.com/rabbitmq/rabbitmq-server/tree/master/deps/rabbitmq_auth_backend_http
Build your own service
To build a RabbitMQ HTTP Auth Backend, you just need to implement the provided
Auth
interface, which will be called by POST
requests to the paths
/auth/user
, /auth/vhost
, /auth/topic
and /auth/resource
:
package rabbitmqauth
type Decision bool
type Auth interface {
// User authenticates the given user. In addition to the decision, the tags
// associated with the user are returned.
User(username, password string) (Decision, string)
// VHost checks if the given user/ip combination is allowed to access the
// vhosts
VHost(username, vhost, ip string) Decision
// Resource checks if the given user has access to the presented resource
Resource(username, vhost, resource, name, permission string) Decision
// Topic checks if the given user has access to the presented topic when
// using topic authorization (https://www.rabbitmq.com/access-control.html#topic-authorisation)
Topic(username, vhost, resource, name, permission, routingKey string) Decision
}
Start a web server using your Auth implementation and the http router provided
by the rabbitmqauth.AuthService.NewRouter()
function like:
package main
import (
"fmt"
"net/http"
"time"
rabbitmqauth "github.com/jandelgado/rabbitmq-http-auth/pkg"
)
const httpReadTimeout = 10 * time.Second
const httpWriteTimeout = 10 * time.Second
func main() {
auth := NewLogInterceptingAuth(DemoAuth{})
service := rabbitmqauth.NewAuthService(auth)
server := &http.Server{
Handler: service.NewRouter(),
Addr: fmt.Sprintf(":%d", 8000),
WriteTimeout: httpWriteTimeout,
ReadTimeout: httpReadTimeout,
}
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}
Have a look at the example for a complete example.
Test it
Start the example by running make build && make run
and then test the service
by issueing POST requests to the User
endpoint , for example:
$ curl -XPOST localhost:8000/auth/user -d "username=guest&password=test"
allow [management administrator demo]
$ curl -XPOST localhost:8000/auth/user -d "username=john&password=test"
deny
Since the DemoAuth
only allows the guest
user (but with any
password), this is the expected result.
Test with RabbitMQ
A docker-compose file is provided which sets up a RabbitMQ broker with the authentication service configured. To test it, run:
$ cd demo && docker-compose up
Then in another console, try to publish a message using rabtap
$ echo "hello" | rabtap pub --uri amqp://guest:123@localhost:5672 --exchange amq.topic --routingkey "#"
In the docker-compose log, should see the auth server logging the request:
auth-http_1 | 2021/04/18 21:28:01 auth user(u=guest) -> allow [management administrator demo]
As the DemoAuth
allows any password for the guest user, you can
try to change the password in the rabtap
command or try to login on the
management console with any password.
Author & License
(c) Copyright 2021 by Jan Delgado. Licence: MIT