Concurrent login with identity server4 - identityserver4

Want to logout from all other session(s) when user logs in other browser.
I am able to delete the PersistedGrants but cookies are still present.
When user refreshes the page a new access_token is generated due to refresh_token.
So basically we want only one concurrent session of user.
Any help would be appreciated.

By default IdSrv persists user session in a cookie. You can change that by implementing IUserSession and registering in DI. Doing so you get access to logged in clients within one session. Having that knowledge, you can register your custom middleware with the check: when authenticated, i.e. has auth cookie, and no other session for the same user id then ok, else handle the collision: the one who logged in earlier logs out. Just an idea, but should work. See my customization of the DefaultUserSession - backing it to Redis, used for another purpose, but should be enough to demonstrate the approach.

Related

How to design React signIn proccess with NodeJS and sessions stored in cookies?

I have React signIn form and sessions mechanism implemented in NodeJs. In React I have protected routes only for authenticated users.
How should I check if user is authenticated. I have two ideas:
If user sign in for the fisrt time I can save this information in LocalStorage and then evrytime just check localStorage.
Send request to NodeJS server every time to check if user is authenticated.
Do you have any other ideas? Which solution should I pick?
I tried both options and second one is more UI unfriendly becasue I have to run loading state evrytime I am waiting for auth response. On the other hand, first option has also disadvantege, because I am based on token in LocalStorage which can be malicious.
Every time a request is made to an endpoint that requires authentication, the request should contain proof that they are who they claim to be.
The classic way to do this is by storing some sort of "Session ID" in a cookie or localStorage (client side), that you send along with every request.
Using a "Token" (e.g: JWT) instead of a "Session ID" is another popular way to handle authentication.
Check out this article for more information about both: https://dzone.com/articles/cookies-vs-tokens-the-definitive-guide
To return to your question, I'm not sure what you're worried about in regards to a "malicious Token in localStorage" (Or do you mean localStorage can be malicious?). But for a secure application you have to either:
Store something client-side
Require your user to provide credentials (username + password) for every request

IdentityServer4: How to set a role for Google user?

I have 3 applications:
An IdentityServer4 API which provides Google authentication and also provides an access token to authorize the resource API.
A simple Resource API which provides some data from DB.
A simple Client in React which have 4 buttons:
Login, for Google auth
Logout
Get data - a simple request with the access token to the Resource API and gets the data from Db
Get user data - returns user profile and token (for debug purpose)
I didn't put any sample code because my problem is not code related, it's knowledge that I'm missing and I ask for guidance.
The workflow is working just fine: the user press the Login button, it is redirected to IdentityServer4 API for Google Auth. From there it is redirected to a Callback Page from the Client and from there to the Index page. I receive the user data and the token, I can request data from the Resource API and it's working.
My problem is: How do I give a Role to the Google Users ?
I don't have users saved in DB. I want three types of Users: SuperAdmin, Admin, Viewer and each of these roles have limited Endpoints which can access.
For limiting their access I saw that I can use Claims-based authorization or Role-based authorization.
So, my question is how ca I give a Google User who wants to login in my app, a specific Claim/Role ? What is the workflow ? I must save it first in DB ? Or there exists a service from Google where I can add an email address and select a Role for that address ?
Thank you very much !
After you get the response from Google in your callback you can handle the user and do what ever you want to do with it. Below are the some typical tasks that you can do in callback that I took from documentation page of identityserver4 link:
Handling the callback and signing in the user
On the callback page your typical tasks are:
inspect the identity returned by the external provider.
make a decision how you want to deal with that user. This might be
different based on the fact if this is a new user or a returning
user.
new users might need additional steps and UI before they are allowed
in.
probably create a new internal user account that is linked to the
external provider.
store the external claims that you want to keep.
delete the temporary cookie
sign-in the user
What I would do is creating an new internal user account that is linked to the external provider and add a role to that user.
If you don't want to save users in db, you can add an extra claim to user in callback method and use that claim in token. and i think this link will help with that.

best way to keep user logged in using JWT and axios

how to keep the user always logged in, in a react application.
I can't refresh the token using an expired token, can I ?
my idea is to make the token expiration to null and refresh it in every request for security
so if user don't use the app for a while, token will never expires, and in every request the token will be refreshed for the security
it's not secure to do this. because now the token will still valid as long as no new requests from the user. tokens that never expire extend the time-frame for attacks such as cross-site request forgery (CSRF), session hijacking and session fixation. also if you want to change this behavior you will need to change it from backend side not react.js side
I might be misreading your question, but at least just on "how to keep user logged in"
You can do this with localStorage, ofcourse there is security concern.
Basic idea: user logins, the user object returns from database, you only need to store the jwt_encoded information that makes a user "looks like is logged in" in the localStorage. By that I mean, you aren't going to return the user's password & email everytime, and on refresh page, log the user in with those credentials... If you are building a todolist app, just store the todolist tasks & username to the localStorage after the user logs in for the first time. And then if the user refreshes the page, just display the information from the localStorage.
It might be a little bit more tricky because UI is dynamic and you have to change your localStorage to change your UI, but on backend calls that update our user object, we can simply return the new user object and set that as the new user in localStorage.
Best to check this article for code, https://blog.bitsrc.io/build-a-login-auth-app-with-the-mern-stack-part-3-react-components-88190f8db718. The author starts talking it about half way through. I only provided theoretical stuff.
Edit: I really was falling asleep. For the "it might be a little bit tricky part" I was being quite dumb. If you saved the user id in the localstorage, you can just make api calls to retrieve the user information with that id whenever you need it, in short, you only need to store user id in localStorage.

Hiding Routes in React Header based on Express.js User login status

I have an application that uses express.js as the server side language and React on the front-end. I use passport.js to authenticate routes in the server, using local login and facebook strategies (no JWT). I use express-session to manage the session, which seems straight forward ( or insufficient, which I do not know yet, for my case, as its work in progress ).
My requirement is to hide/show few links in the Header component.
i.e.,
Log In
Sign Up
should show up in index page, when user has not logged in, but hidden when he is logged in. Likewise, few links should be hidden when the user is not yet logged in.
What is the best wat to check this from the client? Making an AJAX call is not ideal, as I may have more use cases of checking if the user session is valid from the client.
I can see the default connect.sid cookie, which the express creates, but how do I make use of it, or is there a best way for the client to know that the user is already logged in.
You have a couple options. Here are some:
You can check for the presence of a different cookie in the browser, and use that as your metric for whether or not you are "logged in". Your browser won't know if the session has expired server side, so you still have to account for the fact that you may be logged out and not know it. Additionally, you have to be sure to clear this cookie when logging out and set it when logging in.
When starting, your browser can make a AJAX request to get the currently logged in user. This might be useful for all sorts of things, such as displaying the user's name when logged in. You really only need to do this once (on page load and on login), then keep track of the user's login state stored in memory. You mentioned you don't want to do this, but it is fairly common.
When loading the page, you can inject the user into the page. For example, when the page loads there will be a <script> tag containing window.currentUser = null or an object representing the user. You can use this to "bootstrap" the login state without needing an AJAX request.
To clarify, you can't use the connect.sid cookie by itself because this cookie is just the ID of the session, not the session data itself. Only the server knows the session data that's being stored for that user, not the client. You need some way aside from this cookie for the server to tell the client that it's logged in, and the client to keep track of that state.
If you want the client to know from the ID component itself, you'll want to look at token options like JWTs.

angularjs client and spring backend user login and session management

I have a mobile website written in angularjs, with my backend in Spring Boot. Right now, I have my own login page and can login a user without any trouble. However, if the user ever clicks "back", "refresh", etc., the client loses the user's id and login info (obtained from server on login). I need to make sure that this info is maintained and clicking "back" or "refresh" doesn't break everything.
Secondly, a user that knows the url's after login can type those url's in the browser and access them without logging in. I can stop them accessing anything on the server, but not sure what I can do on the client to redirect them to a login page in this case.
Any help would be greatly appreciated!
You should keep in mind that everything running in browser is stateless, there's no way to keep trace of the previous state.
Right now, if the user performs a refresh (or another similar action), Angular loses everything (AuthData included).
You have many way to work around that limit:
Perform an http request after the application bootstrap (have a look at the angular.module().run method
Save a cookie and use the server to print initial data layer directly on the dom via json
Save on local/session storage
Personally, I prefer cookies because that lets the server to work decoupled from the client.
In reference to your comment..."if the user ever clicks "back", "refresh", etc., the client loses the user's id and login info (obtained from server on login)."
Is there any reason you need to maintain the user id or login info after a successful authentication?
If Spring Security is setup for basic authentication, after a successful login, a Session Cookie will be sent back on the response to the client. On all subsequent requests to the server, the same Session Cookie will be sent on the request and the previously authenticated session will be re-established. You just need to ensure that your Angular client is passing cookies when issuing requests.
Take a look at this sample on how this is done.

Resources