I'm trying to create a simple SSO system in PHP for two domains which are thematically connected.
So I was wondering if it is possible to store a signed JWT token containing user username from domain A to the local storage. And then to verify the JWT using the same secret key from a domain B which would lead to a successfull authentication.
I've search google for some answers and I found some of them containing a middle authentication domain, which would take care of authentication. But I would like just to link the two domains I have.
Thanks.
Cross-origin data storage access from domain B to domain A is not allowed by same-origin policy
Access to data stored in the browser such as localStorage and IndexedDB are separated by origin. Each origin gets its own separate storage, and JavaScript in one origin cannot read from or write to the storage belonging to another origin.
The usual solution is to have a central domain for authentication ( could be A or B) and work with redirections among domains sending the JWT or share the authentication token across domains using an iframe. See details here
OpenId, OAuth and SAML protocol works with redirections, and for example Google web suite has their apps connected trough iframes (Additionally google is an openid-connect provider)
There's no reason why you can't do this. A JWT isn't really anything special, it's simply a token much like a session ID token. The difference between a JWT and any other token is that it can contain a payload of data.
What you're describing is essentially the password grant of OAuth 2.0. Your SSO system is the authorisation server which can authenticate users and supply them with an access token. The access token can actually be a JWT in this case too. The users (resource oners) can then use their access tokens to access resource servers (your other, related domains), those resource servers can verify that the access token is valid and allow or deny requests.
I use the following library when implementing OAuth 2.0 in PHP: https://oauth2.thephpleague.com/ - there's some good information in the docs too.
Related
I use firebase authentication in my laravel project and I am curious if there is such a way to give users roles/permissions.
Normally I use laravel authorization to get over it but now my user data are on the firebase.
Firebase Authentication (as its name implies) only handles authentication: verifying the user's identity. It intentionally does not provide any form of authorization: determining what the user's access permissions are.
Many of Firebase's other products have their own authorization mechanism that builds on top of Authentication, such as the server-side security rules of the Realtime Database, Cloud Firestore, and Cloud Storage.
You will need to do something similar in your own server-side code to implement authorization for your app. You'll typically follow this recipe:
Pass the ID token of the user from the client to your server-side code.
Decode and verify the ID token to securely determine who the user is.
Look up the authorization of the user, either in a data store of your own, and/or from the custom claims from their token.
Enforce that the user only accesses the data they're authorized for.
This is pretty much the same process that Firebase's own services also follow.
I'm building a very typical web app product. It will likely have corresponding mobile apps in the future. I'm building it from the ground up with a REST API, which is secured using OAuth2. I've got OAuth2 working, and I'm able to connect successfully using various grant types.
What I'm a little confused about is what grant types to use for the actual web app. Here's what I had in mind:
Public API access
Before a user logs into the web app, some API access is required for things like user registration and password resets. I was thinking of using the client_credientials grant type. A simple client id and secret validation in return for an access token.
However, it seems totally unnecessary to request an access to token for every single public request or even for each session. It seems to make more sense to just generate ONE access token that my web app will always use.
Yet, this seems to go against how OAuth is designed to work. For example, access tokens expire. What is the right way of doing this?
Private user API access
Next, for a user to login to the web app I was planning on using the password grant type (resource owner password credentials). This approach allows me to save the user_id with the access token—so I know which user is logged in. Further, by using scopes I can restrict access within the API.
I plan to save the access token within the PHP session. As long as the PHP session is active they will remain logged into the web app.
Is this an appropriate design for user login?
For Public API Access:
One method is to skip tokens all together and just use Basic HTTP Authentication for API access. You could accept Client Credentials for this, and limit what clients can do using client-specific scopes. Github offers HTTP Basic authentication using user credentials for all their API calls.
For Private user API Access:
This is an interesting question because it begins to breech the line between Authentication and Authorization. OAuth is used for Authorization, so logging in users becomes dicy. Session management, for example, is something not covered by the OAuth2.0 spec.
However, this is a common use of OAuth2.0 anyway. You can use the password grant type, or any other grant type for that matter, to obtain an access token. A major downside is they have to trust your application with their password (Not a big deal for your own app, but for 3rd parties not so much). Also, being logged in one place does not necessarily mean being logged in somewhere else (rather than SSO, you have "linked accounts", so the sessions are managed separately). One way around this is to ALWAYS send users to the oauth authorize endpoint, and if their session is active on the OAuth2.0 Provider side, reroute them back to the client app with an access token or authorization code. This way, if the session is active with the OAuth2.0 provider, the client can immediately log them in.
We are building an SaaS app, let's call it http://mysaasapp.com. When users sign up, they access their instance using a subdomain name http://myinstance.mysaasapp.com or a custom domain name http://instance.mycompany.com and so on.
We are looking at integrating with other services (Facebook, twitter, etc) so that our users can link to accounts on those services within their instance. Twitter is very lenient when it comes to OAuth redirect callbacks (the callback/redirect URL can be set by us when we make the OAuth request). Facebook, however, is not so leninent, the callback/redirect domain is set within the App's configuration on facebook.com
When users use a custom domain name on their instance, they can opt to make the subdomain (http://myinstance.mysaasapp.com) on our site inactive. This means we can't set the callback domain for OAuth to be mysaasapp.com and expect it to work.
The solution would be to use an OAuth proxy (http://proxy.mysaasapp.com). We have used HybridAuth previously, and we believe we should be able to easily turn it into a OAuth proxy.
Having said that:
Should we use the OAuth proxy to only proxy Auth requests? Once we get the access tokens, should we continue proxying the request through the proxy or should we just connect to the provider directly from our instance? In other words, are there any OAuth secured APIs that restrict API calls (after authentication) to certain defined domains?
How should I secure the OAuth proxy so that requests can only originate from instances of our app and responses can only go to instances of our app?
So here's what I ended up doing.
I created a very simple web app which is built around HybridAuth. This webapp would be hosted at oauth.mydomain.com.
What happens is that when the user at his own instance wants to connect to a provider such as Facebook, the app instance does a server to server connection to oauth.mydomain.com by posting the provider type and a few other information. The proxy returns a token.
We then redirect the user to oauth.mydomain.com while passing the token as a get parameter. oauth.mydomain.com invalidates the token and stores the information in the user's session.
The user then proceeds to authenticate with the provider. When this is successful, oauth.mydomain.com POSTs the consumer tokens and keys back to the instance at a special endpoint.
When posting is complete, we redirect them back to the page they were on at theirdomain.com
I have decided not to proxy all requests (only auth requests are proxied) because this is a simple method and providers (at least the ones I have looked at) only implemented domain restrictions during the auth process.
I'm planing to create a few simple REST web services to be used by some other applications (everything internal, not facing Internet). For certain reasons the applications should work with SSO (Windows, NTLM or other). The issue I have is how to do the authentication in the web service.
The application calling the web service has no knowledge of the users password so I'm kind of lost on how to authenticate against REST without having the user to login? eg. avoid Basic Authentication
I would like to avoid login due to simplicity for the user and not having to handle passwords in my applications. What are my options? Am I missing something obvious?
Would this be a solution:
create token, pass it to service and store it in database. web service checks if token exists in database. (expiration handling?)
The most common solution to this problem is, as you mentioned, a simple key or token based authentication. This is how a lot of google services (e.g maps) work. You simply generate a key on your service provider for each consumer, store it in your database, and validate that all calls pass a valid key.
More sophisticated options would be HMAC or OAuth authentication. Given your situation, i.e. providing services only within your intranet, I'd say keep it simple and go with a single key authentication.
In the above scenario I don't see the need for handling expiration. Nonetheless, if you'd like to implement it, then you could
on each client request, generate a timestamp based token on the server
in your reply to the request, also include this token
client should use both the static API key and the dynamic token in subsequent requests
server should check the token's lifetime and accept / refuse the request as necessary.
Twitter'll phase out HTTP basic authentication by August 2010. In the link my scenarios are from Desktop Applications. Basically my client should tweet new posts on a website.
This would be incredibly simple with HTTP basic auth, because I can store and use my account's username and password in the app to authenticate.
However, with OAUTH I can get final credentials by two means:
Callback method. You are redirected to Twitter, (login if isn't), click allow access, get redirection back to your callback URL.
PIN mode. You get a link to open, (login if isn't), click allow access, receive PIN code. Use this PIN code to authenticate your app.
Do I understand correctly that PIN codes also expire? How is it possible, given a username and password just to tweet from a client application? How can a server side script log in with the username/password and click allow access? All scenarios I could google up are for a web application to authenticate via twitter where the user is in front of the browser to walk through the redirect.
All scenarios I could google up are for a web application to authenticate via twitter where the user is in front of the browser to walk through the redirect.
The user has to be there to authorise you the first time (just as they'd have to provide you a username and password), but the resulting access token does not expire and can be reused (unless the user deauthorises your application, that is).
Store the access token - it's as good as a username/password. Better, actually - if they change their password, your access remains.
The PIN does expire under OAuth 1.0a. Using the verification code returned requires use of the temporary request token in the initial authorization request.
OAuth 2.0 defines more flows - one of which uses a direct login/password mechanism. It's up to Twitter to determine which flows they decide to implement. You can also embed a user-agent in the app.
Desktop apps suffered from a really bad user-experience with OAuth 1.0 which led to 2.0. It's doable, but painful. You can request XAuth access if you need to from Twitter as well. It's almost the same as basic auth.