I don't have a specific technical issue but a general problem understanding the architecture for using Auth0 for Authentication and then using the returned profile to access a rails API.
I am using Auth0.Lock in React Native and can successfully sign-up and login to my React Native App and store the returned profile and token.
On the Rails side I have create an API and setup Knock (https://github.com/nsarno/knock) as per the instructions to implement JWT Authentication.
What I don't understand is the link between my User model in Rails and my Database in Auth0. Neither the Auth0 documentation or the Knock documentation are clear on how this association happens.
Thanks
Craig
I've created two example projects, a rails API and a front-end app that illustrate auth0 integration in rails. I'm presuming scope claims are present in the tokens to demonstrate at a very basic level how authorization would work in such scenario.
The frontend uses AngularJS, but this is mostly irrelevant as the logic is very basic and can easily be rewritten in any framework.
As joão-angelo hinted, using tokens mostly defeats the need to have a user model at all, you can of course define a user class as convenience wrapper in runtime, but you don't have to store it in the DB. In fact, having user models living in your app and in auth0 may be counter productive, as you'll have to keep them in sync.
Hope this helps!
From looking into the available documentation the following should be possible.
By defining the appropriate scope you can instruct Auth0 to include specific information - claims - within the ID token returned as the outcome of a successful authentication.
If all the user profile information is included in the token itself you can then use Knock in such way that it will create the user model instance from the JWT payload itself without any need to query additional stores.
By default, Knock assumes the payload as a subject (sub) claim containing the entity's id and calls find on the model. If you want to modify this behaviour, implement within your entity model a class method from_token_payload that takes the payload in argument.
class User < ActiveRecord::Base
def self.from_token_payload payload
# Returns a valid user, `nil` or raise
end
end
(source: Knock Customization)
With this approach the token itself is sufficient and there is no further interaction between the Rails API and Auth0. The user model is created from the token and the Auth0 database is not directly accessed by Rails API, it just uses the information stored there and surfaces on the token.
It should be possible to go with other approaches with more direct interaction with the Auth0 database. If you need to go down that route you should look into the Management API (user related endpoints) as a way for you to interact with the Auth0 database from your own application.
Related
I'm working with authlib for an oidc provider server. I'm using example-oauth2-server as a learning tool. I'm trying to understand why, in the database schema, the User_ID is tied to the client. I understand this is an oauth2 server as opposed to oidc. But the confusion still stands. Am I meant to be registering a client for each human/service user? This isn't a requirement in either oauth2 or oidc right? In fact there's nothing at all in oidc client registration docs about a user_id field in relation to client metadata.
In a different oidc library I used, the registration is "user agnostic" for the lack of a better phrase. I can't wrap my head around why it should not be. I mean, I CAN create a client for each user, but why should I want to do so if I wanted, for example, an Android app capable of authentication and authorization via my oidc provider? Could I not achieve something similar (assuming the purpose is to specifically identify which user is logging in,which, you can determine by the fact that said specific user is logging in) by storing the user_id in some other table?
Any direction or even discussion would be appreciated.
I have a shopping cart application built using Javascript (ReactJS). The app will all listing products, adding them to cart and performing a checkout.
When a user arrives at the site, the APIs will be invoked by the Javascript client to obtain Product Listing, Categories etc. When someone clicks on a Product, the APIs will also provide Product details.
At no point do I require the User to log on to the system. I cannot also keep my API open. We are using IdentityServer4 to manage the APIs.
I can't use Client Credentials flow here (which is suited for Machine-to-Machine flows) because I can't keep secrets in Javascript.
I can't use Implicit Flow because it works on the principal of User Login, whereas I don't need the User to login at all.
What flow should I use? Is there a way to change the implicit flow to work without requiring a user login?
Would using an API Key be a better approach?
Any feedback would be awesome.
You can't change the implicit flow, it is literaly an user login flow.
I think you need to think about what you want to protect here.
You need to allow everybody ( anonymous) to call some methods: f.e. GetProduct.
You need to secure the sensitive methods with login requirements like checkout.
I wrote an API in rails which is of micro services architecture.
In my API i need to implement Role authorization to authorize each and every user using their roles.
Is there any gem that fits into micro services architecture or should I write my own logic to authorize users.
i was using gem authorization gem but it does provide much capability that fits into micro services architecture.(rolify)
Is there any other that suits micro services architecture?
Thanks in Advance.
Whenever you have to implement MicroServices in Rails, then I prefer to put your authentication and authorization (role based permissions) using JWT (JSON Web Token). Because in MicroServices, there are multiple different projects which are deployed on different servers and communicating with each other through APIs and you require only one API Gateway, where user provides the login credentials and its should work for all different projects. I wont prefer devise because it creates a session after successful login which is Stateful, while JWT is Stateless.
Statelessness means that every HTTP request happens in complete isolation. When the client makes an HTTP request, it includes all information necessary for the server to fulfill that request. The server never relies on information from previous requests. If that information was important, the client would have sent it again in this request.
In case of JWT, each request comes with a token something like "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NjUwOTYxMzMsInN1YiI6MX0.e9yeOf_Ik8UBE2dKlNpMu2s6AzxvzcGxw2mVj9vUjYI" which will contain all required info in its payload for login. Please refer https://restfulapi.net/statelessness.
The token should also include the role or permissions (e.g. admin role) of user and based on role it should fetch the data and its relatively faster than Stateful requests. Because in case of Stateful requests (as happens in traditional Web Apps), it stores the session_id in cookies and sends the session_id with request. So on server side, first it fetches its user info and check whether its valid user, then fetch its role and then after successful authentication and authorization, it fetches requested data. While in case of JWT, since the role and username comes within token itself which would be decoded on server side, and directly fetches the requested data from DB. JWT (or Statelessness) helps in scaling the APIs to millions of concurrent users by deploying it to multiple servers. Any server can handle any request because there is no session related dependency.
Difference between Stateful and Stateless, please refer https://restfulapi.net/statelessness and https://nordicapis.com/defining-stateful-vs-stateless-web-services.
For more info about the implementation, please refer http://pacuna.io/2016/06/03/rails-and-jwt and https://github.com/nsarno/knock.
The devise gem is the leader in the industry. All of its methods are fully customizable - they can be used as a before_action (typical usage but not ideal for micro services) and can also be used as just another method in your code (inside a block, in a 'if' statement, etc). Checkout the github page here
https://github.com/plataformatec/devise
It has so much functionality, I could teach en entire course on this gem. There's a lot to learn if you aren't familiar yet.
Thanks for the Answers guys,
Coming to the answer,i have implemented my own way of authorization.
I had come up with a design where User -> Roles -> Resources -> Permissions
Here the resources are individual parts where every user has some permissions upon using a resource and role has set of defined set of resources with some permissions like
read_only,read_create,read_update etc
Each user can have any number of roles, thus user having a permission to access a specific resource.And i perform this check for each action using
before_action
Thanks,
Suresh
I have a rails web which has been using cookie session authentication (devise) from its beginning. Now, we are developing an ionic mobile application which uses the API available from the rails application.
I have considered to use JWT or token authentication for this new application but I can't find a way to combine both authentication methods, cookie and JWT. Also, both applications have different requirements. For example, in the web a user can have concurrent sessions only if he/she has a certain role. On the opposite, in the mobile application it is possible to have concurrent session without any restriction.
I have reading a lot trying to figure how to combine both methods but I can't find the way. Maybe I should consider to use only one of the methods (JWT) or use another approach (doorkeeper).
Finally I have found a solution. According to refaelos and Zac Stewart, I have combined devise with JWT gem, using the last as a new strategy for the first. By this way, when I don't use JWT tokens, devise will choose the default strategy (database_authenticatable in my case). Otherwise, it will use JWT strategy.
However, when the user is not authenticated and make a post request to Session#create to get the credentials, the strategy chosen by devise/warden is database_authenticatable. In order to avoid this, I needed to add a new parameter to the request but only for this case because, as I said, when the token appears in the request, the new strategy is selected.
See also:
An Introduction to Using JWT Authentication in Rails
I'm learning about developing APIs with rails, but I can't find how to secure the base methods like user creation. Let's say I have a rails backend API and a frontend mobile app. I want the app to be able to make API calls to create a new user. Off course, not everyone should be able to create a new user, so it should have some kind of authentication. I could use basic or digest authentication (doesn't really matter, because I'll definitely use SSL), but then I would have to hardcode the credentials into my app. If the credentials are discovered somehow, I would have to change them, but that would mean that all instances of the app are no longer authenticated and they can't create users anymore.
The things I would like to have:
Only my apps should be able to use the user creation calls.
It should be easy to change the credentials, or the credentials should change automatically over time. If they would involve the date and time for example, it would be harder to crack.
It should be impossible (or VERY hard) to beat the system behind it, while having knowledge of a couple of the credentials over time.
Would it be possible for example to let my apps generate public and private key pairs at random and use them? What's the standard way of securing these calls?
Thanks in advance,
Rugen Heidbuchel
I could share my own experience:
https protocol communication with API. That is your last sentence about private/public keys, all is built in into https.
Doorkeeper (we combine it with Devise) gem for Oauth (github accounts in my case) as authentication, while you can use pairs of user/passwords instead.
CanCanCan gem as authorization (User creation restriction is about authorization and not authentication)
Set of that three tools should provide essential security level for your API. I believe cancancan could be under discussion, while devise is mostly industry standard.