Spring MVC Security Token based Authentication

2019-09-04 18:18发布

问题:

Can anyone please help me in this. I have been assigned to secure an existing web application.

Issue: when a user already logs into the application (that means the session is active), at that time an attacker can guess the input fields and save url and create a similar page and send a hyper link. If the user clicks on that link, it will not go through javascript, rather it will hit the spring controller. Since the session is active, it will save the attackers data into the database.

Here is what we are using now. 1) Spring Security

<http auto-config="true"> 
    <intercept-url pattern="/**" access="ROLE_ADMIN, ROLE_HR" />
    <custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>

<beans:bean id="siteminderFilter" class="com.mywbsite.security.UserFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="continueFilterChainOnUnsuccessfulAuthentication" value="false"/>
</beans:bean>

This method is called when user logs into the application first time

protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {

    String userId = request.getHeader("uid");
    logger.info("<<<<<<<<<<<<<<<<<<<<<userId>>>>>>>>>>>>>>>>>>>>>>> : "+userId);

    return userId;
}

This method is called when user does anything which calls any controller/java

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

    System.out.println(request.getParameter(BaseConstants.DV_USER_SESSION_IDENTIFIER));
    logger.info(request.getParameter(BaseConstants.DV_USER_SESSION_IDENTIFIER));
    logger.info("Existing the UserFilter.doFilter method...");
}

Solution: In controller/filter I have to identify if the request is coming from my application or from anywhere else.

Here is what I am thinking to implement.

  • Create a random token inside getPreAuthenticatedPrincipal() method and store that in session.
  • Get the variable from session and put in a hidden variable in jsp
  • When user does any action, pass the hidden variable with value and pass to controller as request parameter.
  • In Controller/Filter get the random value from session and get the hidden value from request parameter. Now compare. If it matches, then do normal operation, else throw error page.

Now my concern is if I implement the above solution, I have to write hidden variable code in every jsp and pass to controller in each request and request parameter.

Can you please help me how to make it easy. Thanks in advance

回答1:

I resolved the above issue by using Spring CSRF. I faced an issue while implementing CSRF. The issue was CSRF was creating 2 tokens. It took long time (at least 1 day) to find the root cause. The root cases was I was trying to get the csrf token value in my Fiter and print it using below code. So once I wrtie the request.getAttribute("_csrf"), it creats a new token. So I just delted the below lines from my csrf and just did what it was described in above spring csrf link. It worked

//      CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
//      System.out.println(">>>>>>>>>>UserFilter.getPreAuthenticatedPrincipal() CSRF Token: " + token.getToken());