Best way to implement single sign on in Laravel? - laravel

I'm building an application that has a core hub, say it's called musictickets.com
We'll provide a subdomain (bandname1.musictickets.com) to bands on which only their content will display, which they can mask using a CNAME record to be part of their domain - so tickets.bandname1.com
There would be multiple bands using the platform so you'll end up with pages at
tickets.bandname1.com
tickets.bandname2.com
etc.
I'd like a user who registers at tickets.bandname1.com to be automatically logged in on every site that uses the service, including the parent, musictickets.com . They should be able to register/login using OAuth or directly via form based authentication.
I'm looking at SAML (specifically https://github.com/aacotroneo/laravel-saml2) as one option, but want to throw this out to the wider community for comment.
I've also looked at using token based SSO as described here (single sign on (sso) laravel) and running an auth server (which I may do in any case). Alternatively, I've looked at using iframes to provide the functionality which feels quick but dirty.
As I understand it, I wouldn't be able to use cookies (for an API key for instance) because whilst all of the content will be displayed via a subdomain, the CNAME would make it a different domain.
Does anyone have any thoughts on the best strategy?

Related

Multi Domain with single login,

I have been planning to create a laravel+vuejs apps stretching across subdomains (presentation creator, forms creator, polls creator etc.,each in a subdomain) and will have 2 version of the same web app (indian version with different languages and content and international with different language and content) in 2 different domain say domain.in and domain.com but I want users from any app or domain to login with the single user login say from passport.domain.com we have WAP versions of the websites served from wap.domain.in and wap.domain.com and also mobile apps for both.
Now, normal users based on the userid and password, the user from .com domain will
be able to access apps and content only from .com domain and .in
will be able to access only from .in
Users will be able to login using facebook, linkedin, google, etc.,
We will have only a single app for iOS and Android and based on the username and password the apps will be able to access corresponding domain.
wap sites will login using the same passport.domain.com
mobile app will be able to access data from the domain through an appID and Key.
others will be able to embed the presentations and forms into their website using an api key and secret.
certain users will be able to transfer data created in one domain to another user in the other domain
admin users will be able to transfer data from both domains.
other platforms may be able to login using the user id from this platform.
is all this part of SSO (Single sign on) ?
is this achievable in laravel ?
is it advisable to write the sign in server in a different framework ?
different tech like SAML Outh2.0 and Open ID with terms like Authorization, authentication and id provider make it all confusing and baffling for a start up.
can some one tell me what tech are involved in the above process. and what one should be aware before jumping in to start development.
That's a lot of questions :)
IS IT POSSIBLE?
OAuth 2.0 based technologies will give you the best options, since:
It has the most up to date app security options
It is designed to be web, mobile and API friendly
Access tokens are designed to cross domains
WILL OAUTH DO EVERYTHING?
No it will not - you will need to build most of the above behaviour yourself, and implement a software architecture, as for any other security technology.
An Authorization Server will externalise logins / passwords and issue tokens. Your apps will then need to implement 'flows' including:
Web token based security and session management
Mobile token based security and session management
API token validation and claims handling
Integrating third party security libraries
GUIDANCE
When new to OAuth tech the best choices and design patterns are not clear, as you indicate. If it helps, my blog has some details you may find useful, but it is not a simple journey:
Step by step tutorials and code samples
Design posts on the tricky areas
Blog Index
This is not a Solution but an article I stumbled upon which explain the terminologies involved in user authentication and SSO.
Laravel authentication an overview
Hope this helps others who are looking for an answer like me now or in future.

Secure public api for mobile app with laravel

I Guys, i have to create a mobile app that need to make a request to a laravel endpoint, app no require registration or login, which is the best way to protect my api? To make sure the only my application can call it?
Thanks!
There's no full proof method of securing your api, because with the right tools and following some tutorials on the web, anyone could view your whole api request, headers, tokens, etc.
Anything you do or store on the app is already compromised, so signatures,ssl, encryption,tokens, etc are not that helpful if malicious users have access to the app. It can make it more troublesome for malicious users, but a dedicated one could overcome it.
Using authentication atleast forces users to register before they can use your api and you can block the user when needed. Along with requiring email verification, users who wish to misuse your api would then need valid email addresses atleast. But since you mention securing without authentication, this goes out of scope.
You can secure your api somewhat by using rate limiting. laravel has an inbuilt rate limiting with the throttle middleware. You can use this to restrict the number of times an api can be called in a particular time interval by an ip address.
Next would be Ip blocking. If any malicious activity is found, you could block the ip address. But this can be overcome with a vpn, and a malicious user could also block someone elses ip in this manner.
Captcha can help against bots, but would also annoy regular users.
Another method would be restriction with cors, those who have faced cors issues know exactly how annoying it can be, but it wont work on native apps (or you could try pwa).
And in a worse case scenario you could go with some terms and conditions and some legal action
A simple solution You can create a table for devices with api key which will be generated for each device app, and always use it to send requests to the api end point, then used it to fetch data from the rest api. The same process like if you are loging in, but you will use the api key unstead and the key will be fixe not refreshed evrey time.

Create one or multiple projects for OAuth 2.0 for the company websites in different countries? (different prefix in URL and local content)

I am developing a structure in Google developer console to create projectsnd configure a OAuth 2.0 client IDs for our company websites. These we use to integrate Google login to the website.
We have around 50 websites now, where some are "company websites", then we have "product websites", etc. such groups.
For example group of company websites - those websites have exactly the same design, the same purpose, but are country specific, thus:
- differ in country prefix, e.g. countryA.companyxy.com, countryB.companyxy.com
- differ in content (types of content are the same, but the ontent itself is connected to the country, thus local)
- the language can be different (although mostly it's english)
I am seeking a recommendation as I cannot decide what is better:
1) Create one project per website and then different Client IDs for environments (prod, staging, dev) - this would be 50 projects, each with 3 Client IDs
2) Create one project per a group - e.g. company websites would have one project and I would create new Client ID for each country and each environment. This way I would have maybe 5-6 projects, each with 10-20 Client IDs.
Can those company websites all use the same application, or they should not?
If I've understood you correctly, this is a fairly standard multi-tenant application where a single app (from Google's perspective) lives at multiple domains. You can use a single Project and a single Client-ID, since in both cases, the ID relates to the app, not to the domain the app lives at.
So, when you start the OAuth dance, you always specify the same redirect URL, which handles OAuth for all domains. The trick is that you include a state parameter at the start of the dance which indicates which country/site your OAuth code should redirect to once the dance is finished.
So, roughly something like this:-
user visits countryA.companyxy.com and requests Oauth (eg. clicks a signin button)
You redirect to accounts.google.com?redirect_uri=common.companyfoo.com/oauth&state=countryA.companyxy
After auth, google will redirect back to common.companyfoo.com/oauth?state=countryA.companyxy
Your oauth handler does its thing, then parses the state param and redirects back to countryA.companyxy.com
Of course there might be administrative reasons for your company to prefer multiple projects and/or client IDs depending on your enthusiasm for admin, and how you wish to segment your data. To explain this last point using Drive as an example, if all companies have the same project, then the drive.file scope would give them all access to the files created by the app. However, if you have a project for each company, then Google sees these as created by different apps, so the are not visible using the drive.file scope.
I am seeking a recommendation as I cannot decide what is better:
I would align the Folder/Projects in the same structure as the company organization with a preference towards more projects (separation) instead of consolidation. Try to think of the chain of command and the distribution of resources. Factor in how you want security to separate resources. This might help figure out what should go where. Do separate development from production resources (separate projects).
Can those company websites all use the same application, or they
should not?
The answer is "it depends". If they all share a common domain name root, and they authenticate at the root, very easy to implement. The authentication cookies can be shared across domains. Otherwise, you will need to use multiple redirect_urls so that auth on one site completes on the same site. I am not sure what the limit is for Redirect URLs per Client ID.
To the second part of your question "or they should not". If the websites are designed to look like the same company then customers will expect to only authenticate once and be authorized across all sites. Is this a good idea, Yes. Is it the correct idea, this depends on your security requirements, isolation needs, etc. No simple answer here.

Organizing a secure channel between a Web app and a Native app

This question is kinda complimentary to "Share credentials between native app and web site", as we aim to share secrets in the opposite direction.
TL;TR: how can we securely share the user's authentication/authorization state from a Web Browser app to a Native Desktop app, so the same user doesn't have to authenticate additionally in the Native app?
TS;WM: We are working on the following architecture: a Web Application (with some HTML front-end UI running inside a Web Browser of user's choice), a Native Desktop Application (implementing a custom protocol handler), a Web API and an OAuth2 service, as on the picture.
Initially, the user is authenticated/authorized in the Web Browser app against the OAuth2 service, using the Authorization Code Grant flow.
Then, the Web Browser content can do one-way talking to the Native app, when the user clicks on our custom protocol-based hyperlinks. Basically, it's done to establish a secure bidirectional back-end communication channel between the two, conducted via the Web API.
We believe that, before acting upon any requests received via a custom protocol link from the Web Browser app, the Native app should first authenticate the user (who is supposed to be the same person using this particular desktop session). We think the Native app should as well use the Authorization Code flow (with PKCE) to obtain an access token for the Web API. Then it should be able to securely verify the origin and integrity of the custom protocol data, using the same Web API.
However, it can be a hindering experience for the user to have to authenticate twice, first in the Web Browser and second in the Native app, both running side-by-side.
Thus, the question: is there a way to pass an OAuth2 access token (or any other authorization bearer) from the Web Browser app to the Native app securely, without compromising the client-side security of this architecture? I.e., so the Native app could call the Web API using the identity from the Web Browser, without having to authenticate the same user first?
Personally, I can't see how we can safely avoid that additional authentication flow. Communication via a custom app protocol is insecure by default, as typically it's just a command line argument the Native app is invoked with. Unlike a TLS channel, it can be intercepted, impersonated etc. We could possibly encrypt the custom protocol data. Still, whatever calls the Native app would have to make to decrypt it (either to a client OS API or some unprotected calls to the Web API), a bad actor/malware might be able to replicate those, too.
Am I missing something? Is there a secure platform-specific solution? The Native Desktop app is an Electron app and is designed to be cross-platform. Most of our users will run this on Windows using any supported browser (including even IE11), but ActiveX or hacking into a running web browser instance is out of question.
The best solution : Single Sign On (SSO) using Custom URL Scheme
When I was checking your question, I remembered the Zoom app that I am using in my office. How it works ?
I have my Gmail account linked to a Zoom account (this is account linkage, which is outside the scope of implementation). When I open Zoom app, I can choose the option to login with Gmail. This opens my browser and take me to Gmail. If I am logged in to Gmail, I am redirected back to a page that asking me to launch Zoom app. How this app launch happen ? The application register a custom URL scheme when app get installed and the final redirect in browser targets this URL. And this URL passes a temporary secret, which Zoom application uses to obtain OAuth tokens. And token obtaining is done independent of the browser, a direct call with SSL to token endpoint of OAuth server.
Well this is Authorization code flow for native applications. And this is how Mobile applications use OAuth. Your main issue, not allowing user to re-login is solved. This is SSO in action.
There is a specification which define best practices around this mechanism. I welcome you to go through RFC8252 - OAuth 2.0 for Native Apps.
Challenge
You need to implement OS specific native code for each application distribution. Windows, Mac and Linux have different implementation support for custom URL scheme.
Advice
PKCE is mandatory (in IETF words SHOULD) for all OAuth grant types. There is this ongoing draft which talks about this. So include PKCE for your implementation too.
With PKCE, the redirect/callback response is protected from stealing. Even some other application intercept the callback, the token request cannot be recreated as the PKCE code_verifer is there.
Also, do not use a custom solution like passing secret through another channel. This will make things complicated when it comes to maintenance. Since this flow already exists in OAuth, you can benefit with libraries and guidance.
-----------------------------------------------------
Update : Protecting Token Request
While the custom URL scheme solves the problem of launching the native application, protecting token request can be challenging. There are several options to consider.
- Bind native application launch with a secret shared from browser
When browser based client launch the native client, it can invoke a custom API to generate a secret. This secret acts like a one time password (OTP). User has to enter this value in native app before it obtain tokens. This is a customization on top of Authorization code flow.
- Dynamic client registration & Dynamic client authentication
Embedding secrets into public clients is discouraged by OAuth specification. But as question owner points out, some malicious app may register itself to receive custom URL response and obtain tokens. In such occasion, PKCE can provide an added layer of security.
But still in an extreme case, if malicious app registers the URL plus use PKCE as the original application, then there can be potential threats.
One option is to allow dynamic client registration at the first time of application launch. Here, installer/distribution can include a secret that used along with DCR.
Also, it is possible to use dynamic client authentication through a dedicated service. Here, the application's token request contains a temporary token issued by a custom service. Custom service obtain a challenge from native application. This may be done through totp or a cryptographic binding based on an embedded secret. Also it is possible to utilize OTP (as mentioned in first note) issued through browser, which needs to be copy pasted manually by end user. Once validated, this service issue a token which correlate to the secret. In the token request, native client sends this token along with call back values. This way we reduce threat vectors even though we increase implementation complexity.
Summary
Use custom URL scheme to launch the native application
Browser app generate a temporary secret shared with a custom service
At native app launch, user should copy the secret to native app UI
Native app exchange this secret with custom service to obtain a token
This second token combined with call back authorization code (issued through custom url scheme) is used to authenticate to token endpoint
Above can be considered as a dynamic client authentication
Value exposed to user can be a hashed secret, hence original value is never exposed to end user or another client
DCR is also an option but embedded secrets are discouraged in OAuth world
As you mentioned, using a custom protocol handler is not a safe way to pass secrets, since another app may handle your protocol and intercept that secret.
If you are imposing a strict constraint that the communication channel between the native app and the web app is initiated from the web app, and that the native app has not previously established a secure channel (e.g. shared secret which could encrypt other secrets), then it is not possible to safely transmit a secret to the native app.
Imagine if this were possible, then PKCE would be redundant in an OAuth 2.0 Code Flow, since the server could have safely transmitted the access token in response to the authorization request, instead of requiring the code_verifier to be provided with the grant when obtaining the access token.
Just got the following idea. It's simple and while it doesn't allow to fully automate the setup of a secure channel between Web Browser app and the Native app, it may significantly improve the user experience.
We can use Time-based One-Time Password algorithm (TOTP). In a way, it's similar to how we pair a Bluetooth keyboard to a computer or a phone.
The Web Browser app (where the user is already authenticated) could display a time-based code to the user, and the Native app should ask the user to enter that code as a confirmation. It would then use the code to authenticate against the Web API. That should be enough to establish a back-end channel between the two. The life time of the channel should be limited to that of the session within the Web Browser app. This approach might even eliminate the need for a custom protocol communication in the first place.
Still open to other ideas.
You could try driving the synchronization the other way:
Once the user is authenticated into the web app, launch the native app from the web app via the custom URL scheme.
If the native app is not authenticated, connect securely to the backend over HTTPS, create a record for the native app, retrieve a one time token associated with that record and then launch the web app in the user's browser with the token as a URL parameter.
Since the user is authenticated in the browser, when the server sees the token it can bind the native app's record with the user account.
Have the native app poll (or use some other realtime channel like push notifications or a TCP connection) the server to see if the token has been bound to a user account: once that happens you can pass a persistent auth token that the native app can store.
Did you think about using LDAP or Active Directory?
Also OAuth2 could be combined, here are a related question:
- Oauth service for LDAP authentication
- Oauth 2 token for Active Directory accounts
SSO should be easier then too, furthermore access-rights could be managed centralized.
Concerning general security considerations you could work with two servers and redirect form the one for the web-application to the other one after successful access check. That 2nd server can be protected so far that a redirect is required from the 1st server and an access check could be made independent again but without need to login another time, might be important to mention here the proposed usage of Oracle Access Manager in one linked answer for perimeter authentication.
This scenario with two servers could be also hidden by using a proxy-server in the frontend and making the redirects hidden, like that data-transfer between servers would be easier and secure too.
The important point about my proposition is that access to the 2nd server is just not granted if anything is wrong and the data are still protected.
I read here some comments concerning 2FA and some other ideas like tokens, surely those things increase security and it would be good to implement them.
If you like the general idea, I'm willing to spend still some time on the details. Some questions might be helpful for me ;-)
EDIT:
Technically the design in detail might depend on the used external authentication provider like Oracle Access Manager or something else. So if the solution in general sounds reasonable for you it would be useful to elaborate some parameters for the choice of a external authentication provider, i.e. price, open-source, features, etc.
Nevertheless the general procedure then is that the provider issues a token and this token serves for authentication. The token is for unique one-time usage, the second link I posted above has some answers that explain token-usage very well related to security and OAuth.
EDIT2
The Difference between an own OAuth2 / OIDC server and a LDAP/AD server is that you need to program everything by yourself and can't use ready solutions. Nevertheless you're independent and if everything is programmed well perhaps even a bit more secure as your solution is not public available and therefore harder to hack - potential vulnerabilities just can't be known by others. Also you're more independent, never have to wait for updates and are free to change whatever you want at any time. Considering that several software-servers are involved and perhaps even hardware-servers the own solution might be limited scale-able, but that can't be know from outside and depends on your company / team. Your code base probably is slimmer than full-blown solutions as you've only to consider your own solution and requirements.
The weak point in your solution might be that you have to program interfaces to several things that exist ready for business-frameworks. Also it might be hard to consider every single point in a small team, large companies could have more overview and capacity to tackle every potential issue.

Google Apps Premium Edition: which authentication mechanism to use?

Our company has a web application that is only used internally by our employees. We also have Google Apps Premier Edition. We would like to make it so our employees can log into our private web application using the Google Apps account that they already have.
Requirements: We want to display our own login form. We don't want to pass the email/password in plain text through the internet.
Which authentication mechanism should we use to achieve this?
Note: our application is written in PHP using Zend Framework (if that matters).
I would look into some combination of OpenID and your domain users (i.e. only let those at domain.com can log in).
Google API
They also have libraries for PHP and other languages that you can leverage to make this happen.
EDIT:
Some more info
When it comes to integrate Google Apps and an internally used private system, we simply have two options.
Use Google as the authentication center. Modify the private system to authenticate at Google's server. We could use OpenID or AuthSub. Check http://code.google.com/apis/accounts/docs/OpenID.html and http://code.google.com/apis/accounts/docs/AuthSub.html for more information.
Use the private system as the authentication center. In this case, we have to implement SAML protocol in the private server and configure Google Apps's SSO settings. Check http://code.google.com/googleapps/domain/sso/saml_reference_implementation.html for more information.
It is easier to accomplish SSO with the first method since there's already bunch of OpenID libraries out there. But, as you described in the requirements, you want to use your own login form. So I guess you have to go with the second method.
BTW, if your private system has to get or set information from Google, you may want to use OAuth for authorization. See http://code.google.com/apis/accounts/docs/OAuth.html for more information.
Use the ClientLogin API, it does exactly what you're after: allow you to verify username and password. (the link goes to provisioning API doco but that is not relevant here)
Pro's:
you get to use you own login form
Cons:
you don't get SSO with Google Apps, i.e. users already in Apps will be prompted to login again (you didn't mention that as a requirement, but it seems a reasonable thing to want)
Google won't like you (they're trying to discourage ProgrammaticLogin.
you will get occasional CAPTCHA tests you'll need to show your users.
OpenID specifically prevents you from displaying your own login page, so if that's a hard requirements, Programmatic Login is really your only choice.
Going the SSO route let's you do pretty much anything, but may be a bit of overkill to take on authentication for the whole domain to make one app authenticate in a nicer fashion? If you really want to go down this route, check out SimpleSAMLphp.

Resources