Signing into my Gitlab CE installation with my app's login - node.js

I have a nodejs webapp with many users with a custom login process. I would like gitlab to accept that authentication and not force users to create a new app. What is the best way to accomplish this?

I would go for OAuth 2.0 Single Sign On (SSO). Below you can find the architecture diagram taken from here. As you can see the client is redirected to log in in the OAuth2 provider to get a valid token for authentication. The OAuth2 server must be configured for the application requesting access including the secret, the client id and the callback URL.
You can configure GitLab CE to sign in with almost any OAuth2 provider. Only be careful with the limitations:
It can only be used for Single Sign on, and will not provide any other access granted by any OAuth provider (importing projects or users, etc)
It only supports the Authorization Grant flow (most common for client-server applications, like GitLab)
It is not able to fetch user information from more than one URL
It has not been tested with user information formats other than JSON
You also need to configure your node js web application as an OAuth2 server. There are npm availables with the source code here.
Recommendation
I would install some open source Identity Management to separate the user management from your webapp, provides better integration with other third parties and forget about encryption and other stuff you need to take care in your webapp. There are multiple options such as KeyCloak for instance.

You have to define a dedicated user , and use the private_token of this user to login for ALL users that will use your application.
The restricition would imply all users will have the same rights ....
The other solution is to use the Private Token of the user at login. In this case , only the rights of these particular users will be used.

Related

Centralized identity management with different providers

I am going to build a web application that allows users to sign in with their Google or Twitter account. I think OpenID Connect(OAuth2) is the standard today to verify the identity.
I also want to provide several API services that can be only accessed with a valid access token from either Google or Twitter.
For example, all the four API's above are going to be public and so I have to protect from unauthorized users. For NodeJS based API services I can use http://www.passportjs.org/ to protect all APIs.
Assume, in the future the number of API's will be grow for example up to 20 API's and sign in with Facebook account will be also allowed.
Again, all the API's have to be protected and I have to do it 16 times with http://www.passportjs.org/.
In addition add the new provider Facebook, I have to do the changes on all 20 APIs.
The question is, is their a way to keep centralized, which means in the future when I will provide more the providers for example GITHUB for sign in I would like to do changes in one place not in 20 places.
Is the tool https://www.ory.sh/hydra what I need?
These are perhaps the two primary features of OAuth 2.0 and Open ID Connect:
Federated sign in to your UIs via multiple identity providers and the ability to easily add new options such as GitHub in a centralised manner
Full control over claims included in access tokens, so that your APIs can authorize requests however you'd like
FOREIGN ACCESS TOKENS
You should aim to avoid ever using these in your apps. Your UIs and APIs should only use tokens issued by your own Authorization Server (Ory Hydra), which manages the connection to the Identity Provider. Adding a new sign in method will then just involve centralised configuration changes, with zero code changes in either UIs or APIs.
IF YOU DON'T HAVE AN AUTHORIZATION SERVER YET
Maybe have a look at the Curity Identity Server and its free community edition - use sign in with GitHub, which has strong support for both of these areas:
Many Authenticators
Many Options for Issuing Claims
EXTERNAL RESOURCES
One exception to the above is that your APIs may occasionally need to access a user's Google resources after login, by calling Google APIs. This would require the token issued by Google. It can be managed via an embedded token approach - though it doesn't sounds like you need that right now.

Method for site wide authentication?

I am currently looking for a method to provide site wide authentication, for services exposed to the cloud, on the site I am responsible for. Some services are a Python based, some in PHP and some in Perl. Individual services would need to be able to get access to the user profile and the associated roles.
On the main page users are logged in and a cookie is created using a JWT token. The main site is using NodeJS for the auth system and is built in-house.
At this point I am wondering whether we should use OAuth2 across the site or whether there is another approach that may be simpler, where we don’t need to deal with inter domain requirements?
The approach you're currently investigating is the re-use of a JWT as an authentication token across multiple services. Although it's technically possible - it is not the ideal secure approach.
The most secure approach is for separation of application contexts, whereby each application should be tied to a different application credential (in OAuth2 terms). This is ensures that the user receives a credential unique to that application, allows the credentials to be managed/revoked separately and audited in isolation.
To implement this smoothly for UI flows requires an identity provider that supports SSO, and also assumes that each UI application can handle negotiation to the IDP to access that SSO session.
For interactions that are system to system authenticated, eg. Python, you would need to use system to system authentication (OAuth2 client credentials) that again have its own credential. In the case where you need access to the end-user's profile, a management api key (or similar) would be required.

Can this OAuth2 Native app flow be considered secure?

I have an OpenID Connect provider built with IdentityServer4 and ASP.NET Identity, running on let's say: login.example.com.
I have a SPA application running on let's say spa.example.com, that already uses my OpenID Connect provider to authenticate users through login.example.com and authorize them to access the SPA.
I have a mobile app (native on both platforms) that is using a custom authentication system at the moment.
I thought it would be nice to get rid of the custom auth system, and instead allow my users to log-in with the same account they use on the SPA, by using my OpenID provider.
So I started by looking on the OpenID connect website and also re-reading the RFC6749, after a few google searches I realized that was a common problem and I found RFC8252 (OAuth2 for Native clients), also Client Dynamic Registration (RFC7591) and PKCE (RFC7636).
I scratched my head about the fact that it was no longer possible to store any kind of "secret" on the client/third-party (the native apps) as it could become compromised.
I disscussed the topic with some co-workers and we came out with the following set-up:
Associate a domain let's say app.example.com to my mobile app by using Apple Universal Links and Android App Links.
Use an AuthenticationCode flow for both clients and enforce them to use PKCE.
Use a redirect_uri on the app associated domain say: https://app.example.com/openid
Make the user always consent to log-in into the application after log-in, because neither iOS or Android would bring back the application by doing an automatic redirect, it has to be the user who manually clicks the universal/app link every time.
I used AppAuth library on both apps and everything is working just fine right now on test, but I'm wondering:
Do you think this is a secure way to prevent that anyone with the right skills could impersonate my apps or by any other means get unauthorized access to my APIs? What is the current best practice on achieving this?
Is there any way to avoid having the user to always "consent" (having them to actually tap the universal/app link).
I also noted that Facebook uses their application as a kind of authorization server itself, so when I tap "sing-in with facebook" on an application I get to a facebook page that asks me if I would like to" launch the application to perform log-in". I would like to know how can I achieve something like this, to allow my users login to the SPA on a phone by using my application if installed, as facebook does with theirs.
I thought it would be nice to get rid of the custom auth system, and instead allow my users to log-in with the same account they use on the SPA, by using my OpenID provider.
This is what OAuth 2.0 and OpenID Connect provides you. The ability to use single user identity among different services. So this is the correct approach .!
it was no longer possible to store any kind of "secret" on the client/third-party (the native apps) as it could become compromised
Correct. From OAuth 2.0 specification perspective, these are called public clients. They are not recommended to have client secrets associated to them. Instead, authorization code, application ID and Redirect URL is used to validate token request in identity provider. This makes authorization code a valuable secret.!
Associate a domain let's say app.example.com to my mobile app by using Apple Universal Links and Android App Links.
Not a mobile expert. But yes, custom URL domains are the way to handle redirect for OAuth and OpenID Connect.
Also usage of PKCE is the correct approach. Hence redirect occur in the browser (user agent) there can be malicious parties which can obtain the authorization code. PKCE avoid this by introducing a secret that will not get exposed to user agent (browser). Secret is only used in token request (direct HTTP communication) thus is secure.
Q1
Using authorization code flow with PKCE is a standard best practice recommended by OAuth specifications. This is valid for OpenID Connect as well (hence it's built on OAuth 2.0)
One thing to note is that, if you believe PKCE secret can be exploited, then it literally means device is compromised. Think about extracting secret from OS memory. that means system is compromised (virus/ keylogger or what ever we call them). In such case end user and your application has more things to be worried about.
Also, I believe this is for a business application. If that's the case your clients will definitely have security best practice guide for their devices. For example installation of virus guards and restrictions of application installation. To prevent attacks mentioned above, we will have to rely on such security establishments. OAuth 2.0 alone is not secure .! Thats's why there are best practice guides(RFC68129) and policies.
Q2
Not clear on this. Consent page is presented from Identity Provider. So it will be a configuration of that system.
Q3
Well, Identity Provider can maintain a SSO session in the browser. Login page is present on that browser. So most of the time, if app uses the same browser, users should be able to use SPA without a login.
The threat here comes from someone actually installing a malicious app on their device that could indeed impersonate your app. PKCE prevents another app from intercepting legitimate sign in requests initiated from your app so the standard approach is about as safe as you can make it. Forcing the user to sign in/consent every time should help a bit to make them take note of what is going on.
From a UX PoV I think it makes a lot of sense to minimize the occasions when the browser-based sign in flow is used. I'd leverage the security features of the platform (e.g. secure enclave on iOS) and keep a refresh token in there once the user has signed in interactively and then they can sign in using their PIN, finger print or face etc.

Azure AD Login/logout implementation for Spring cloud microservices

I want to implement login and logout functionality and retrive user details like username and user role using Azure Active Directory.
We are using Docker to deploy Spring cloud microservices project on Azure cloud. Could you please suggest me steps to get user details?
Do we need to secure all microservices edge points using Spring cloud OAuth2 security using JWT or just we can secure one web microservice ? Do I need any permission ,specific user roles to implement this?
You can find Azure's documentation about OAuth 2.0 support for AAD here
https://learn.microsoft.com/en-us/azure/active-directory/active-directory-protocols-oauth-code
I've got an application that's using OAuth 2.0 with a different Authentication Server, and I'm about to see if I can use AAD as the Authentication Server. But, whatever ends up being your Auth Server, the rest of the application should be the same...
The Auth Server handles the log in (typically as a Single-Sign On pattern)
The Auth Server will return a Json Web Token (at some point, depending on the Grant Type being used to retrieve it)
The JWT should be included in each subsequent request to ensure the caller has authorization
From a Spring perspective, you'll need at least a SSO Client (denoted by the #EnableOAuthSSO annotation). If everything in hosted by that process, you'll need that JWT to call subsequent methods. If you have processes hosted in other processes, it's likely you'll want them secured as well. Using the #EnableResourceServer annotation will configure Spring Security to look for the JWT, just not attempt to retrieve one if the request does not have it.
Unless the endpoint is meant to be publicly accessible, you will want to secure it. Of course, I really don't know the context of your application, so this statement is purely an uninformed opinion based on zero knowledge of what you're trying to do with your application. Take it for what it's worth.
EDIT
This has become a little more complex than I originally thought. I have been able to write some code to dynamically retrieve the public key from Microsoft in order to validate the returned JWT.
But, the main issue is the fact the Azure AD supports Open Id Connect when acting as an Identity/Authentication Server. And, at the moment, spring-security-oauth2 doesn't support Open Id Connect.
I was able to make some small changes to the spring code, but I did ask the question to the Spring group and they are actively working on adding support for Open Id Connect. They hope to have a release two months (ish?).
For the short term, the oauth2 support doesn't support Open Id Connect. Given this is the protocol used by AAD, the current version of oauth2 won't work with AAD. That said, I will be happy to wait for the official support which shouldn't be too long.

Securing a nodejs / sailsjs API with OAuth2

I have developed a REST API with sailsjs and I'd like to add OAuth2 authorization to secure this API. I'm quite new to OAuth and I'm not sure where to start.
I found several modules that could be used for this purposes, for instance oauth2orize and an example of its usage https://github.com/aaron524/sails-oauth2-provider-example but I do not fully understand how this is working internally.
Basically, I'll have several clients consuming the API I'm developing:
- clients that I trust and that I'd like to use with the "Resource Owner Credential Authorization"
- clients that I do not trust and that will connect using the Authorization Code flow
I was thinking of adding a trusted property to the Client model within the sails application and then when a user will log onto an application:
- he will have a direct access to its resources (case of the trusted application)
- he will be requested to approve or deny the application from accessing his resources (case of the untrusted application)
Is this a good approach ? Any pointers on how to select the corresponding strategy based on the client trusted level ?
UPDATE
I've setup the following project on GitHub, using several tutorial and projects I found.
https://github.com/lucj/sails-oauth2-api
This project is not functional yet.
I'm still not clear on how to select the correct grant type (authorization code vs resource owner's password) when the user consume the API through an application. How to integrate this check in the policies ?
I do not manage to create the link between the OAuth endPoint (/oauth/authorize, /oauth/token) and the call to oauth2orize. Any idea ?
I finally struggled with Oauth2orize, sails and passport and managed to integrate OAuth2 security of my API in the project: https://github.com/lucj/sails-oauth2-api

Resources