I'm building an Angular 2 application using SAML2 via the passport-wsfed-saml2 strategy https://github.com/auth0/passport-wsfed-saml2. When I receive a users info back from SAML I generate a JWT token which I use to authenticate a user on an API I am also writing.
So I have two servers, APP/Auth Server is serving my application as well as generating my JWT tokens and API Server has my API. Both servers have a copy of the JWT secret, so when a user sends a request from APP/Auth Server to the API Server I verify the token they sent with their request by verifying it with the secret.
Now for my questions, is it bad practice to have your app served from the same server you use to generate your JWT tokens? If so, what should I do here? Should I be doing more to authenticate a user on my API side?
Something about this just feels dirty....any help would be appreciated.
Having the application and authentication system in the same service is not a malpractice by itself. In general, decoupled services are recommended but this does not mean that the deployment can group services and of course depends on the context
If you are worried about sharing the secret key among servers, you can use an asymmetric key pair (private and public). The private key only needs to be known by the Auth Server in order to sign the JWT. The API Server can use the public key to verify tokens.
Related
I have some client-side-rendered application written in Vue3. I perform user authentication and authorization to let him access certain views (OAuth).
App is calling some REST API with fetch, and everything works properly. And there comes the problem - this API is now forcing s2s authentication based on JWT token signed with key pair (I have to generate JWT token, sign it with private key, then send it to oAuth provider where it's being decoded with public key stored on my frontend app profile, and verified).
Is there any safe way to perform such authentication in my Vue app? Or the only way is to create some 'middleware' api just for my frontend, which will verify user token, and then perform call to this target API with system token, withouth exposing it to clients browser
I have the following doubt, I have a project that is based on microsoft authentication, a frontend with angular using msal and the backend with passport-azure-ad.
My question is the following, is it necessary to use the client secret?
When we are using authorization code flow or hybrid flow in OpenID Connect, the client exchanges an authorization code for an access token. During this step, the client has to authenticate itself to the server. One way to authenticate the client is by using a client secret.
Client secret is required for web apps which can store the client_secret securely on the server side.All confidential clients have a choice of using client secrets or certificate credentials and passport azure ad library is designed for auth flows in server side web apps.
Note:ClientID and Client Secrets are passed to AAD by MSAL, and if you are using a confidential client (like: WebApp, WebAPI or
Daemon/Service) that runs on Azure PaaS Service, or any other secured
servers, only the clientID gets exposed by MSAL but not the client
secret, as the client secret is passed only in the backend (server
side) to AAD and never directly exposed and requires proper
authentication.
msal client apps
If your app is native(spa), client secret is not needed
Public clients, which include native applications and single page apps, must not use secrets or certificates when redeeming an authorization code as client_secret can't be reliably stored on devices or web pages and the secret can be vulnerable to attacks if it is client side exposed..
Reference: v2-oauth2-auth-code-flow-Client secret
I am working on an application where the front end is VueJS and the backend is NodeJS and ExpressJS.
The NodeJS, ExpressJS will be hosting REST API's and I want to secure them using Azure AD. I want to use Auth Code flow.
My question is: I have put my thoughts in the diagram, is this the right approach?
This approach looks good to me. I am thinking of it as an advanced version of something like JWT (https://jwt.io/) based authentication. Please see the steps below for JWT:
The client requests authentication by providing credentials.
The server provides the client with the token that is encrypted using the private key present in the server.
The JWT is stored in client's session and is sent to the server anytime the client requests something from it requiring authentication.
The server then decrypts the token using the public/private key and sends the response back to the client.
A session is validated at this point.
With the architecture you have described above, it does the exact same thing except the means to encrypt (generate) and decrypt (verify) the token exists with Azure AD. Below are the steps for achieving authentication based on your architecture:
The client requests authentication by providing credentials.
The Azure AD server does a 2FA kind of thing but in the end provides the token (equivalent to JWT in the previous approach).
The token is stored in client's session and is sent to the application backend server anytime the client requests something from it requiring authentication.
The backend server uses Azure AD for verifying the token (similar to the decryption/verification step of JWT) and sends the response back to the client.
A session is validated at this point.
I would suggest a small change to this though. If you look at the step 4 above. The application server will keep hitting Azure AD every time it needs to authenticate the session. If you could add an actual JWT for this phase, it may help in avoiding these redundant calls to Azure.
So the steps described above for JWT may be added after the 4th step for Azure AD described above i.e. create a JWT and store it in clients session once everything is verified from Azure and then keep using JWT based authentication in the future for current session.
If required, JWT can be stored in the browser cookies and calls to Azure AD can totally be avoided for a specific period. However, our objective here is not to decrease load on Azure AD server but just suggesting a way of using JWT in this specific situation.
I hope it helps.
I would like to seek help from you guys.
I have multiple RESTful API services running in NodeJS Express. Each API is hosted by different NodeJS with different port. And in our front-end, it is accessible via reverse proxy.
We are now moving to a secured services. However, there's a problem in authenticating with the services. The front-end should request 1 auth token upon login that can be used in accessing the internal API services (API is also accessible in our public domain /api/).
How can we solve this problem?
Current Setup
You could issue a signed JWT token upon login (see https://jwt.io/).
The front end application has to send the token back with each API call.
Each API server has to know in advance the key (public key or symmetric key depending on the type of the signature algorithm) and use the key to check the signature of the token is valid.
If it is valid, the API server knows it can trust the token content, and decide whether to serve the request. The token would contain the identity of the user, expiration time, ...
Note that signing the token does not encrypt the data: if you need to convey sensitive data through the token, it needs to also be encrypted
Thus it is not necessary to establish a session and then share the session across the many API instances. Knowing the key is enough to trust the token content
To pass the JWT in API calls you can use a header:
Authorization : Bearer theBase64EncodedToken
Of course, it is up to you to check if this scheme satisfies the security concerns related to your application.
I have a requirement to secure my JAX-RS resources and only accept requests that originate from authorized mobile applications. Is this possible? How can this be done?
All of my resources are protected already with user authentication, the goal here is to reduce user ID fishing attempts. I know one solution would be to keep the response error with an invalid user ID generic, but the application is very large and at the moment this isn't possible.
One idea I came up with is to use JWT tokens signed with a shared secret. Then I could add an Authorization filter on the server to check the signature. If it doesn't validate then discard the request. Does this sound like a viable option?
My concern is the security of the shared secret on a mobile device, could it be compromised with a rooted device?
Using tokens is the preferred way. But the secret key is not shared. Only the server has access to it. That secret key is used to generate the message authentication code(MAC) of the JWT. Since secret key is only known by the server, no one else can generate a JWT with a valid signature. Secret may be persisted or application scoped.
Once a client is authenticated using credentials, server must send a signed JWT to the client.
That JWT must contains necessary information to identify the client and state(if necessary).
Then client send that token in a header field along with all the other requests.
Server validates the JWT using secret key and process the request.
Even though client can change the JWT body, he cannot get it verified. That's the whole point of using a signature.