How to authenticate to frontend with jwt from backend? - jwt

I'm trying to implement jwt for authentication for my backend and frontend. I have 2 apps (.net core mvc) one is backend other one is frontend
I send login request and then i get access and refresh token etc. Those parts are ok.
Question:
But problem is that front end has no idea that i have token from backend API that's why there is no session created on frontend yet. So i cannot redirect user to protected areas of website [Authorize]
First thing comes to my mind is after i get access token from backend API ı should post it to front end controller via ajax. Lets say "/Account/Login" and this frontend controller will validate token (because it has same key with backend) then it will create session for this user and will return success from ajax call.
Is this correct approach for this kind of login flow ? Are there any alternatives ?

How is your user talking with the backend app? Directly or through frontend app? I would presume that they make a request to the frontend app and the frontend talks to backend. In such a scenario frontend can easily create a session for the user and associate the token from backend with the session.
If the user is talking directly to backend app, then I would go with your idea - the backend app would have to somehow notify frontend app that it now has a token for the user.
Another solution is to create some shared session mechanism (there are some readily available solutions for that). Your backend app can create a shared session and associate the token with it, and then the frontend app can use the same shared session.

Related

How to perform user registration and authentication between a single page application and a REST API with OpenID Connect

Consider that we have:
An SPA or a statically generated JAMStack website.
A REST API.
The website is being served with nignx that also reverse proxies to our API.
--
It is required that a user should be able to register/authenticate with an identity provider (say, Google) through the OpenID Connect protocol. For the sake of simplicity, let us assume that the user has already registered with our API.
Talking about authentication using OIDC, from what I have read on the subject, the steps you take are the following:
Register the application with the IdP and receive a client id and a secret.
When the user initiates a login (with Google) request on the API ('/api/loginWithGoogle') the API sets a state variable on the request session (to prevent CSRF) and redirects the user-agent to the IdP's login page.
At this page, the user enters their credentials and if they are correct, the IdP redirects the user to the callback URL on the API callback (/api/callback).
The request received on the callback has the state parameter (which we should verify with the one we set on the session previously) and a code parameter. We exchange the code for the identity token with the authorization server/IdP (we also receive access/refresh tokens from the auth server, which we discard for now because we do not want to access any APIs on the behalf of the user).
The identity token is parsed to verify user identity against our database (maybe an email).
Assume that the identity is verified.
-- The next part is what's giving me trouble --
The documentation that I have read advises that from here we redirect the user to a URL (e.g. the profile page)and start a login session between the user agent and the API. This is fine for this specific architecture (with both the SPA/static-site being hosted on the same domain).
But how does it scale?
Say I want to move from a session based flow to a JWT based flow (for authenticating to my API).
What if a mobile application comes into the picture? How can it leverage a similar SSO functionality from my API?
NOTE: I have read a little on the PKCE mechanism for SPAs (I assume it works for JAMStack as well) and native mobile apps, but from what I gather, it is an authorization mechanism that assumes that there is no back-end in place. I can not reconcile PKCE in an authentication context when an API is involved.
Usually this is done via the following components. By separating these concerns you can ensure that flows work well for all of your apps and APIs.
BACKEND FOR FRONTEND
This is a utility API to keep tokens for the SPA out of the browser and to supply the client secret to the token service.
WEB HOST
This serves unsecured static content for the SPA. It is possible to use the BFF to do this, though a separated component allows you to serve content via a content delivery network, which some companies prefer.
TOKEN SERVICE
This does the issuing of tokens for your apps and APIs. You could use Google initially, though a more complete solution is to use your own Authorization Server (AS). This is because you will not be able to control the contents of Google access tokens when authorizating in your own APIs.
SPA CLIENT
This interacts with the Backend for Frontend during OAuth and API calls. Cookies are sent from the browser and the backend forwards tokens to APIs.
MOBILE CLIENT
This interacts with the token service and uses tokens to call APIs directly, without using a Backend for Frontend.
BUSINESS APIs
These only ever receive JWT access tokens and do not deal with any cookie concerns. APIs can be hosted in any domain.
SCALING
In order for cookies to work properly, a separate instance of the Backend for Frontend must be deployed for each SPA, where each instance runs on the same parent domain as the SPA's web origin.
UPDATE - AS REQUESTED
The backend for frontend can be either a traditional web backend or an API. In the latter case CORS is used.
See this code example for an API driven approach. Any Authorization Server can be used as the token service. Following the tutorial may help you to see how the components fit together. SPA security is a difficult topic though.

Identity Server Resource Owner flow with external Identity Provider

We have a project where the client requests the use of their own Identity Provider, in this case, it is SalesForce.
We secure the application using IdentityServer 3 and have configured it that for this client (based on parameters) it will use SalesForce as the IDP.
For the web app, no problem, Identity Server redirects to the Sales Force login page and everything works great.
Now we have a mobile app to build and the client would like to avoid having a web login page and would rather have a nice polished login form built in the application. This means that we will have to use the Resource Owner flow.
Now, the users creds are on SalesForce side so how does that work and is this at all possible in IdentityServer 3 ?
I see 2 possibilities but I kind of like neither of them:
Send the auth call to IdentityServer which should detect that it is up to SalesForce to validate the user and forwards the request there. I think it is not good as I would rather avoid having my IdentityServer dealing with credentials that he should not even know
Send a first auth call to SalesForce to get some "id token" that would then allow me to send another auth call to IdentityServer which will then recognize the "id token" and release an access token.
That seems like a stretch and forces the app to know that there is an IDP which is none of its business.
Any idea?

Symfony 3 authenticate user against remote API

I've got an application where back-end and front-end are served from different hosts and are two different applications (both Symfony 3 based).
One of them (back-end ofc) handles business logic and keeps users and their roles in it's DB. Back-end provides REST API to be used by front-end. I have no possibility to modify back-end code as it's not my project - I just want to create a front-end for it.
Currently, I'm trying to create front-end app in Symfony 3 but I'm not sure how to make the front-end app authenticate against a remote API and keep no user data (or as little as possible) on its side.
After passing credentials to the backend via REST API a token is sent to front-end application and following API requests (e.g. data the front-end app would present to the user are to be sent with token received after successful authentication).
My question again: How can I authenticate against remote custom (non-OAuth) API from Symfony 3?
And additionally: How to handle token properly later? (it has to be used while making every request after successful authentication). What is the easiest way to achieve this?
I've been struggling to find decent info (maybe a tutorial?) I'm a noob in Symfony :(
Most articles describe providing an API which allows clients to connect to it, not making a client app in Symfony.
What I found:
Symfony2 authentication via 3rd Party REST API - most relevant, though it describes a flow for Symfony 2 and the accepted answer describes what should be done only briefly
https://blog.vandenbrand.org/2012/06/19/symfony2-authentication-provider-authenticate-against-webservice/ - concerning Symfony 2
http://symfony.com/doc/current/security/custom_authentication_provider.html - probably the most on topic, however, I don't understand where will app keep it's users (is writing a custom user provider necessary in this example?)
You've already found the answer on your question. That's custom authentication provider. You can keep the tokens in your frontend app storage, and just authenticate them. On login, you should create the token via request to backend app, save it in your token storage and that's all. Then you only need to authenticate the token (just see an example of auth provider).
Regarding keeping user data in your frontend app, it's up to you. You don't have to keep any data, therefore if you'd like to show some details (i.e. user name and so on) you have to store that details too (or retrieve it each request - but that will impact the performance). At least you can use caching for that.
So the possible approach is:
On login(with login form or elsewhere), just authenticate user in login handler (create your own auth provider as described there - don't worry about Symfony 2, security component is almost the same - there are some incompatibilities, but the direction is correct). After successful authentication, store token in your frontend storage (also you can store some user details you need like name and so on).
On each request, authenticate the user using the token that's kept in your frontend app storage (that's another auth provider) - you don't need to send request to your backend app.

Symfony Restful API authentication and OAuth2

I am building a RESTful API application with Symfony2.
The app will consist of two parts.
JavaScript front-end - everything the user will ever be able to see and do will reside here.
Symfony2 back-end API - every resource and data the user will be able to reach from front-end will be served in standard JSON via endpoints.
I have never built a fully RESTful application before. My main concern is how to authenticate users.
I imagine REST authentication like this:
A user enters his credentials in a form generated in the front end, then the request is sent to the server where authentication logic happens and if the user is authenticated, a response with "token" is sent back to user, that he will add that token to every request url or authorization header (I don't know which of these options is preferable).
Then with every request, the server will check if the user token is valid and if the user is authorized to access that data (roles) and if so serves request data. (I don't want to allow users login with Google, Facebook or anything like that. I want my users logging in to other application using my app)
Now this seems quite simple, but then there's OAuth2 that got me confused because I jumped into developing without research. I downloaded FOSOAuthServerBundle and started messing around when I started to get a feeling that something is not right.
What I would like to know is the difference between RESTful authentication and OAuth.
What are the recommendations for implementing the described login mechanism?
You've got it pretty spot on. You use OAuth just for the authentication and all the following requests will have to provide that HTTP-Authorization header. You would need to create your custom authentication provider to handle that. Also use something like FOSRestBundle to create your resources.

REST API and client on same server, need API authentication?

First, let me describe the application: we are working on a web-based software which is some kind of custom help desk application. It requires the user to login (we use FOSUserBundle). After login the user is redirected to the dashboard. From the dashboard there is no more page reload, the frontend is build on Angularjs and the user can get anywhere within the application without page reload. You could speak of a single page application.
So the data that is presented to the user, is fetched from a rest api (we use FOSRestBundle). This works quite well at this point.
There is some kind of dilemma. Only our staff will access this application (for now). So a staff member needs to login to access the helpdesk. The data that is pushed to the frontend via angularjs is called via api, so the user that has just logged in needs to authenticate again on every request because of rest.
Problem: Since the backend runs on symfony2 let us just try to get the user object of the currently logged in user when an api call is made:
$this->get('security.context')->getToken()->getUser()
returns anon. that stands for anonymous, or
$this->getUser();
returns just null.
So the authenticated context seems to be gone when using the rest api. However when I call an action directly without rest, I can get user information.
So what we need is to secure our rest api and get user information on every api call. We don't want third party people to access our application, just staff. I am not familar with OAuth, but the user will be redirected to a third party page to Allow/Deny access to his data? This would not be an option for us.
Based on that information, do you have any suggestions or ideas how to secure the api and transport the user data so that getUser does not return null or anon. but the actuall logged in user?
there's another way to resolve your problem.
It's by using Certificates.
you can generate certificates then use Http tunneling (https obviousley), the server will ask for a certificate (you've to configure Apache for that but it's not a big challenge).
with this in place, you've to add a CertificateManageron the server side to ensure that the certificate is valid and to know who's calling the service (to be able to authenticate the user at each request), the CertificateManager(or what ever you'll call it) will probably have to be configured within you filters chaine (as known in the java world), et voilà
Hop that help you,
Abderrazak
REST is stateless so you will have to send some kind of authentication/authorization in each request. You can use HTTP BASIC AUTH or something like OAuth.
Have a look at https://github.com/FriendsOfSymfony/FOSOAuthServerBundle
I'm kind of building our application in exactly the same architecture (RESTful API with Symfony2 back-end and AngularJS frontend.
Another way is to duplicate the api routes, so that you have the api routes protected by OAUTH and the api routes protected by the session, both of them pointing to the same controllers. The method was explained here: https://stackoverflow.com/a/22964736/435026