jcelliott/turnpike

Implement Authorization

Closed this issue · 13 comments

Hello,

I would like to implement a custom Dealer/Broker but I can't find a way to identify the caller/publisher.
If the Session instead of just the Peer would be passed down to the Dealer/Broker from the Router, I could identify the caller/publisher with Session.Id.

Any thoughts?

I'm curious, what do you want to implement with a custom dealer/broker? We have thought about this, but didn't have a concrete use case in mind.

My dealer/broker would handle access rights. I don't want to implement handling access rights in every callee application. This would also eliminate the trip to the callee and back if the caller hasn't the access right.

Edit:
From the WAMP/basic.md spec:
"A Realm is a WAMP routing and administrative domain (optionally) protected by authentication and authorization."
I think it is a good place to handle access rights.

Seems like the router would be the right place to implement this, to avoid duplicate code in the dealer and broker.

Authentication should already be working (see router.go, realm.go, and authentication.go), but authorization (access rights) is not. Would you want to implement this?

Do you mean an interceptor in the router which gets called before the message goes to the dealer/broker?

I just implemented the passing down the Session instead of just the Peer. But I just thought about the Peer.Received channel. I don't think it is a good idea to be able to get messages from that channel at the dealer/broker level.

Sorry for taking so long to get back to you on this.

Do you mean an interceptor in the router which gets called before the message goes to the dealer/broker?

That is what I meant. Were you able to solve your issue?

I implemented the passing down of the Session but as I wrote, it's not a good idea.
I like the idea of an interceptor more. I managed to work on other topics while waiting for a response.
When I get back to it, I will implement an interceptor.

How would you design the interceptor?

I would add a function like the AddSessionCallback:
Router.AddMessageHandler(MessageHandler)
type MessageHandler func(Sender, Message) (stop bool)

And call all message handlers before passing the message to the broker or dealer in defaultRouter.handleSession.
Depending on the return value of each MessageHandler call, continue the calling until all handlers are called. If none return true, pass the message to broker or dealer.

@marshauf I changed the title to be more relevant.

What do you think of the implementation from #92?

I require the Session to be passed to IsAuthorized or at least the ID. The Realm would be nice, too.
Why an interface instead of a function for Authorizer and Interceptor, if they both just contain one method?

I understand why you need the session or the session.ID to the IsAuthorized method to determine the caller/publisher, that would be easy enough to add. I was using the information in the details for the same purpose.

Since each realm has its own Authorizer, you should be able to pass the realm information in when the Authorizer is initialized without needing to add it to the interface. This is the same reason I chose to add an interface to the realm instead of a callback function to the router, so each realm could have its own.

It is common for interfaces in go to contain only one method:
https://golang.org/doc/effective_go.html#interfaces
Although, now I'm wondering if the method names should be changed to Authorize and Intercept to conform with the information in the link above. Any thoughts?

Would be nice if you add that.

You are right, it is common. I got confused with the net/http.HandleFunc function.
Yeah, I prefer shorter names. Since the method is authorizing and not returning if the message is authorized, I think Authorize fits better. Same with Intercept.

@DaniloMoura1 I pulled your commit in before the refactoring in 8205059 so there wouldn't be conflicts. If you have additional changes you should base them on the v2 branch head.

@jcelliott : thanks. Since the welcome.Details were added to the session in de54ebe, I believe we could simplify the interface even further to simply take in the entire session and message.