Integrating Cossbar Auth with existing system

#1

Hi,

I’m having trouble understanding what is the the correct and secure way to integrate Cossbar.io current authentication and authorization methods into my current system (PHP).

Currently I use application-defined user/password and roles, so my application itself manages authentication and authorization. Auth information is stored in PHP sessions (cookies).

I need to allow certain users to perform WAMP subscription.

Authentication itself is not a problem. I can implement a WAMP-CRA with a shared secret for my web-client, but how do i handle authorization?

In a classic PHP web request, the cookie is sent and the session get’s created, so i can identify the user and check it’s authorization against my backend. But a WAMP Web client (say, Autobahn|JS) has absolutely no clue witch user account is in use, so how will i treat authorization i my WAMP auth component?

Thanks in advance,

Pedro Peixoto.

0 Likes

#2

Hi Pedro!

AFAI understand your question, you need to implement some way of connecting WAMP sessionIDs to your backend user roles at the authentication for the session. Using this, you can then use dynamic authorization (http://crossbar.io/docs/Authorization/#dynamic-authorization) to do checks what a particular users is allowed to do.

Regards,

Alex

···

Am Mittwoch, 29. Juli 2015 15:04:30 UTC+2 schrieb Pedro Henrique Peixoto:

Hi,

I’m having trouble understanding what is the the correct and secure way to integrate Cossbar.io current authentication and authorization methods into my current system (PHP).

Currently I use application-defined user/password and roles, so my application itself manages authentication and authorization. Auth information is stored in PHP sessions (cookies).

I need to allow certain users to perform WAMP subscription.

Authentication itself is not a problem. I can implement a WAMP-CRA with a shared secret for my web-client, but how do i handle authorization?

In a classic PHP web request, the cookie is sent and the session get’s created, so i can identify the user and check it’s authorization against my backend. But a WAMP Web client (say, Autobahn|JS) has absolutely no clue witch user account is in use, so how will i treat authorization i my WAMP auth component?

Thanks in advance,

Pedro Peixoto.

0 Likes

#3

This is a problem I hit. Long story short, I solved this by not using dynamic authorisation at all and getting the session meta when each resource is called.

So it’s something like this in principle:

connection.onopen = function (session) {

session.register(‘com.me.findMyProfile’, function (args, kwargs, details) {

return getSessionDetails(session, details.caller)

  .then(function (sessionMeta) {

    var authId = sessionMeta.authid;

    

    if (!isAuthorised('com.me.findMyProfile', authId, kwargs)) {

      throw 'Not authorised';

    }

    

    return findProfileById(authId);

  });

});

};

You have to ensure the caller adds the “disclose_me: true” option to their call for this to work.

While the dynamic authorisation end-point does get the session meta, it’s not aware of the parameters that are passed to the end-point (so you can’t do an auth check on, for example, can user 123 view a list of articles in category 456 where the category ID is passed in the args).

Hope that helps. Still finding my way myself so if others have better strategies, feedback would be appreciated.

If you need help translating that snippet into PHP, let me know.

Regards,

Andrew Eddie

···

On Wednesday, 29 July 2015 23:04:30 UTC+10, Pedro Henrique Peixoto wrote:

Authentication itself is not a problem. I can implement a WAMP-CRA with a shared secret for my web-client, but how do i handle authorization?

In a classic PHP web request, the cookie is sent and the session get’s created, so i can identify the user and check it’s authorization against my backend. But a WAMP Web client (say, Autobahn|JS) has absolutely no clue witch user account is in use, so how will i treat authorization i my WAMP auth component?

0 Likes

#4

Hi Andrew,

Thank you for replying.

I’m not sure i got your strategy. Is that your application-defined authorization component? Let’s check this use case:

1- Client 1 (witch has already been authenticated) calls com.me.findMyProfile.

2- Crossbar allows it, since you are not using it’s authorization checking. It then routes the call to You component.

3- The component receives the call and executes:

3.1- getSessionDetails (can you post the code for that?), witch returns an object that contains the Client 1’s authid

3.2- If that client is authorized, it executes the real business logic of com.me.findMyProfile. Else it throws an error;

4- Back on the client side, the Promise will execute the appropriate callback with the result or the error reason (Will that throw trigger the onError method?)

So, as far as I understand you solution, your authorization check is an like stub, that runs just before the real business logic the procedure. As so, you would have to replicate that stub to each new procedure served in your realm (does not seem to scale well). Did I get it right? If so, how do you deal with another component (say, third party?) registering a new procedure, where you can’t guarantee that this same logic is not followed?

···

Em sexta-feira, 31 de julho de 2015 21:23:19 UTC-3, Andrew Eddie escreveu:

On Wednesday, 29 July 2015 23:04:30 UTC+10, Pedro Henrique Peixoto wrote:

Authentication itself is not a problem. I can implement a WAMP-CRA with a shared secret for my web-client, but how do i handle authorization?

In a classic PHP web request, the cookie is sent and the session get’s created, so i can identify the user and check it’s authorization against my backend. But a WAMP Web client (say, Autobahn|JS) has absolutely no clue witch user account is in use, so how will i treat authorization i my WAMP auth component?

This is a problem I hit. Long story short, I solved this by not using dynamic authorisation at all and getting the session meta when each resource is called.

So it’s something like this in principle:

connection.onopen = function (session) {

session.register(‘com.me.findMyProfile’, function (args, kwargs, details) {

return getSessionDetails(session, details.caller)
  .then(function (sessionMeta) {
    var authId = sessionMeta.authid;
    if (!isAuthorised('com.me.findMyProfile', authId, kwargs)) {
      throw 'Not authorised';
    }
    return findProfileById(authId);
  });

});

};

You have to ensure the caller adds the “disclose_me: true” option to their call for this to work.

While the dynamic authorisation end-point does get the session meta, it’s not aware of the parameters that are passed to the end-point (so you can’t do an auth check on, for example, can user 123 view a list of articles in category 456 where the category ID is passed in the args).

Hope that helps. Still finding my way myself so if others have better strategies, feedback would be appreciated.

If you need help translating that snippet into PHP, let me know.

Regards,

Andrew Eddie

0 Likes

#5

Sorry, I should have posted all of this in the previous message:

Here’s how I plan to solve my problem: Ditch dynamic auth. I’m going to use static crossbar-defined auth roles, and only deal with dynamic authentication. Here’s my scenario

1- Client loads a page (normal HTTP request) where this whole WS is needed.

2- Before opening the connection, the JS on the page will issue an ajax request to my backend:

2.1- In the backend, I can produce a one-time-only, application-defined authid-and-secret pair (this solves the problem of storing authid and secret in a Javascript, where anyone can read).

2.2- This pair is returned to the client page as JSON

3- The client opens the WS connection with the provided authid and secret. That connection get’s checked agains my custom authentication component, where I can check if that secret is still valid, and what role I am going to assign to it.

4- With the role information, the Router itself deals with denying the connection at all (if authentication fails) or denying specific action (pub, sub, call or register) the client took.

I chose to use crossbar-defined roles because I only have one frontend role, so it is simple to me to define it statically on the crossbar configuration. When all this is ready and proves to work OK, I may introduce dynamic authorization. To do so, I believe I’ll have to implement an additional WS role storage on my backend.

Feel free to comment about this approach, and point ou possible weak points.

Regards,

Pedro Peixoto.

···

Em sábado, 1 de agosto de 2015 11:04:58 UTC-3, Pedro Henrique Peixoto escreveu:

Hi Andrew,

Thank you for replying.

I’m not sure i got your strategy. Is that your application-defined authorization component? Let’s check this use case:

1- Client 1 (witch has already been authenticated) calls com.me.findMyProfile.

2- Crossbar allows it, since you are not using it’s authorization checking. It then routes the call to You component.

3- The component receives the call and executes:

3.1- getSessionDetails (can you post the code for that?), witch returns an object that contains the Client 1’s authid

3.2- If that client is authorized, it executes the real business logic of [com.me](http://com.me).findMyProfile. Else it throws an error;

4- Back on the client side, the Promise will execute the appropriate callback with the result or the error reason (Will that throw trigger the onError method?)

So, as far as I understand you solution, your authorization check is an like stub, that runs just before the real business logic the procedure. As so, you would have to replicate that stub to each new procedure served in your realm (does not seem to scale well). Did I get it right? If so, how do you deal with another component (say, third party?) registering a new procedure, where you can’t guarantee that this same logic is not followed?

Em sexta-feira, 31 de julho de 2015 21:23:19 UTC-3, Andrew Eddie escreveu:

On Wednesday, 29 July 2015 23:04:30 UTC+10, Pedro Henrique Peixoto wrote:

Authentication itself is not a problem. I can implement a WAMP-CRA with a shared secret for my web-client, but how do i handle authorization?

In a classic PHP web request, the cookie is sent and the session get’s created, so i can identify the user and check it’s authorization against my backend. But a WAMP Web client (say, Autobahn|JS) has absolutely no clue witch user account is in use, so how will i treat authorization i my WAMP auth component?

This is a problem I hit. Long story short, I solved this by not using dynamic authorisation at all and getting the session meta when each resource is called.

So it’s something like this in principle:

connection.onopen = function (session) {

session.register(‘com.me.findMyProfile’, function (args, kwargs, details) {

return getSessionDetails(session, details.caller)
  .then(function (sessionMeta) {
    var authId = sessionMeta.authid;
    if (!isAuthorised('com.me.findMyProfile', authId, kwargs)) {
      throw 'Not authorised';
    }
    return findProfileById(authId);
  });

});

};

You have to ensure the caller adds the “disclose_me: true” option to their call for this to work.

While the dynamic authorisation end-point does get the session meta, it’s not aware of the parameters that are passed to the end-point (so you can’t do an auth check on, for example, can user 123 view a list of articles in category 456 where the category ID is passed in the args).

Hope that helps. Still finding my way myself so if others have better strategies, feedback would be appreciated.

If you need help translating that snippet into PHP, let me know.

Regards,

Andrew Eddie

0 Likes