0

There is a spring application which needs user authentication.

It check if JWT cookie exists then allow user access else redirect to authentication application.

This authentication application validates user against database and return to original application with JWT cookie(private key of which is known to original application) as url parameter .

Original application then set JWT cookie, allow user access and send ajax request to spring backend which reinitialize the User session object.

User is defined as a component:

@Component
@Scope("session")
public class User {
}

In controller, i do this:

@Controller
@RequestMapping("/login")
@Scope("request")
public class LoginController {

    @Autowired
    private User user;
    @RequestMapping(value = "/do-login", method = RequestMethod.POST)
    @ResponseBody
    public String login(HttpServletRequest  request) throws IOException{
        user = new User()
        // SET USER PROPERTIES USING JWT TOKEN
    }
}

Is it the correct approach? Shall i directly set values in session instead of using spring component? Shall jwt token be stored in session rather than cookie?

Gautam Kumar
  • 941
  • 2
  • 16
  • 37
  • 1
    In my ways, It's better to use spring security for user authentication in spring framework. As its more secure than JWT only. If you want to go with this approach please do reply so I can post a good answer for this. – Ankur Mahajan Aug 28 '15 at 03:41
  • @AnkurMahajan sure, that will be helpful. – Gautam Kumar Aug 28 '15 at 07:29
  • +1 for using Spring-security. Not only for login, there are many more features which Spring-security provides. – We are Borg Aug 28 '15 at 07:42

2 Answers2

1

First of all, you must think about why use JWT. JWT were created to attend particular problems of modern web applications, principally the server state problem that represent cookies.

1. Apps are distributed across many servers

Many of today's applications aren't deployed the same way they were in the past. It is now very common--and often necessary--for apps to be distributed across many servers so that up-time is increased and latency issues are mitigated. With this comes the side effect that, when a user accesses an application, it is no longer guaranteed that they are always accessing the same server. Since traditional authentication relies on the server to keep the user's authentication state in memory, things break down when the app is accessed from different servers. The user might be logged in on one server but not on the others that the application is distributed across.

2. Apps use APIs for data

Using APIs in this fashion is great, but things can become challenging when it comes to authentication. The traditional approach of using sessions and cookies for the user's identity doesn't work so well in these cases because their use introduces state to the application. One of the tenets of a RESTful API is that it should be stateless, meaning that, when a request is made, a response within certain parameters can always be anticipated without side effects. A user's authentication state introduces such a side effect, which breaks this principle. Keeping the API stateless and therefore without side effect means that maintainability and debugging are made much easier.

3. CORS (very common with Single Page Applications)

Another challenge here is that it is quite common for an API to be served > from one server and for the actual application to consume it from another. To make this happen, we need to enable Cross-Origin Resource Sharing (CORS). Since cookies can only be used for the domain from which they originated, they aren't much help for APIs on different domains than the application.

RESTful APIs are more common with each day and they must be stateless by definition. The stateless feature allows horizontal scaling because a request can be attended by any server. You can have a simpler JSON API with a stateless backend and benefit from the horizontal scalling without REST. So, you can use Custom JWT authentication that integrates with Spring and benefit from the authorization part if you require complex authorization like method authorization.

When you say

Shall jwt token be stored in session rather than cookie?

I think you don't fully get the idea of JWT because the JWT token does not have to be stored in the server-side (session). This would mean state in server side what is JWT comes to avoid. The JWT must be created on succesfull user authentication against a login endpoint (something like /login). This work will be done by a AuthenticationSuccessHandler that is injected to the UsernamePasswordAuthenticationFilter. For example:

public class JWTAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    protected JWSSigner jwsSigner;

    public JWTAuthenticationSuccessHandler(JWSSigner jwsSigner){
        this.jwsSigner = jwsSigner;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String ipaddress = request.getRemoteAddr();
        JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
        JWTClaimsSet claimsSet = builder.subject("subject").issuer("issuer").expirationTime(new Date(new Date().getTime() + 60 * 1000)).claim("ipaddress",ipaddress).build();
        SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);

        try {
            signedJWT.sign(jwsSigner);
            String serializedJWT = signedJWT.serialize();
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getOutputStream().println(serializedJWT);
        } catch (JOSEException e) {
            e.printStackTrace();// TODO
        }


    }
}

Then, the client must store the token in localStorage or cookie and send it with each request. The server will only verify the integrity of the token, authentication against user credentials is no longer needed (unless the token has expired).

So, what you expect from JWT? What features must accomplish your authentication mechanism?

Community
  • 1
  • 1
gabrielgiussi
  • 9,245
  • 7
  • 41
  • 71
0

Why to use Spring security.

CONFIGURATIONS:

Use security:form-login login-page tag in your spring security configuration xml file. It will automatically redirect your application to login page.

REMEBER: to configure these url's(security:intercept-url pattern) in your Controller.

<security:http auto-config="true" use-expressions="true">

        <security:intercept-url pattern="/login"
            access="permitAll" />
        <security:intercept-url pattern="/accessDenied"
            access="permitAll" />
        <security:intercept-url pattern="/loginFail"
            access="permitAll" />
        <security:intercept-url pattern="/logout"
            access="permitAll" />

        <security:intercept-url pattern="/resources/**"
            access="permitAll" />
        <security:intercept-url pattern="/**"
            access="hasRole('ROLE_ADMIN')" />

        <security:access-denied-handler
            error-page="/accessDenied" />

        <security:form-login login-page="/login"
            default-target-url="/home" always-use-default-target="true"
            authentication-failure-url="/loginFail" username-parameter="username"
            password-parameter="password" />

        <security:logout logout-success-url="/logout" />
    </security:http>

This one is the best reference tutorial on spring security, I have came across. Please try to configure your application according to this and If you want both configurations(JAVA/XML) refer MKYONG example.

Recommend: Use spring security, it's a great spring tool to manipulate/handle authentication processes and its very easy to configure you don't have to go very deep in this.

I hope this will help.

Ankur Mahajan
  • 3,396
  • 3
  • 31
  • 42
  • If you want more clarification about this answer. Just leave the comment, I will tell you about each security attribute defined in the spring security configuration xml. – Ankur Mahajan Aug 29 '15 at 06:00