CSRF token generation

前端 未结 9 933
清酒与你
清酒与你 2020-12-07 09:58

This is a question about generating CSRF tokens.

Usually I\'d like to generate a token based off of a unique piece of data associated with the user\'s session, and h

9条回答
  •  隐瞒了意图╮
    2020-12-07 10:40

    With the help of CSRF token we can sure incoming request is authenticated (know user not hacker)

    Please note i have required below approach but google can't help me even on stackoverflow i did't get mentioned code below but after collection of stackoverflow answer i have made my day. So it's useful for further searching/ specially for beginners

    I have described below Spring MVC with Spring Interceptor

    Note - I have used google cache to store salt in cache for re verification

    below dependency need to add pom.xml

        
        
            com.google.guava
            guava
            28.0-jre
        
    

    below HandlerInterceptorAdapter implemention

    
        package com.august.security;
    
        import java.security.SecureRandom;
        import java.util.Enumeration;
        import java.util.LinkedList;
        import java.util.List;
        import java.util.concurrent.TimeUnit;
    
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.http.HttpSession;
    
        import org.apache.commons.lang3.RandomStringUtils;
        import org.springframework.web.servlet.ModelAndView;
        import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    
        import com.google.common.cache.Cache;
        import com.google.common.cache.CacheBuilder;
    
        public class CsrfSecurity extends HandlerInterceptorAdapter {
            List urlList= new LinkedList<>();
            private static final String CSRF_TAG = "CSRF-CHECK";
    
            @SuppressWarnings("unchecked")
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handleer)
                    throws Exception {
                System.out.println("Inside Pre Handler");
    
                String reqUrl = request.getRequestURI().toString();
                System.out.println("Request URL : " + reqUrl);
                String ipAddress = request.getHeader("X-FORWARDED-FOR");
                if (ipAddress == null) {
                    ipAddress = request.getRemoteAddr();
                }
                //local host url http://localhost:8080/august/
                if (request.getRequestURI().contains("/august/")) {
                    System.out.println("pre handler return true");
                    //it will return and next executed postHandelr method
                    //because of on above url my webApplication page working
                    return true;
                }
                if (ignoreUrl().contains(request.getRequestURI())) {
                    System.out.println("inside ignore uri");
                    return true;
                } else {
                    System.out.println("CSRF Security intercepter preHandle method started.......");
                    String salt = request.getParameter("csrfPreventionSalt");
                    HttpSession sessionAttribute = request.getSession();
                    Cache csrfPreventionSalt = (Cache) sessionAttribute
                            .getAttribute("csrfPreventionSalt");
                    if (csrfPreventionSalt == null) {
                        System.out.println("Salt not matched session expired..");
                        parameterValuesPrint(request, "saltCacheNotFound");
                        response.sendRedirect("error");
                        return false;
                    } else if (salt == null) {
                        parameterValuesPrint(request, "noSaltValue");
                        System.out.println("Potential CSRF detected !! inform ASAP");
                        response.sendRedirect("error");
                        return false;
                    } else if (csrfPreventionSalt.getIfPresent(salt) == null) {
                        System.out.println("saltValueMisMatch");
                        System.out.println("Potential CSRF detected !! inform ASAP");
                        response.sendRedirect("error");
                    } else {
                        request.setAttribute("csrfPreventionSalt", csrfPreventionSalt);
                    }
                    return true;
                }
    
            }
    
            @SuppressWarnings("unchecked")
            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                    ModelAndView modelAndView) {
                System.out.println("Inside post Handler");
                System.out.println("CSRF Security key generator method started");
                try {
                    //localhost url http://localhost:8080/august/
                    //api is my controller path so no need to genrate token for api
                    if (request.getRequestURI().contains("/august/api/")) {
                        System.out.println("No need to genrate salt for api");
                    } else {
                        HttpSession sessionAttribute = request.getSession();
                        Cache csrfPreventionSaltCache = (Cache) sessionAttribute
                                .getAttribute("csrfPreventionSalt");
                        System.out.println("csrfPreventionSaltCache ::: " + csrfPreventionSaltCache);
                        if (csrfPreventionSaltCache == null) {
                            csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
                                    .expireAfterWrite(20, TimeUnit.MINUTES).build();
                            request.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
                        }
    
                        String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
                        System.out.println("csrfPreventionSalt genrated ::: " + salt);
                        csrfPreventionSaltCache.put(salt, Boolean.TRUE);
                        if (modelAndView != null) {
                            System.out.println("Model and view not null and salt is added in modelAndView");
                            modelAndView.addObject("csrfPreventionSalt", salt);
                        }
                    }
                } catch (Exception ex) {
                    System.out.println(ex.getMessage());
                    ex.printStackTrace();
                }
            }
    
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                    throws Exception {
                System.out.println("afterCompletion : ");
                if (ex != null) {
                    System.out.println("exception : " + ex.getMessage());
                    ex.printStackTrace();
                }
            }
    
            private List ignoreUrl() {
                if(urlList == null) {
                    urlList.add("/august/error");
                    //add here your ignored url.
                }
                return urlList;
            }
    
            private void parameterValuesPrint(HttpServletRequest request, String err) {
                StringBuilder reqParamAndValue = new StringBuilder();
                Enumeration params = request.getParameterNames();
                while (params.hasMoreElements()) {
                    Object objOri = params.nextElement();
                    String param = (String) objOri;
                    String value = request.getParameter(param);
                    reqParamAndValue = reqParamAndValue.append(param + "=" + value + ",");
                }
                System.out.println(CSRF_TAG + " " + err + "RequestedURL : " + request.getRequestURL());
            }
        }
    
    

    Below is Interceptor registration with spring context

    
    package com.august.configuration;
    
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.ComponentScan;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.ViewResolver;
        import org.springframework.web.servlet.config.annotation.EnableWebMvc;
        import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
        import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
        import com.august.security.CsrfSecurity;
    
        @Configuration
        @EnableWebMvc
        @ComponentScan(basePackages="com.august")
        public class SpringConfiguration extends WebMvcConfigurerAdapter  {
    
            @Bean
            public ViewResolver viewResolver() {
                InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
                //viewResolver.setViewClass(JstlView.class);
                viewResolver.setPrefix("/WEB-INF/views/");
                viewResolver.setSuffix(".jsp");
                return viewResolver;
    
            }
    
            @Bean
            public CsrfSecurity csrfSecurity() {
                return new CsrfSecurity();
            }
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new CsrfSecurity());
            }
        }
    

    below is my controller

    
        package com.august.v1.appcontroller;
    
        import javax.servlet.http.HttpSession;
    
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Controller;
        import org.springframework.ui.Model;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
    
    
        @Controller
        public class HomeController {
    
            @Autowired 
            HttpSession httpSession;
    
            @RequestMapping("/")
            public String index(Model model) {
                httpSession.invalidate();
                System.out.println("Home page loaded");
                return "index";
            }
        }
    

    below is my index.jsp jsp page

    
        <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
            pageEncoding="ISO-8859-1" isELIgnored="false"%>
             //don't forget to add isELIgnored="false" on old(version) jsp page because of i 
             //have wasted 1 hour for this
        
        
        
        
        ADS Home
        
        
        

    ${csrfPreventionSalt}

    For Understanding about CSRF - CSRF explanation

提交回复
热议问题