Spring - How to secure Server Sent Events - spring

I want to to use Springs Server Sent Events to update specific parts in a Angular frontend. I want that only authorized user can subscribe to the Server Sent Events. That's not the problem but how can I check if the user is still authorized to retrieve the push messages after e.g. the session is expired?
I'm also using JWT Token based authorisation so that the server doesn't know when the token expires. What is a good practice here? Should I save the token alongside with the SseEmitter and check it before each push?
Thanks!

Related

OneLogin programmatic session cookie validation - No browser

I have the following scenario that I am curious if it is possible to implement. I need to use SSO and more specifically OneLogin to authenticate the user via custom UI from my Java standalone application. I know this can be done via Create Session Login Token and then Create session via token One Login API calls. With some parsing I can get the session cookie out of the last call and store it.
Now I need to programmatically hit the API server, which is to be build still and this server somehow needs to validate the session cookie that I am going to send along with request. The key word "Programatically" as in there will be no browser
OneLogin doesn't provide SDK to validate existing session cookie => it would be nice if I could, based on session cookie find out if it is still valid and what is the user name used for this session. If session is invalid API server would return unauthorized.
Is this even possible? Or is it possible in some other way?
Basically One Login is already used in our ecosystem and I have to continue using it
The app that will log user in and get the session cookie may not be the one calling the API server. This could be another java application that would receive the session
I guess what I am looking for is Validate Session equivalent from Open ID Connect API in general API
The session_token that is returned via that API has a short expiry is only intended to be used for making the Create Session request which returns session cookies.
It sounds like OpenId Connect might be the best option for this use case. If you have user credentials then you could use the Resource Owner Password Grant flow to authenticate the user and obtain an id_token.
The id_token is a JWT containing user details can then be verified for authenticity by checking its signature, audience and expiry claims. It can also hold other custom information about the user that may be used by your backend application.

sharing the principal object received from an oauth2 provider between spring and angular

I have stumbled upon a problem with Spring Security and Angular.
On my BE (Spring Boot application), there are defined OAuth2 providers, such as Google, GitHub and Facebook.
My BE works fine with this providers, since I can authenticate on the desired providers.
The problem is when I try to send the principal object to the FE (Angular 6 application).
I get undefined value when i try to subscribe the value from the rest endpoint.
I assume this is due to the Spring Servlet creating a new thread for the login request.
I am doing my login request from the Angular app.
I did watch dozens of tutorials and rad so many articles, but I just can't find the answer. If it's possible for you to share some code on how it is done, or give me a link, since for sure I am making a silly mistake and can't seem to find the answer here.
Thanks for understanding, have a good day.
:)
I am assuming that you are using the Authorization Code flow from your BE to authenticate the user that interacts with your FE Angular application (you in your example). Otherwise, you would be trying to authenticate the BE Client with the Client flow and you wouldn't need to return the "principal object" to the FE application. If my assumptions are correct... read on.
The Authorization Code flow goes as follows:
1) The user somehow selects an Authentication provider (ex: Google) and that selection is returned to some endpoint in the BE as a non-authenticated request..
2) The BE Client receives this request, preferably intercepted by a filter and, since the request is not authenticatedd, redirects the browser to the selected auth provider's authorization endpoint.
3) The user then proceed to authenticate against that provider which, upon succesfull authentication, returns a response that redirects the browser to a BE Client endpoint. That redirect holds a parameter that provides a code that the BE Client will use to get an idToken representing the user. At this point, it is important to note that the browser has not been returned any response for this redirect.
4) The BE Client then proceeds to send a regular HTTP request to the provider's token endpoint along with the received authorization code. The provider then returns the idToken an HTTP response directly to the BE Client. All this is happening while the browser is still waiting for the response to the last redirect.
5) The BE Client then process the idToken (verification, validation, user details, session etc) and only then, will finally send the response to the browser patiently waiting since the code redirect. That response may provide a header or a cookie with a sessionId or token (your choice) that the FE application will be able to read or use for the given purpose.
This flow is relatively easy to implement and requires minimal SS configuration. You must keep the BE Client auth endpoint with permitAll() otherwise, you would not be able to trigger this flow. Also, make sure that, once the FE app. has received the header/cookie, all subsequent calls shall be processed as "authenticated calls". Finally, make sure to document yourself on the perils of stateless sessions as well as cookie security and always use HTTPS.
Jake.

Post Restful Authentication

I am using MEAN stack for developing a web application. I choose it be completely RESTFULL that is stateless. For authentication I am using JWT(Json Web Token) strategy.
Client sends login request to server, server authenticates and sends JWT and user data to the client(here angular 2).I am storing this JWT token in the cookie.
Now my question is how do we store/display user details in the view continuously. For eg if we consider Facebook as restful , after a user logs in, client display user data such as profile image, profile link etc etc.
Since Rest Authentication just retrieves the data, with credentials sent in each request.
How are these user related data retained in the client side. Is it like for each request, user data is fetched from the server and updated continuously in the view.
If yes how or if no then am I missing something.
I know this question might be nonsense to experts, but any advice, suggestion or kickstarter information would be helpful for a novice like me.Are there any best practises for these?
Thanks in advance
Yes, you can fetch user data from server on every request but the right approach is to store it in JWT token as custom claims and on each request get the token from cookie, decode it and get the necessary details from those custom claims.
By the way, you can store user data in localStorage for frequent use.

How to OAuth using WeChat Login for Parse Server

We would like to enable WeChat Login on our iOS client that is connected to a Parse Server backend on Heroku. From reading through the PFFacebookAuthenticationProvider, it seems that we need to write a custom authentication provider for WeChat.
WeChat Login is based on OAuth 2.0. It works as followed:
1. From our app, an authorization request is sent to the WeChat app installed on the same phone. WeChat app is called to the foreground.
2. After user approved the authorization request, a code (NOT the access token) is sent to our app.
3. With the code and our app id and app secret, our server can then call WeChat API and get the appropriate user id and access token from WeChat. This step has to happen on our server, as we cannot include the app secret within our client app.
On the WeChat documentation, it is strongly recommended that we keep the access token strictly in the control of server (anyone with the access token can make requests to WeChat API and it will be counted towards the usage limit for our API calls).
If we are to follow this practice, we cannot save the access token in the authData field of the user. Would it be acceptable to save only the code and id from WeChat into the authData and save the access token to another class that only the master key has access to? This obviously requires us to write a custom AuthAdapter for the Parse Server.
Or is there a better way to implement this custom auth? The custom auth documentation for Parse Server is pretty thin and I plan to improve it after I can get it working for myself.
You can definitely update the auth adapter to exchange the code for an access token server side. The logic would be similar to other adapters, failing to login/signup if the server is unable to process the code to access token exchange.
Here
https://github.com/parse-community/parse-server/blob/master/src/Adapters/Auth/wechat.js#L7
If the authData object has that code, you can add additional logic to exchange it.

How to protect REST API when using AJAX?

There are SNS application with 2 servers. Web backend server and REST API server.
The web server allows user login/logout with username/password, and show user information
The REST API server provides APIs like /topics, /comments, it should be stateless without session
The REST API will serve other web applications
There are some potential solutions, but neither is security.
Base Auth, the browser hold the username/password
Token with expiry timestamp, the problem is user could stay on the page until token expires
So, is there a way to protect the REST API when calling it from AJAX?
If I have understood your problem correctly I may suggest you use the Token solution. In order to maintain security you may generate new token on every request (& send it to client in response), which should be used to make next request, and disable token if it is once used or has expired.
Sorry, I meant to mention it as a comment, but I don't have enough reputation.

Resources