My Node.js (MeteorJS) site will be interacting with a 3rd party platform via SSO using SAML 2.0 (their requirement). Essentially, when a logged-in user (on my site) clicks a specific link on our site, we're supposed to create a SAML token (with some specific attributes related to the user, in addition to required SAML 2.0 ones) and then POST it to the 3rd party platform's URL. They will process the token and then send a redirect to the user's browser, which will redirect the user to the 3rd party platform's site with the user being logged into the 3rd party platform's user account without the user having to log into that system, specifically. (Sorry for the re-stating of SSO basics, but I just want to be thorough to explain our the situation at hand).
The 3rd party platform is acting as the Service Provider (SP), and they have provided me with the payload attributes I need to add to the SAML Assertion (unencrypted is fine) to properly log the user into their system.
I have asked the support team at the 3rd party platform some questions about what I need to do on my side to set up the SAML engine. I have never used or implemented SAML before, so I'm learning on the fly and researching everything I can find heavily. Anyway, the support member said the following:
Your SAML engine (acting as the IDP) creates your SAML token and that
token is just posted to the [3rd party platform's] endpoint. From
that point you’ve given all control to [the 3rd party platform] and we process the token with intent to return the redirect back into your browser window.
Since we're acting as our own IDP (we know who the logged-in user is, and we know the information that we need to send over in the SAML token based on their user account), it appears that all I need to do is create a SAML token with the appropriate attributes and just HTTP post it programmatically. Am I missing anything?
With SAML being an "older" technology and Node being a "newer" one, the documentation on implementing a SAML engine in Node is quite sparse. Most everything I see regarding SAML and Node (here on S/O and elsewhere) usually points to passport-saml, and the like, with some vague examples related to token authentication and IDP endpoints. From what I'm gathering, it seems like most all of that is overkill for what I need to do, but being a complete SAML newbie, I'm not totally sure and I'm looking to you all for your guidance.
The abridged version of my question is:
If I just need to POST a SAML token in a Node environment, is it as simple as creating a token with the payload attributes and setting that token programmatically in a FORM where the action is the URL provided by the 3rd party SP and the response is the SAML Assertion token? Also, what recommendations do you have for Node libraries (or at least examples with details) that would create that token for me? Most all examples and libraries I see appear to be overkill for what I actually need to provide, but having no reference to compare against, I'm not sure.
Many, many thanks to anyone who can help me out with this one!
Related
My situation is this. I have a legacy Angular application which calls a Node API server. This Node server currently exposes a /login endpoint to which I pass a user/pwd from my Angular SPA. The Node server queries a local Active Directory instance (not ADFS) and if the user authenticates, it uses roles and privileges stored on the application database (not AD) to build a jwt containing this user's claims. The Angular application (there are actually 2) can then use the token contents to suppress menu options/views based on a user's permissions. On calling the API the right to use that endpoint is also evaluated against the passed in token.
We are now looking at moving our source of authentication to an oAuth2.0 provider such that customers can use their own ADFS or other identity provider. They will however need to retain control of authorization rules within my application itself, as administrators do not typically have access to Active Directory to maintain user rights therein.
I can't seem to find an OIDC pattern/workflow that addresses this use case. I was wondering if I could invoke the /authorize endpoint from my clients, but then pass the returned code into my existing Node server to invoke the /token endpoint. If that call was successful within Node then I thought I could keep building my custom JWT as I am now using a mix of information from my oAuth2 token/userinfo and the application database. I'm happy for my existing mechanisms to take care of token refreshes and revoking.
I think I'm making things harder by wanting to know my specific application claims within my client applications so that I can hide menu options. If it were just a case of protecting the API when called I'm guessing I could just do a lookup of permissions by sub every time a protected API was called.
I'm spooked that I can't find any posts of anyone doing anything similar. Am I missing the point of OIDC(to which I am very new!).
Thanks in advance...
Good question, because pretty much all real world authorization is based on domain specific claims, and this is often not explained well. The following notes describe the main behaviors to aim for, regardless of your provider. The Curity articles on scopes and claims provide further background on designing your authorization.
CONFIDENTIAL TOKENS
UIs can read claims from ID tokens, but should not read access tokens. Also, tokens returned to UIs should not contain sensitive data such as names, emails. There are two ways to keep tokens confidential:
The ID token should be a JWT with only a subject claim
The access token should be a JWT with only a subject claim, or should be an opaque token that is introspected
GETTING DOMAIN SPECIFIC CLAIMS IN UIs
How does a UI get the domain specific data it needs? The logical answer here is to send the access token to an API and get back one or both of these types of information:
Identity information from the token
Domain specific data that the API looks up
GETTING DOMAIN SPECIFIC CLAIMS IN APIs
How does an API get the domain specific data it needs from a JWT containing only a UUID subject claim? There are two options here:
The Authorization Server (AS) reaches out to domain specific data at the time of token issuance, to include custom claims in access tokens. The AS then stores the JWT and returns an opaque access token to the UI.
The API looks up domain specific claims when an access token is first received, and forms a Claims Principal consisting of both identity data and domain specific data. See my Node.js API code for an example.
MAPPING IDENTITY DATA TO BUSINESS DATA
At Curity we have a recent article on this topic that may also be useful to you for your migration. This will help you to design tokens and plan end-to-end flows so that the correct claims are made available to your APIs and UIs.
EXTERNAL IDENTITY PROVIDERS
These do not affect the architecture at all. Your UIs always redirect to the AS using OIDC, and the AS manages connections to the IDPs. The tokens issued to your applications are fully determined by the AS, regardless of whether the IDP used SAML etc.
You'll only get authentication from your OAuth provider. You'll have to manage authorization yourself. You won't be able to rely on OIDC in the SAML response or userinfo unless you can hook into the authentication process to inject the values you need. (AWS has a pre-token-gen hook that you can add custom claims to your SAML response.)
If I understand your current process correctly, you'll have to move the data you get from /userinfo to your application's database and provide a way for admins to manage those permissions.
I'm not sure this answer gives you enough information to figure out how to accomplish what you want. If you could let us know what frameworks and infrastructure you use, we might be able to point you to some specific tools that can help.
Right now I'm rolled in a project where we want to create an SAML IDP with Node.
Problem:
We have a system that implements an API REST and this API authenticates users, its response has the information of the authenticated user... just as an API response (nothing about SAML).
The point is to aggregate the responses from the API in a SAML IDP system, where some SAML requests (XML) arrive from Service Providers. The SAML IDP system internally queries the API, gets the authentication information, and responds as a SAML Response (XML) to the Service Provider.
I was looking for easy solutions for this problem like Okta, OneLogin, but the problem is that those companies authenticate the user and the one who authenticates in my system is the API, I can't change that because the project was defined as that.
My question is:
Do you know about a system that provides SAML configurations but authenticates with an external API?
We are using samlify Node Library to attack this problem, do you have information about the performance of this library?
Do you have any idea how to solve this problem easily?
We are planning to deploy with lambdas is this a good practice for this kind of problem?
I'm not an expert about SAML so if you have documents about creating a SAML IDP or any help would be useful.
Thank you for reading and sorry for my English.
Do you know about a system that provides SAML configurations but authenticates with an external API?
First, you have to remember that SAML is a protocol; it's the language that a service provider may choose to speak to the identity provider. The task of validating user credentials and authenticating a user is entirely separate from the protocol. An SP may choose to send a SAML authentication request to an IdP, and the IdP is free to authenticate the user however it sees fit. The two usually have nothing to do with each other.
Second, there are plenty of IdPs that allow you to:
Turn on the SAML2 functionality so the IdP can speak the SAML2 protocol.
Validate user credentials using a custom REST API. The IdP would reach out to your API to validate the credentials it receives from the user, and would the finally produce a SAML2 response back to the SP.
An example of such an IdP would be: https://github.com/apereo/cas. It allows you to have it act as a SAML2 IdP and supports a REST API for user authentication.
While it may not 100% fit your use case OOTB, it's a good starting point. You should never begin from scratch and re-invent the wheel. To "create a SAML IDP that authenticates with an API from scratch" is generally a good way of asking for a lifetime of punishment.
PS Your other questions should likely be posted as separate posts/questions.
Please bear with me while I explain my problem and the solutions/guides I have found.
Description: In my company, we have one product that have multiple modules. Each module is its separate backend and frontend. We have JavaEE/JakartaEE with JAX-RS as our backend stack and React as for our frontend. Until now we are using Basic Authentication using the JavaEE Security via Sessions, but because the product is evolving and we need mobile clients and allow third parties to access the data, we have decided to integrate OAuth2/OpenID Connect into our application.
Since there are multiple implementations out there that provide OAuth2 functionality, we are currently looking into a few available options. (Keycloak and ORY Hydra for example). The decision which we will choose depends on how much work we want to do change the existing structure of the application how we handle the users in the database. But regardless of which implementation we opt for, we have similar questions going forward.
Questions
How do the react applications handle login process and token storage?
Every documentation says: If the user is not logged in s/he is redirected to the login page. Where after login and consent he is redirected back to the app (After completing the oauth2 workflow obviously) with the Access/ID Token for the resource server and/or Refresh Token for refreshing the Access/ID Token.
Now here is what is not clear to me:
Since this is our own React app, we do not want to show the consent screen, like in apps from Microsoft/Google etc you do not see any. I guess this is possible by setting a value in the request itself, or skipping the consent screen based on the client id but I just want to make sure.
Next is where do I store the Access and Refresh Token? Access Token should be sent as the Bearer token with each request. So it can be stored in local storage because they are short lived, but the refresh token should be stored securely. Like in a secure http cookie?. If that is the case, then the server has to set it. If this is correct is this how the flow will look like?
Our React App (Not logged In) --> Login Page (Another React Page) --> User Enters Credentials --> Java Backend --> Authenticates the user --> Initiate the OAuth2 process --> Get the Access and Refresh Tokens --> Set them as secure Cookies --> Return the authenticated response to frontend with the cookies --> Login Page redirects to the previous page --> User continues with the app
This does not feel correct. How would PKCE help in this case?
Assuming what I wrote above is correct, I would need different login flows when the users logs in from our own app or from a third party app. That can however be determined by checking client ids or disabling password flow for third party clients.
The same would be applicable then for the refresh token flow too. Because for my own app I have to set the cookies, for third parties this has to be directly from the OAuth Server
Resources I have read/researched:
https://gist.github.com/mziwisky/10079157
How does OAuth work?
Edit: Adding more links I have read
What is the purpose of implicit grant
Best practices for session management
RESTful Authentication
And of course various writings and examples from Keycloak and ORY Hydra also.
I am currently trying both Keycloak and ORY Hydra figuring out which fits our needs better.
Thank you all in advance!
You don't have to show the consent screen. Here's an example of a React app authenticating using the Authorization Code Grant: https://fusionauth.io/blog/2020/03/10/securely-implement-oauth-in-react (full disclosure, this is on my employer's site but will work with any OAuth2 compliant identity server).
The short answer is that it's best for you to avoid the implicit grant, and have the access and refresh tokens stored in some middleware, not the browser. The example in the link uses a 100 line express server and stores those tokens in the session.
I wrote a bit about PKCE. Excerpt:
The Proof Key for Code Exchange (PKCE) RFC was published in 2015 and extends the Authorization Code grant to protect from an attack if part of the authorization flow happens over a non TLS connection. For example, between components of a native application. This attack could also happen if TLS has a vulnerability or if router firmware has been compromised and is spoofing DNS or downgrading from TLS to HTTP. PKCE requires an additional one-time code to be sent to the OAuth server. This is used to validate the request has not been intercepted or modified.
Here's a breakdown of the various OAuth options you have (again, this is on my employer's site but will work with any OAuth2 compliant identity server): https://fusionauth.io/learn/expert-advice/authentication/login-authentication-workflows You can allow different flows for different clients. For example, you could use the Authorization Code Grant for third parties and the Resource Owner Password Credentials grant (which essentially is username and password) for your own applications.
I'm not sure I answered all of your questions, but I hope that some of this is helpful.
The OAuth 2.0 Security Best Current Practice should be consulted. Even though it is still a "Internet Draft" it is mature and has been implemented by several vender implementations.
In general the OAuth 2.0 Authorization Code with PKCE Flow is the recommendation regardless of the use of Bearer tokens or JWT.
You should also consider reading about WebAuthn (Where there is not password)
Background
I'm building a .NET MVC enterprise web application that must have the ability to authenticate users from different companies. One of the major requirements was to ensure that users don't need to create and remember new credentials to use the application, instead they should continue to use whatever credentials they use to access applications within their company intranet.
Since the application will be hosted on the extranet and needs to handle authenticating against multiple domains (i.e. multiple Active Directories), we are expecting each client to set up a security token service (AD FS) that the application can interface with to implement claims authentication.
The MVC application will check if the user is authenticated, and if not, start the workflow that ends with the MVC application being given a SAML claim being associated with the user.
Problem
At this point, the user is authenticated and given access to the MVC application. However, the application itself is a modern day web application that uses quite a bit of JavaScript to consume a .NET Web API that handles most of the business logic. My main question is how I can secure this API. I want to make sure the only requests being sent to this server are being sent from a valid source, and that the user consuming the service has permissions to do so.
Current Solutions
There are two approaches I can take to consume the API:
Straight from JavaScript (Preferred solution)
Route the request through the MVC server, which will then forward it to the API.
In order to pick an approach, I first need to find a way to secure the API.
HMAC Authentication
The most straight forward solution I've found is HMAC Authentication - http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/. However, this approach requires all API requests to come directly from the MVC server, since the secret key will need to sit on the MVC server.
OAuth 2.0
The second approach I can implement is some flavor of OAuth 2.0. The flavors I'm familiar with can be found here http://alexbilbie.com/guide-to-oauth-2-grants/:
Authorization Code
Implicit
Resource owner credentials
Client credentials
Authorization Code Grant
This is not the approach that I want to take. The MVC application has already received claims for the user - they shouldn't have to do it again just because the API needs the claim. (I have a followup question asking if I can simply pass the claim to the API server)
Implicit Grant
I like the way this approach sounds, since I will be able to execute API requests in the client (i.e. JavaScript code), however it suffers from the same problem as the first approach.
Resource Owner Credentials Grant
This approach is out of the question - I don't want either the MVC application or the API to ever hold onto the user's credentials.
Client Credentials Grant
This approach is the only reasonable OAuth approach listed - however I fail to see a major difference between this approach and HMAC authentication detailed above.
Questions
Have I correctly set up the MVC application's authentication structure? Specifically, in this context is it appropriate to have AD FS handle authentication and respond with SAML tokens representing user claims?
I plan to store user data in the server's session. Can I also store the user's claim in the session, and then somehow send that up to the API for authentication?
If I can pass the claim from the MVC server to the API server, and the API server can correctly authenticate the request, is it safe to pass the claim to the client (browser / JS code) so that consuming the API can bypass the MVC server?
Is the HMAC Authentication approach the best way to go?
Yes, using ADFS or any IdP products as an IdP for your application is a good way to implement SSO. Doing this way help you delegate all the federated access management as well as claim rules to ADFS.
Yes, you can store claims in session and somehow send them to the WebAPI. Please note that if you are using WIF, it already stores claims in Thread.CurrentPrincipal as a ClaimsPrincipal object. Another thing is that I assume you only want to somehow send the claims only, not the whole SAML2 token.
I would say it is as safe as the mechanism you use to protect the token on the client side. Check https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/ and https://security.stackexchange.com/questions/80727/best-place-to-store-authentication-tokens-client-side for more details.
I can't say if it is best for you, but it seems to be a viable way, given that you have control over the WebAPI too. However, it also seems that using JWT token would be easier: https://vosseburchttechblog.azurewebsites.net/index.php/2015/09/19/generating-and-consuming-json-web-tokens-with-net/. Talking about JWT token, you can also ask ADFS to issue it for you: https://blogs.technet.microsoft.com/maheshu/2015/05/26/json-web-token-jwt-support-in-adfs/.
we are implementing SSO solution with our customers.Due to its complex nature and time sensitivity, we employed a third party security partner firm that can act as SP and redirect the request after authenticating the user.
The third party firm is now telling me they are going to send SAML response to our application to further validate.
My question is , Given that SAML response is already validated at our third party provider(who is acting as SP on our behalf), why we(application owner) again have to do SAML assertion?
I was expecting it is going to be a redirect from the third party with some token to validate so that our application can skip the login validation part.
but I wanted to talk to them with research facts and industry practice. Can anyone help? please let me know if i am missing something here.
The usual practice when using such intermediary SP for SSO to (typically a legacy) application is to:
process and validate the SAML Authentication Response and the Assertion at the SP
SP then encodes a cookie on a common domain or a token provided as a request parameter/HTTP header
cookie/token is typically constructed using a symmetric cryptography with a shared secret and e.g. HMAC
SP redirects user to the application which verifies the provided cookie or token and grants access
I don't think you're missing anything. Perhaps your provider just confused things and gave you wrong information. It makes sense to include the SAML token itself in the response from SP to your application (e.g. for audit purposes), but it makes no sense to expect your application to understand or validate the SAML message once it's been done already by the intermediary SP.