I'm looking for guidance as to how I should introduce authentication and authorization into my Rails application. I apologize if this gets long, but I'm trying to provide the context necessary to help me understand what roads I should go down to achieve this.
First off, my technologies:
Rails API BE
React FE
Business Requirements:
Invite only (Invite from root admin user)
Multiple types of users
Root Admin (invite users and assign types)
Users
Attorney, Paralegal, Client (each has different roles / capabilities)
Walkthrough
Root Admin User creates accounts for attorneys and paralegals. These accounts go out via an invitation to join.
Paralegals can create clients. When created, an invite goes out to the client to join the application. Paralegal assigns attorneys to be responsible for the clients.
Different Roles
Clients manage their own data
Paralegals can 'validate' client data
Attorneys can 'Approve' Paralegal changes
Bottom line:
We need each type of user to log into the application
Each user gets a role specific to their capabilities
These capabilities will involve different UI capabilities in React
React will need to know that
The user is authenticated
The user is authorized only for certain actions
These capabilities will involve REST calls to Rails
Rails will need to validate that
The user is authenticated
The user is authorized only for certain actions
I've done this in the past using Devise but am looking to move authentication and authorization to the cloud to allow for future app development ideas. That's where I'm not sure what to do. I've been reading a lot of different possibilities and at this point I'm just not sure which path I should choose. So I'm looking for advice how to pull authn/authz out of Rails and into the cloud.
After all this, I think my question is just -- could someone point me down which road I should go? AWS Cognito? Auth0? Stick with Devise? How does Rails work with cloud auth providers?
Really, just anything helps.
Any advice would be appreciated.
Related
I work for a company where we give customer (hundreds/thousands of users) access to 2 sites. One owned by a 3rd party SaaS and one owned by us.
Customers spend alot of time registering for both sites and we also spend alot of time removing accounts when customers no longer need access.
I would like users to register for Site A. After successful authentication; a user can click on a link within the site to access Site B but without the user entering credentials.
I want Site A identity to be used to access site B and its resources. I do not need site B resources to be presented on Site A site, but simply allow users to access site B if already authenticated to site A.
Users may have different roles on site B.
What is my best option? Oauth2 sounds like a good option. But will it satisfy my requirement above?
Who will manage the authorisation server? I presume Site B?
Thank you.
Two main options:
OLD TECH WITH COOKIES
Perhaps the cheapest option is to use hosting domains and have 2 apps like this:
mail.google.com
drive.google.com
Use a cookie issued to the parent domain, google.com
Cookie identifies user, to provide a user id
Rights are looked up in each app from the user id
OAUTH2 AND OPENID CONNECT
This is the option for modern apps and they are usually used together, due to being web, mobile and API friendly.
It is a big job though, including user migration, and usually involves giving users a new password. So it needs to be something your company are prepared to invest in.
The Authorization Server (AS) becomes a shared central resource and it is common to use a Cloud Provider to ensure high availability.
RELATED RESOURCES OF MINE
Initial Code Sample with Cloud AS
User Migration Blog Post
I recently switched to a new company where my manager wants me to develop entirely new cloud based project in MVC. I have never worked on a project from the start and I think this is a good opportunity for me to lead.
However, I think the requirements of the clients are bit confusing.
Here is what he wants:
Client should be able to access the cloud hosted application from his network with single sign on. He wants to use his active directory for that.
There are different users in active directory, they will have different roles (I think we can handle this on database side. Create different roles and assign roles to users).
Client has to add vendor info in the application. But for this, system should send an email to vendor with the url of the cloud application. He wants user to login to the application using 2 Factor Authentication. So, send dummy password with url, and send OTP to his mobile number. Just like registering to any system.
Now my questions are:
Is it possible to have 2 different types of login mechanisms in the same application? SSO for client and 2FA for outside vendors?
If yes, could you please guide me in the right direction?
what things I need? Which framework, design pattern should I prefer?
How do I proceed ?
I'm writing an application that will be the backend for a react website. The website is to be used by our customers, but we will fully control the permissions of the user. We have decided to use Azure AD to secure requests, but will also be exposing the API for end users to use directly if desired.
My understanding is in Azure AD I will have to create an application that will allow web based implicit authentication (for the react site), as well as a native application that will allow a dameon based application to authenticate to the API.
This I believe means I will have two audience ids in my application.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Sorry I'm just totally lost and the documentation is beyond confusing given how frequently this appears to change!
TLDR: Do I need two applicaitons configured in azure ad, and if so whats the best way to set permissions (claims). Also is oAuth 2 the right choice here, or should I look at open id?
Right away I gotta fix one misunderstanding.
Daemon apps usually have to be registered as Web/API, i.e. publicClient: false.
That's because a native app can't have client secrets.
Of course the daemon can't run on a user's device then.
Since that's what a native app. An app that runs on a user's device.
This I believe means I will have two audience ids in my application.
You will have two applications, at least. If you want, the back-end and React front can share one app (with implicit flow enabled). And the daemon will need another registration.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
Yes, ids are included only. If you need names, you go to Graph API to get them. But why do you need them? For display? Otherwise, you need to be using the ids to setup permissions. Names always change and then your code breaks.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Your thoughts for multi-tenant scenarios are correct. If you did want to implement these though, I made an article on it: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Why would you need to setup the roles in multiple apps though? Wouldn't they only apply in the web app?
If the native app is a daemon, there is no user.
Overall, I can see your problem. You have people from other orgs, who want access to your app, but you want to control their access rights.
Honestly, the best way might be to make the app single-tenant in some tenant which you control. Then invite the external users there as guests (there's an API for this). Then you can assign them roles by using groups or appRoles.
If I misunderstood something, drop a comment and I'll fix up my answer.
Azure AD is of course a powerful system, though I also find the OAuth aspects confusing since these aspects are very mixed up:
Standards Based OAuth 2.0 and Open Id Connect
Microsoft Vendor Specific Behaviour
ROLE RELATED ANSWERS
This is not an area I know much about - Juunas seems like a great guy to help you with this.
OAUTH STANDARDS AND AZURE
I struggled through this a while back for a tutorial based OAuth blog I'm writing. Maybe some of the stuff I learned and wrote up is useful to you.
AZURE SPA AND API CODE SAMPLE
My sample shows how to use the Implicit Flow in an SPA to log the user in via Azure AD, then how to validate received tokens in a custom API:
Code Sample
Write Up
Not sure how much of this is relevant to your use case, but I hope it helps a little on the tech side of things...
I am trying to get Sitefinity to work with MVC and JQuery Mobile and am having many issues....
The current issue is that I need to have users authenticate to access parts of the application. This authentication needs to be with an external service, the users logging into the front end will not be in the Sitefinity user base. I also need to have users who can log into the back-end to update the content, these users will be managed by Sitefinity.
To secure pages in MVC I add a authorize attribute on the controller. This needs to confirm the users on the front end have been authenticated by the external service, but still allow users logged into the back end to be able to updated content.
This is not working, when I hit the page with the authorize attribute on the front-end it is trying to take me to the sitefinity login. Has anyone found a way to make this work?
Well, I have a way to do it now, but I'm not all that excited with it...
I heard back from Sitefinity support and was given a few different ways to do this.
1) Create my own custom AuthorizeUser attribute, save the values when I authenticate to the session of a cookie, check for that value on the attribute...basically rewrite all the Authenticate functionality myself. - I'd really like to keep the Authenticate functionality as much as possible so I don't think I will do this.
2) Create a Custom Membership Provider, add this to the Sitefinity backend as a valid membership provider. This would be a good solution if I was wanting to store my users in a database and validate/update them. But, I am only validating against a service.
3) Create a dummy user in the Sitefinity backend with no access and definitely no backend access or admin access. After authenticating to my service if all is good then log into this user from the code. After this the [Authenticate] attribute finds that this user is logged in so all is good. As I do not need to check roles or claims in my app, just that user is logged in, this may work. It seems pretty ugly to me but I am assured that as long as the user does not have backend access or admin access it will not count to co-current users and many many users can be logged in as the same user.
I will go forward with option 3 and see how it goes and if I can get it past the architecture team.
here is the link where I found option 3 with some more info...
http://www.sitefinity.com/developer-network/forums/sitefinity-sdk/custom-authentication
James!
Not sure but I think your 3rd party service should use the Sitefintiy Single Sign On.
Maybe the following help topic on how to setup Sitefinity single sign on will be helpful:
http://www.sitefinity.com/documentation/documentationarticles/authentication-models-overview
I'm working on an MVC4 site using SimpleMembership to handle user accounts and role based authentication. We have another site and we'd like to implement a single sign on system allowing users from the existing site to log in to the one I am building. What would be the best way to achieve this and hopefully leverage to the existing roles based authorization I'm using on the MVC4 site. Is it possible to have multiple membership providers (i.e. use the built in one and if the user is not found, attempt to authenticate via a custom provider that I'll write (once I work out how!). Or would it be better to abandon the built in membership/roles and roll my own?
I also thought of letting WebSecurity check the local database and if the user is not found, query the 2nd database and if the users credentials are valid, create a local account for them. One issue with this approach is if a user called Fred registers on the MVC site, and then a user from the other site called Fred logs in, we couldn't create them a local account with the same username. We could prefix/suffix the username with some text to indicate that they are from the other site but then we lose the single sign on feature.
We will also want to integrate AD authentication for staff in the future.
So essentially I'm looking for the best way to authenticate users from multiple databases and keep using roles based authentication?
I've also done a little digging was wondering if ADFS might be useful for this.
Any help or advice would be greatly appreciated!
I recommend the use of an Identity server to handle all your login request and switching to a claim based authentication instead of a role based authentication if you can.
I personally went with Thinktecture IdentityServer
pluralsight.com have a good course on it.
Thinktecture IdentityServer is build on top of simple Membership and it supports multiple protocol such as
WS-Federation
WS-Trust
OpenID Connect
OAuth2
ADFS Integration
Simple HTTP
I recommend checking it
Good Luck