How can I handle the most basic user auth in Spring Boot? - spring

I've implemented really basic user authentication before - generate a session cookie when logging in, and when the user loads a page with authentication just check the cookie.
However, the complexity of Spring Security / Apache Shiro is really confusing me.
All I really want is:
be able to have a user log in once and see their username on every page they visit (like on Stackoverflow)
have this login persist for a reasonable length (cookie expiry time or something like that)
It looks like I have the option of using EhCache or implementing my own subclass of... something... to use something like postgres.
I seem to have gotten the first thing I want working in Apache Shiro:
Subject sub = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(remember);
try {
sub.login(token);
// ...
But I'm super stuck on how to get this session to persist between restarts of the spring webserver. Like, I know Stackoverflow highly recommends a code example but I literally don't even know where to start. Right now my "progress" on trying to figure out how to persist sessions between restarts (bolded to clarify what I'm asking) is literally the single line
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
// ...
dwsm.setCacheManager(new EhCacheManager());
and I don't even know what that actually does.
I would really appreciate any kind of guidance here since I really don't even know where to begin and the documentation I've been able to find is unfortunately not super thorough.

thats one of the problems with just sessions. That they are not persistant over restarts unless you save your sessions.
Now days people usually use a token based approach like oauth2.
The flow in a token based authentication system is:
User sends his/hers credentials to an authorizationserver (oauth2).
If credentials were correct they get a token back
The client (webpage) makes a request to the backend to get the user object and supplies the token in this call as an "Authorization"-header.
The backend takes the token and sends it to the authorizationserver (oauth2) to check its validity.
if the token is valid the backend server fetches the user object and sends this to the client.
The client gets the username from the user object and stores this in its state (react, redux if such an app). In every call to the backend the client must supply the token it got from the first login so that the server always knows that the caller is whom he/she claims to be

Related

Best way to store user related data from db, in a webapp with OIDC authentication

I have a Core3.1 web application protected with azureAD (OpenIdConnect) and I retrieve most of the user's related data I need, from the idtoken:
Username, email, employeeId, even the user's AD groups.
I also need to get some additional data from the database and I'm not sure how I should store this data in the application, to make it available everywhere and for the entire time the user is logged in.
I don't want to use cookie. For now, I used the session.
Problem is this session expires differently from the authentication session, so I had to call a static method to check if the variables are empty and eventually doing the query again.
It works... but is ugly.
I feel like I'm supposed to handle things differently but I don't know how.
A claims based solution can work best here, where you:
Define a Claims Object in your API
Populate it when your API first receives an access token
Cache the claims object for subsequent requests with the same access token
This cache will always be in sync with the user session
See my blog post for further details on the pattern. And here is some implementation code.

Implementing JWT with Spring security without users

I would like to set up an IT solution based on the Front / Back principle.
Front side I would use a technology like React, Angular and Back side I would use a technology like java spring boot to implement controller Rest.
The front will make Rest requests on the back to retrieve data.
I would like to add a security concept to the solution by implementing the JWT standard on the back. Thus the client, knowing the secret, could request a token back and could make requests by specifying the token via the header of the request.
I found several tutorials explaining how to set up this type of solutions. In particular: https://medium.com/#nydiarra/secure-...n-e57a25806c50
In this tutorial, we assume that we define somewhere (here in a H2 database) the different users of the app and their role (admin or standard).
So the front could ask a token but it would have to indicate the user and his password and the secret defined. The back looks in the database and gives a token relative to the role defined for this user.
My question is simple. Do we have to define users and roles if we want to use JWT?
What I would have liked to do is not to inform and not to store potential users and their roles.
Simply the front requests a token with the secret without giving user and the back gives a token. Which will be used later in the header of the requests.

How do I properly secure a REST-like service using Spring Security based on cookies?

I read this article on using Spring Security to "secure" (password-protect) a REST-like service: http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/.
This solution is what I seem to want, however, I noticed that at the bottom of the article, the authentication process is based on a cookie. If you notice, after a user logs in, a cookie is sent back to the user, and the user keeps using this cookie on subsequent request to access the REST endpoints (see the curl commands).
My concern about this approach centers on security; meaning, what's to stop the user from sending this cookie to someone else for use or someone from copying this cookie and using the REST service without proper authentication?
Is there a way to set the cookie (or cookies) such that it is valid for only one user? For example, for only the IP that authenticated correctly? But even this is problematic, as multiple users may share one external IP address.
It looks like the code is just demonstrating how to maintain a session between requests, exactly as your browser would do, by storing the JSESSIONID cookie. So I think your question is really the same as "what's to stop a user from copying the session cookie from their browser and giving it to someone else?". Of course there is nothing to stop them doing that but why would they want to? The same argument applies to any kind of security token. There's nothing to stop them giving away their username and password either which would have the same effect.
In most cases a web service would be stateless, so it wouldn't use session cookies. But OAuth tokens and so on are just as sensitive, often more so since they usually have a longer life span.

Number of external requests when serving a resource

So, I have a web application that makes a lot of requests to the server for data. A project requirement is to have very fast server response times. The server is hosted on a cloud based platform.
The app uses sessions to keep track of user authentication once they've logged in. Since it's hosted on a cloud provider, I'm using a cache to back up session storage (in my case it's Auzre cache, but if you're unfamiliar with that think Redis)
The current flow is like this:
The user accesses a resource
Trying to get the session based on the session ID via the cache. This is a cache request.
User is authenticated via session state (if logged in).
Request for data is sent, usually via cache.
Data is returned to the user.
The problem with this approach is that it's hitting the cache twice. Removing the session altogether caused a significant speed improvement (about 50%).
I was considering hitting the cache once, asking for both the key I need for the user, and the SessionID to save the extra round trip. However, I've never seen this approach before, and it requires 'rolling my own session' as I'd have to generate the session IDs and such. I feel like there might be a simpler, easier way.
So, what would be the most efficient way to serve the user a resource and authenticate them?
Note: I'm using ASP.NET MVC/ WebAPI with C# but I don't find that very relevant to the question, so I left the language and platform out of the question because of it.
You would want to combine the authenticate and resource request steps into one single request. Not only is this faster, it is also safer than your implementation. Consider the following scenario:
User authenticate to the server. Result is success.
Authentication is changed. (e.g. user changes password, admin decides to lock the user account, etc.)
User makes a request using the sessionID in step 1.
To ensure that the user is not granted access to the resource, you'd want to authenticate the user precisely at step 3. But that doesn't make sense, you've already authenticated this user previously in step 1...
HTTP, in is core, is designed exactly to do this. There are various ways to pass authentication information along with the request, such as:
Write the authentication information in the content (stupid, but works)
Include authentication in the url, e.g. example.com/pic/123?sessionID=abc (better, but makes your url ugly and long)
Store session info in cookie (better, but what if the client does not support cookie? what about cookie expiration?)
Authenticate HTTP header (my best personal recommendation)
HTTP itself has an authenticate header meant to be compatible with "basic authentication" (it is well defined, look it up if you're interested). But you can implement your own custom header.
Any cache lookup is bound to be slow (compared to computation), so you should omit the cache for the authentication part all together. Your server should be stateless; i.e. do not keep track of login sessions. How do you know if the sessionID is valid? Put a timestamp on it. And to avoid others faking the sessionID, sign it as well.
So, your HTTP request would look something like this (pseudo code):
var request = new HttpRequest();
request.url = "example.com/pic/123";
request.Headers["CustomAuth"] = "id=abc&t=123456789&s=01de45890a";
Implement your own signing method, sort of like a hash function (you can use HMAC), and keep the key securely on the server. If the signature matches, you know you've signed this previously at the login, and it has to be from your server. A timestamp helps you detect session expiration and also protect against replay attacks.
Now in your server, do something like this:
public void Get(){
var authHeader = Request.Headers["CustomAuth"];
if(!validate(authHeader)){
Response.StatusCode = 404;
Response.End();
}else{
//something else
}
}
If you need to do login + session authenticate + resource request in one request, then there're simply just 2 ways for authentication. Users can either provide a username/password combination, or a session key. Think about this scenario, which comes from an API I worked on:
user register with username/password combo
server responds registration success / failure (e.g. username already taken)
if it was a success, user now logins with username/password combo
server returns a session token
Wouldn't it be simpler (and faster) if we do it this way:
user register with username/password combo
if it is success, respond "reg success" and "sessionToken=xxxxxx". if it is failure, respond "reg failure".
I hope this give you some idea.
Also, you can remove the authentication at the server end by modifying / restricting settings on the server to cater to requests coming only from the ip(s) where your web app is hosted. Your web application will let the request pass to server only if its authenticated and hence all the requests reaching the data server will be served automatically without checking for any authentication. In this case you will just need one cache hit to check if the user is authenticated and straight away hit the server.

where should i set the session api and client

Here is the situation, I have setup 2 codeigniter installation.
One will be a client and one will be an api. Further improvement of this will be
The client will no longer be made from CI, since I wasn't using it's functionality. I just wanted to start out from a mvc framework right on.
My question would be where should I be storing sessions? during logins.
Below is how I did it, but I think I did it wrong.
I created a Login from the client. This one sends the login credentials to the api and then validated these information sent by the client and will return a message/response whethere the login credentials were valid or not.
If the login details were valid, the api will set a session in it's controller like this
if(true) {
$this->session->set_userdata($array);
}
This is in the login_controller I created. Is this the proper way of setting sessions for a client of a api?
You've got the concept right. You only want to set session userdata upon verifying the user supplied valid credentials.
That said, make sure you're using encrypted cookies and, if you're handling sensitive data, store your session data in the database. Storing it in the database causes some odd quirks with how sessions work in CodeIgniter (mainly with flashdata), but the added benefit of positive identification might potentially be worth it.
By storing the session data in the database, you can more positively verify a user is who they claim to be (in terms of the session ID, etc). The reason is because the session data is stored only in the database, and not in the session cookie (which only holds session ID and some other info). That way, even if someone does manage to decrypt the cookie, they can't modify their userdata to pretend to be someone else, like you might be able to with the cookies only method.

Resources