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

ticket dynamic authentication like crossbar.io #125

Open
goldcode88 opened this issue Jul 6, 2018 · 16 comments
Open

ticket dynamic authentication like crossbar.io #125

goldcode88 opened this issue Jul 6, 2018 · 16 comments

Comments

@goldcode88
Copy link

goldcode88 commented Jul 6, 2018

how to implement ticket dynamic? "user.token.authenticate.d10" is provided by client in autobahn.py.
In nexus, I think "user.token.authenticate.d10" should be implemented in nexusd router. But no example can be referenced.

crossbar.io config.json partially.
```

 "auth": {
                        "anonymous": {
                            "type": "static",
                            "role": "public"
                        },
                        "ticket": {
                            "type": "dynamic",
                            "authenticator": "user.token.authenticate.d10"
                        },
                        "wampcra": {
                            "type": "static",
                            "users": {
                                "authenticator": {
                                    "secret": "******************",
                                    "role": "authenticator"
                                },
                                "usermanagement": {
                                    "secret": "****************",
                                    "role": "backend"
                                }
                            }
                        }
                    }
@gammazero
Copy link
Owner

This is definitely something I need provide both examples and additional documentation for. Until then, probably the best help is to look at some of the test code.

Client that tests simple CR auth handler:
https://github.com/gammazero/nexus/blob/master/aat/auth_test.go#L28

On the server side, a very simple CRAuthenticator is defined, and given a KeyStore:
https://github.com/gammazero/nexus/blob/master/aat/main_test.go#L105-L108
This is then provided to the server:
https://github.com/gammazero/nexus/blob/master/aat/main_test.go#L127

For a ticket authenticator, you can create your own or use the skeleton TicketAuthenticator provided with nexus (it is just a type of CRAuthenticator). Create a new TickerAuthenticator: https://github.com/gammazero/nexus/blob/master/router/auth/ticket.go#L23
...and supply a KeyStore implementation to return the user info from where your application keeps it.

Here is a unit test that provides a ticket authenticator and a CR authenticator:
https://github.com/gammazero/nexus/blob/master/router/auth/crauth_test.go#L116

The AuthKey method of the KeyStore returns the ticket:
https://github.com/gammazero/nexus/blob/master/router/auth/crauth_test.go#L37

I will provide some examples and docs very soon.

Consider using TLS
Generally, due to the need to protect ticket data, TLS is used to secure the client-server connections. If TLS is already in place, then the server can be configured to only trust certain client certificates. Doing that may remove the need to implement CR/Ticket authentication.

@martin31821
Copy link
Contributor

In our advanced router (to be open sourced soon) there is dynamic ticket authentication, as well as TLS authentication using a custom PKI, maybe you want to use this...

@gammazero
Copy link
Owner

@martin31821 I would be very interested to see how your authentication system fits with nexus.

I think the current ticket/CR authentication interface could be improved and made much easier to work with. TLS support is provided, but is basically what the golang stdlib provides, so having something that is better integrated into the rest of the auth stuff could be a good improvement.

@martin31821
Copy link
Contributor

I'lll see if I can get this into a good shape within the next week :) should work, we have currently docker images which are production ready

@gammazero
Copy link
Owner

@goldcode88 It looks like there is one thing nexus is missing to be able to provide dynamic ticket authentication as described in Crossbar. That is specifically the ability to make the ticket available in the session details after authentication success. If that is done, the the ticket can be used in the authorizer for the authorization of each message. I will fix this!

All of the other information available to Crossbar's dynamic authorization is also available in nexus. If you set EnableRequestCapture in the WebsocketServer then the authorizer will have access to all information from the websocket HTTP upgrade request.

@goldcode88
Copy link
Author

goldcode88 commented Jul 8, 2018

@gammazero @martin31821 Thanks!
I have implemented wampcra just now. Autobahn js client can connect to nexus server by wampcra authmethods.

"wampcra": {
                            "type": "static",
                            "users": {
                                "authenticator": {
                                    "secret": "******************",
                                    "role": "authenticator"
                                },
                                "usermanagement": {
                                    "secret": "****************",
                                    "role": "backend"
                                }
                            }
                        }

I'll try to implement dynamic ticket authentication after your fix.

@martin31821
Copy link
Contributor

Just pushed it: https://github.com/EmbeddedEnterprises/autobahnkreuz. However, docs are still lacking, we're working on it.
Docker image is available on docker hub, feel free to play with it.

@goldcode88
Copy link
Author

goldcode88 commented Jul 8, 2018

Thanks.
wampcra's config is a little complex. I change testKeyStore to CraKeyStore. CraKeyStore is compatible with crossbar's wampcra model.

type testKeyStore struct {
	provider string
	secret   string
	ticket   string
	cookie   *http.Cookie

	authByCookie bool
}

// new struct
type CraKeyStore struct {
  provider string
  users    map[string]CraUsers
}

type CraUsers struct {
  role     string
  secret   string
  ticket   string
  cookie   *http.Cookie

  authByCookie bool
}

By the way, Crossbar's wampcra model has a problem. It can't support the following request.

"wampcra": [{
                            "type": "static",
                            "users": {
                                "authenticator": {
                                    "secret": "******************",
                                    "role": "authenticator"
                                },
                                "usermanagement": {
                                    "secret": "****************",
                                    "role": "backend"
                                }
                            }
                        },
                     {
                            "type": "dynamic",
                            ... ...
                      }
                    ]

Maybe nexus is easy to implement the model

@gammazero
Copy link
Owner

One note of caution... If putting ticket into session details, then it will probably be necessary to enable MetaStrict in the RealmConfig. At this point I am thinking that making MetaStrict=true be the default/only behavior and if it is necessary for additional values from the session meta API, then explicitly list these in MetaIncludeSessionDetails.

@gammazero
Copy link
Owner

gammazero commented Jul 9, 2018

@martin31821 The autobahnkreuz API looks like it will make things simpler for the user. I see that your AnonymousAuth is providing a list of authroles:
https://github.com/EmbeddedEnterprises/autobahnkreuz/blob/master/auth/anon.go#L15
Is that something new in the WAMP spec or is this specific to your router?

I would like to integrate DynamicTicketAuth directly into nexus, if that is alright.

I still need a way to return the ticketObj, as mentioned to @goldcode88, so that it can be put into the session details. I could stash it in the Welcome.Details, under a special key that gets removed before the Welcome message is sent to the client, but that seems like a huge hack. I do not want to change the interface and break backward compatibility. I may need to create a place where extra details can be stored and retrieved later by the router, and provide additional API.

@martin31821
Copy link
Contributor

martin31821 commented Jul 9, 2018

For the first part: the spec states that the authrole should be a string, but the session details are specified as dictionary, so any router should tolerate the list (this is what we tested). Basically it allows us to add features to our application with different authroles at runtime and (re-) assign privileges. I'd also like to keep support for list of authroles within nexus, if that's fine for you @gammazero.

All of our authproviders return lists of authroles.
You can integrate the dynamic ticket auth into nexus, however our endpoints has not the same signature that is used in the crossbar router (that was changed in order to support keep-me-logged-in tokens).

I also think that crossbar does not store the ticket object anywhere within the router, since its only purpose is to assign authid/authrole to the client. IMHO storing the user passwords (==token) within the router seems like a security issue to me.

Edit:
Our primary motivation to write autobahnkreuz was to provide a router which is super easy to use, solves real applications problems (broken binary serialization, keep-me-logged-in, easy setup of TLS between your microservices, integration into any existing authentication providers, feature based procedure access etc.)

@gammazero
Copy link
Owner

@martin31821 Yes, certainly want keep support for list of authroles. My concern was was about what what to return in session meta events: wamp.session.get specifically calls for authrole to be returned as string. What do you return?
https://wamp-proto.org/static/rfc/draft-oberstet-hybi-crossbar-wamp.html#wampsessionget

@martin31821
Copy link
Contributor

The current implementation just returns the list, which is exactly what is desired. Maybe It would be feasible to add this to the spec, but I don't know what the maintainers think of this...

@gammazero
Copy link
Owner

@martin31821 Maybe there is a why to have it both ways? The session details could contain two different items: authrole and authroles. The first, authrole, would be the "effective" authrole and the second would be all the authroles that the client has membership in. This would be similar to the Unix group concept:

> id
uid=1001(ajg) gid=1001(ajg) groups=1001(ajg),0(wheel),20(staff)

An administrative meta procedure (wamp.modify.session_details perhaps) could be used to set the effective authrole, much like the Unix newgrp command.

@martin31821
Copy link
Contributor

@gammazero What's the advantage of having authrole and authroles? An authorizer would need to know both values anyway and it adds more complexity into the router implementation. Or do you think of any difference between the "primary" role and the other roles within the authroles dict?

For now, I'd just keep the implementation as-is...

@gammazero
Copy link
Owner

@martin31821 Yes, primary vs others is what I had in mind. Anyway, I think the current implementation is best since it does not force the session details to be any particular type, as long as they serialize. This allows whatever flexibility the router implementer needs.

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

No branches or pull requests

3 participants