I want to built a SSO Service with nodejs.
I have been looking in oauth methods and passport examples, but did not come to a conclusion.
I want to have an Identity Server like https://id.mycompany.com, where the user can create and edit his profile. He also should see what services he can use from my company.
There will be another resource like https://app1.mycompany.com. If the user enters this page he will be redirected to id.mycompany.com to authenticate, and if so, he will be redirected back to app1 with access granted.
Is this an oauth2 mechanism? Because I don't want the user to decide if app1 gets access. I want to decide which user have access to resources of app1.
So I need kind of oauth, but without the client_id part in the redirect url, because I own all Servers.
Hope you can help me, or what I need to search for.
Related
I've successfully integrated the saml2-js package with my node.js application, and I've confirmed that the authentication process is completing successfully. However, I'm not really sure how to properly put the app or routes behind the authentication. The saml2-js example doesn't cover that scenario (and maybe that makes sense). So how do I put the app behind the authentication?
I have successfully completed our SSO over SAML2.0 task in my organization, so I might be able to help you, at least I can share my experiences.
So here's how we did it
first of all you need to find out if a certain set of users want to do SSO. This isn't that trivial because before authenticating themself you don't know who wants to login to your system. In our case, we have big corporate users. So we can't just put a "Login by Okta" or "Login by ADFS" button for every customer, because some customer wants the IdP to be Okta, another wants it to be ADFS etc. We solved this by introducing subdomains, and we identify the corporate account by the url. Then we can check what IdP that corporate account wants to use and put a matching SSO button accordingly.
then, when the user clicks the SSO button you create the login request after which if the user successfully identified himself at the IdP you are ready to create a security context (a.k.a session). Then this session will guard you endpoints and app. When you created the session the user is actually "logged" in to your app.
I would like to use Active Directory with a REST API Express backend: users would fill out a username and login form on the client side, and get authenticated with their Active Directory credentials, through the backend. Then, based on their user groups, they would see certain information. I have tried the node package passport-windowsauth, but I am not able to authenticate, possibly because I don't know what the bindDN or bindCredentials are. I have also tried node-sspi, and had better luck with this, but the issue with this is that it's only server-side, and as far as I can tell, I can't create a form that would then allow the user to authenticate from the client side. I am hosting this site on IIS, and using iisnode for the backend. How can I can achieve this Active Directory authentication with Node/Express server-side and a client-side login form, or in other words, not a .NET application?
Active Directory (AD) authentication is accomplished by binding to the Active Directory with credentials (not the credentials from the User form) supplied by your AD engineers. After binding, AD is searched for matching credentials (from the User form).
Basically you need to talk to your AD engineers about what you should use.
Then you need a /login/ route the user form sends to, the route accomplishes the login (AD bind, authentication) and returns to the client.
A simpler workaround can be to bind to AD with the credentials entered into the login form - a successful bind means the user is logged in. I would, again, talk to your AD engineers about how they prefer this to be done. I've run into problems in the past where it's taken a long time to authenticate users after binding so we used this as a workaround.
You might ask if your AD already has single-sign-on options - maybe they use Shiboleth or something similar.
You should try that package : https://www.npmjs.com/package/ad I'm not sure it will meet your requirements, but it's a very easy t work with Active Directory in a node/express back end.
I'm trying to understand conceptually and practically how to perform an oauth2 with openID-connect flow in my web-api application, utilising Azure AD.
Importantly, when a request is made to the API I want to know who made the request.
My current understanding is :-
My client would detect that the user isn't logged in and redirect to a sign-in.
The user would provide their credentials, and be redirected back to the client, along with an oauth2 token.
This token would be supplied to web-api endpoints for any requests.
This is where it gets murky for me.
How exactly do I use this token to authorize access to a particular resource, determine who is accessing the resource, and what is the mechanism that does so?
I'm sort of assuming that I would need to reuse the token to make a call to the Azure AD user endpoint - if the token was indeed valid, the AD endpoint would return the users details - thereby providing some means of determining that the token is valid and providing details on the users identity. Authorizing access to a resource could be done through membership of groups in Azure AD.
BUT ...
I can only assume this a solved problem, and have noticed use of OWIN middleware as per this example
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
But I'm still rather unsure as to what is exactly going on.
The service makes mention of scopes and claims, but I don't understand where these are derived from (I assume from a token supplied by the client, but not sure). The service must be receiving identity information in the call.
Which brings me to two points, for this to be secure -
The token provided in call to the service would need to be secured in transmission (hence the use of HTTPS) - to prevent MITM.
The token would need to be signed some how - I guess by using client secret or something - to prevent information in the token being spoofed.
Can someone help me clear up this muddled mess?
In particular -
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
How to limit access to some endpoints of the API based on a user role?
What do I do to practically achieve this by building on existing middleware and libraries available to me?
Disclaimer: This will not be a comprehensive answer. It is off the top of my head.
OpenID Connect provides an identity layer on top of OAuth. In your case, Active Directory provides the authentication and sends back an access_token. The access token represents a user that AD has authenticated. If your doing OpenID Connect, then AD will also send an id_token, which may contain additional identity information (such as birthday, avatar, and whatever else AD exposes.)
Neither OpenID Connect nor Active Directory have anything to do with the the roles that your app assigns to a user; roles are entirely the bailiwick of your app. You assign user roles just like you normally would; you assign them to the nameid though instead of to an email address or username. Your app no longer has to authenticate the user but it does need to assign roles to the nameid.
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
The identity is embedded in the access_token that AD includes in its response. This token will have a nameid in it that your app can associate with a user and role. The nameid is like an email address, username, or other uniqueID that your app uses to recognize the user.
How to limit access to some endpoints of the API based on a user role?
You choose. When your app receives a request with a particular access_token, that token will be associated with a particular user via its nameid, and you can assign whatever roles and rights to that user. Basically, associate roles with a nameid.
What do I do to practically achieve this by building on existing middleware and libraries available to me?
There is an unfinished demo here, though it doesn't use Active Directory as the provider, instead, it uses an internal provider. For the demo, the username is shaun and password is Testing123!. The source code is here.
Here is the link to the source of another demo, though again, it doesn't use Active Directory as the provider, instead, it uses Twitter.
The nice thing about OAuth and OpenID Connect is that we can use whatever identity provider we want, so you can adapt the demos to use Active Directory.
Apart from question #1 (the identity is verified on the service side) all your question are very open ended and would require a super long answer.
I would recommend reading https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/ - it is a good introduction to the flows underlying many of the modern authentication cenarios, including the web API one you are focusing on.
Once you have read that, you will find a complete set of samples in https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/ - in particular, I suggest studying the web API and thru authorization one to find guidance on the 3 questions you listed. HTH!
I understand the security issues around attempting to use OAuth for authentication from a provider's point of view. However I've been asked to provide users the facility to log on to a new web application using OAuth and obtain their basic identity info from the likes of Google and Twitter, from which a new user account within the client application will be created. Additionally users will be able to regster/login directly via user/passwords for anyone not wishing to use third party accounts.
We do not require any access to the user's details/info or providers APIs, just their basic identity when they first logon, and of course allow them to login via the provider in the future. Not exactly the use case OAuth is intended for, OpenId would have been preferred, but OAuth has been specified and without valid concerns would need to be adhered to.
My question is how safe is it to assume that the user has correctly authenticated themselves with the relevant provider. If I trust say Google to perform adequate authentication and I obtain an access token and their identity, presumably I can consider that a legitimate user? There are obviously issues if some one has access to the resource owners machine and saved passwords in the browser but that issue is present for those users who elect to register directly.
Presumably it possible to fake an access token, e.g. man in the middle pretending to be google? A MITM could fake an access token and supply identity details that matched a registered user's google id? I don't see anything for a client to know that the information definitely came from the provider. Obviously this problem is not unique to OAuth.
Are there another ways someone could illegitimately access an account that used OAuth to authenticate themselves.
OAuth allows that an application to access a specific user resource (that has been provided permission by the user) and it cannot go outside that scope. I have not seen the documentation that refers to creating a new user using OAuth based application.
That being said:
We do not require any access to the user's details/info or providers
APIs, just their basic identity when they first logon
This violates OAuth authorization process. The Service Provider does the authentication and provides the relevant tokens (based on the success of the authentication). This is to ensure that there are no 3rd party authentication done during the OAuth authentication process.
My question is how safe is it to assume that the user has correctly
authenticated themselves with the relevant provider.
This all depends on the service provider itself. To conform to OAuth protocol, one of the requirement is that user authentication must be done in a secured transport layer with a digital certificate (for HTTP, it must be done in HTTPS). OAuth consumer don't have any reference to the authentication process. Also the authentication process basically asks the user if the consumer can access the resource of the specific user (and not anyone else, since he doesn't have authorization to it).
Is it possible to fake an access token, e.g. man in the middle
pretending to be google?
Spoofing a Service Provider IS possible but it'll be tedious. For one, you will have to create a whole OAuth handshake process, create the exact API as the service provider, also setup an environment that is secured (as OAuth recommends). The only thing the spoofing service provider can obtain is the client credentials. If it has its user credentials, there is no need to use the application as there is no way of providing a user credentials using an application to do malicious damage.
Secondly, access tokens do expire so even if you spoof and retrieve an access token, the original application owner can ask for the service provider to block the application and the access token can be useless.
A man in the middle attack won't be possible. You will have to replicate the service provider in a sense that the end user won't be able to distinguish between the original and the spoofing service provider in order to capture all relevant credentials (from both the application and end user).
Sadly saying, the scenario from your last sentence is the truth.
But you should realise that the security is a huge and complex issue, especially in client side. It's not happen just in a single point but many points through the whole internet access life cycle. The scenario you given is not what OAuth try to solve.
If I understand correctly, to make API calls from my desktop application (let's call it from now and on 'client' as in the OAuth2 standard) I need to obtain an access_token which is an identifier that combines both the application id and the user's, who's data I want to access, id ('resource owner').
Following client flow on the authentication guide (developers.facebook.com/docs/authentication/) I understand that I need to send request to h**ps://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=http://example.com&response_type=token. In result, the page will be redirected to h**p://example.com/#access_token=XXX. If the client is a pure desktop app, then redirect_uri can be h**p://www.facebook.com/connect/login_success.html. Since the client owns the web control the access_token can be easily extracted from the redirected address.
The client side flow consists of 3 OAuth steps:
User authentication, if resource owner is not logged in to Facebook, a dialog, asking for Facebook credentials, will be shown. If the resource owner is logged in, the session will be authenticated using the cookie on Facebook's servers. Security - CHECK V !
App authorization, if resource owner didn't give permission for the app yet, the permission dialog will ask from the resource owner to grant permissions to the app, if the resource owner previously grated all needed permission, the permissions dialog will not be shown. Security - CHECK V!
App authentication - Now, here is where it gets sticky. The guide says: "App authentication is handled by verifying that the redirect_uri is in the same domain as the Site URL configured in the Developer App". Security - In my opinion - FAIL!
Why do I think that the last step is a security fail? First of all, both app id and redirect_uri are public information that anyone can obtain. Second of all, redirect_uri can be h**p://www.facebook.com/connect/login_success.html.
Let's look at the following scenario. A desktop app, EVE, shows to the user a web control where the user logs in to facebook and grants EVE some basic permissions. Resource owner has no reason to suspect anything. Next, EVE hides the the web control, and tries to load on it h**ps://www.facebook.com/dialog/oauth?client_id=OTHER_APP_ID&redirect_uri=http://www.facebook.com/connect/login_success.html&response_type=token. The app can try and load this url with the most popular facebook apps application ids. The app will get the Success message if the user previously authorized the OTHER_APP, since both login dialog and permissions dialog will not be shown. This will give EVE an access_token to access all resources of the resource owner that the resource owner granted to OTHER_APP and not to EVE.
So, is this a security hole? Did I miss something in the follow?
(UPDATE)
Clearly in a case of a desktop app, the security issues are irrelevant since the app has already the username and the facebook session and even the username and password, it can do anything with the users account.
(UPDATE)
For JavaScript apps that run in a web browser redirect_uri actually works! (See answer and comments by hnrt).
CURRENT QUESTION:
The only remaining mystery is how the client authentication works on iPhone and Android apps? Is the security whole is similar to the one when using a desktop application? Is there some difference in jailbreaked iPhones or rooted Androids?
Cheers!
If I understood correctly, your scenario would require that the user has already authenticated himself for the other apps using the same web control that EVE can use to talk to Facebook. If that is the case, then there are already much bigger security problems :) EVE could just hijack the whole session and all its authentication tokens.
[UPDATE] Regarding Javascript applications, same origin policy prevents EVE from accessing the reply of the /dialog/oauth?client_id=OTHER_APP request. The only way to access the data is to wait at redirect_uri and parse the redirected request. Here the "site url"-protection kicks in.
I am not sure how things work in iPhone and Android applications, but I would be really surprised if their web controls allowed access to the authentication data (=cookies) of other applications.