Spring Two factor authentication where to save credentials - spring

I'm trying to implement two factor authentication in my Spring application.
Desired situation
I want the user to first log in with his username and password, if those are correct I want the system to generate a random key and email that to the user. After that the system has to redirect the user to a page where he only has to enter the token and login to the system.
What I got so far (in pseudo code)
User enters the login.jsp page. Upon logging in with username/password the system sends out a CustomMade AuthenticationException. In the AuthenticationFailureHandler I do a getAuthentication on the exception (I'm aware of deprecacy) But I use the username to send the user his token. After that I put the exception in the session (using request.getSession().setAttribute ) and finally the system reloads the login.jsp.
Login.jsp sees the exception in the session and shows the token input field. User fills the token input field and logs in. System authenticates the user with the credentials in the session and the given token.
Question
I think it's bad practice to save the username/password in session. Two possible solutions I thought of:
After checking Username/Password. Save the username in a static variable or in DB. When user is entering the token check whether username is in the variable/db and check the token. If the token is correct do a login with the user.
After checking username / password log the user in with a low role. With the low role the user can only go to the token page, after entering a valid token the system gives the user new authorities.
What would be the best solution to implement?

Related

Understanding the authorization part of JWT and session

So i read about how authentication is done using JWT, where we basically verify if the token is valid using a private key (assuming RSA is the algortihm). And if the token is valid, then the user is considered authenticated. And I also read about session authentication where we check if the user supplied session id (through cookie), exist in the session store (assuming mysql / redis is used to store session). If it exist, then the user is considered authenticated.
But how do we use JWT and session for authorization ? Lets consider an action such as GET invoice , whereby a user can only view the invoice that he owns.
If we consider the user is already authenticated,
how do we check if the user is authorized if we are using JWT?
And how do we do it for session ?
You are probably confusing the things. One of the benefits using JWT is to avoid maintaining sessions which is big bottle neck in scaling.
JWT (Json Web Token) carry all the information that would require it to get authenticated, you don't need to maintain the session. Every single HTTP request to server will carry JWT that would contain necessary user claims including the signature. On server you will validate the signature to verify if the token is valid or not. You can verify the token without maintaining any session and there are number of ways to do it.
Since JWT is essentially a Json object (Header, Body , Signature) , you can put in claims (emails, roles, profile etc) in JWT body. Once you verify the token , you can extract the claims including any roles and check if user is authorized to access the resource.
You must look into Open ID Connect and Tokens here

Spring security - Is username and password must for creating authentication

I am using spring security to authenticate a user. The user is authenticated by a third party and will already be authenticated when he reaches my application.
To implemented this, I have simulated a Authentication object.
I don't have any username and password and instead just have identifier. I check if this identifier is valid or not using my custom code.
My query is as follows:
Do I require a username and password to create a authentication object.
I have done without providing username and password and my application works fine.
I just want to ensure that I am using spring-security correctly.
Is there any impact of not putting username and password in Authentication object. I read below in AbstractUserDetailsAuthenticationProvider:
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
I have also implemented a custom provider.
What does above comments means?
Is my approach correct?
The Authentication interface in Spring Security represents a token for carrying out validations against the configured security rules and the current call context. This interface has six methods of interest - getPrincipal, getCredentials, getDetails, getAuthorities, isAuthenticated and setAuthenticated.
Since you are authenticating users on your own, you should be mostly concerned with calling setAuthenticated(true) at an appropriate stage in the flow so that isAuthenticated starts returning true to indicate an authenticated user. Additionally, you may add GrantedAuthoritys to the Authentication for any role-based checks to work correctly.
However, it will be useful to make sure that getPrincipal (username in the case of form login) returns a unique value per user or per session. This will prevent the possibility of user sessions getting interchanged due to non-unique principal, which is used by the framework to identify users uniquely.
You may leave getCredentials and getDetails unimplemented. In fact, getCredentials (password in the case of form login) should be left unimplemented in your case because your application does not have the credentials used to actually authenticate the user; plus, it is a security risk to keep the credentials around after the user has been authenticated successfully.

What should happen to when user changes username in Oauth2

Am pretty new to Oauth2 and I wondering what should happen in a scenario where a user changes the username used to authorize a client.
Should all access tokens expire after change is successful requesting the client to a new access code?
or
The access tokens are to be updated with the new username by the authentication server?
In normal cases, username of a user and the unique ID of the user are different. If an access token is associated with the unique ID (not with username), you don't have to invalidate or update access tokens even if username is changed.
Otherwise, if you associate access tokens with username (not with the unique ID), when username is changed, you should invalidate access tokens or update access tokens with the new username.
The OAuth spec doesn't specify what should happen -- one the user passes authentication and gets a token, they have an active authorization "session" as long as that token is valid.
You can invalidate tokens, and authorization sessions, as you like, though. So as a matter of policy, if you want to invalidate their tokens when there's a change to the account, then you are free to do that.
Just remember to invalidate both access tokens and refresh tokens for the user, or else they might just use their refresh token to start over with a access token.

spring security 2 phase authentication

I'm a newb to spring security and I'm not sure where to start. I have requirements to have a multi-page authentication. The first page authenticates the username, if the username exists the web app progresses to the password page. (site image) The second page authenticates the password, if successful then the user is authenticated. I'm not sure how to fit this into spring auth. Do I add multiple login-filters and authenticationproviders ? If I add multiple authenticationproviders, will I be authenticated after the first login ?
Page 1: User enters username. Submit this to your own controller where you check if the user exists. If the user exists, display page 2, pass the username in the model. You better not include Spring Security authentication in this step.
Page 2: User enters password. Use a readonly or hidden field to keep track of the username. Submit the form to Spring Security form login filter. You don't need multiple authentication providers.
Note: This approach has an information "leak"; any visitor can check whether a username exists in the system or not.
It depends on the kind of your authentication:
JDBCAuthentication
You can do with #holmis83 suggests.
LDAPAuthentication:
I am afraid tht you can't do that.

How to implement one controller mapping method for different scenarios

I have a spring controller method which could be called in different scenarios. here is the example...
#RequestMapping("/resetpassword")
public ModelAndView resetpassword( #Valid #ModelAttribute("resetpasswordForm") ResetPawdFormForm resetPawdFormForm, ModelAndView modelAndView){
... this method could be executed in 3 different scenarios....
using the hyper link coming from the user reset password link sent to user email..
eg: localhost/myApp/login/resetpassword//
Here I can authenticate userID and activationSecretCode in DB and let user reset password
user can click on resetpassword link from user settings page.
eg: Since the user is already coming from user settings page, I can validate userSession and allow him to reset password
User can login for first time successfully, but are forced to reset password due to admin requirements for reset initial default password.
eg: in this user neither have session, nor passing any activationcode to validate.
login method validates userid/default password and redirects to resetpassword mapping(method=GET).
How can the system authenticate the user request and allow him to reset password?
One alternative for this is, to use flash attributes and set a authenticationKey as flash attributes...which could be verified in resetpassword method.
is there other way to implement this....
Note: I posted an issue in implementing this approach in
Post: Spring: How to pass Java objects during redirect while using ModelAttribute
Any help?
I think the best way to implement this is using three different action methods:
resetPassword (e-mails)
resetLoggedUserPassword (via settings)
changeDefaultPassword
They may even share the same view, but the behaviors are not equal, so I would avoid overloading the action responsibility.
EDIT: elaborating on your comment:
1) To secure the e-mail link, one way is to add a authentication token. The token can be as weak as a hashed user id plus some salt string, or as strong as a GUID with expiration time in a database table, generated whenever a user requests a password reset.
2) The settings way is not a problem, considering that the user is already logged in.
3) The temporary password action can be secured the same way as 1, or the same way as 2, if you put the user on the session. Logging in the user even with the default password status shouldn't be a concern if the code that verify the status of the account are inside a request filter.

Resources