org.springframework.boot
spring-boot-starter-test
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/CSRFConfig.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/CSRFConfig.java
new file mode 100644
index 0000000000..1a8f05359c
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/CSRFConfig.java
@@ -0,0 +1,25 @@
+package io.jsonwebtoken.jjwtfun.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+
+@Configuration
+public class CSRFConfig {
+
+
+ private static final Logger log = LoggerFactory.getLogger(CSRFConfig.class);
+
+ @Value("#{ @environment['jjwtfun.secret'] ?: 'secret' }")
+ String secret;
+
+ @Bean
+ @ConditionalOnMissingBean
+ public CsrfTokenRepository jwtCsrfTokenRepository() {
+ return new JWTCsrfTokenRepository(secret);
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/JWTCsrfTokenRepository.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/JWTCsrfTokenRepository.java
new file mode 100644
index 0000000000..2489beb76e
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/JWTCsrfTokenRepository.java
@@ -0,0 +1,76 @@
+package io.jsonwebtoken.jjwtfun.config;
+
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+import org.springframework.security.web.csrf.DefaultCsrfToken;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.UUID;
+
+public class JWTCsrfTokenRepository implements CsrfTokenRepository {
+
+ private static final Logger log = LoggerFactory.getLogger(JWTCsrfTokenRepository.class);
+ private static final String DEFAULT_CSRF_TOKEN_ATTR_NAME = CSRFConfig.class.getName().concat(".CSRF_TOKEN");
+
+ private String secret;
+
+ public JWTCsrfTokenRepository(String secret) {
+ this.secret = secret;
+ }
+
+ @Override
+ public CsrfToken generateToken(HttpServletRequest request) {
+
+ String id = UUID.randomUUID().toString().replace("-", "");
+
+ Date now = new Date();
+ Date exp = new Date(System.currentTimeMillis() + (1000*60)); // 1 minute
+
+ String token;
+ try {
+ token = Jwts.builder()
+ .setId(id)
+ .setIssuedAt(now)
+ .setNotBefore(now)
+ .setExpiration(exp)
+ .signWith(SignatureAlgorithm.HS256, secret.getBytes("UTF-8"))
+ .compact();
+ } catch (UnsupportedEncodingException e) {
+ log.error("Unable to create CSRf JWT: {}", e.getMessage(), e);
+ token = id;
+ }
+
+ return new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", token);
+ }
+
+ @Override
+ public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
+ if (token == null) {
+ HttpSession session = request.getSession(false);
+ if (session != null) {
+ session.removeAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME);
+ }
+ }
+ else {
+ HttpSession session = request.getSession();
+ session.setAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME, token);
+ }
+ }
+
+ @Override
+ public CsrfToken loadToken(HttpServletRequest request) {
+ HttpSession session = request.getSession(false);
+ if (session == null) {
+ return null;
+ }
+ return (CsrfToken) session.getAttribute(DEFAULT_CSRF_TOKEN_ATTR_NAME);
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java
new file mode 100644
index 0000000000..2715990d38
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java
@@ -0,0 +1,23 @@
+package io.jsonwebtoken.jjwtfun.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.csrf.CsrfTokenRepository;
+
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ CsrfTokenRepository jwtCsrfTokenRepository;
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .csrf().csrfTokenRepository(jwtCsrfTokenRepository).and()
+ .authorizeRequests()
+ .antMatchers("/**")
+ .permitAll();
+ }
+}
diff --git a/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/FormController.java b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/FormController.java
new file mode 100644
index 0000000000..178af2f48d
--- /dev/null
+++ b/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/controller/FormController.java
@@ -0,0 +1,26 @@
+package io.jsonwebtoken.jjwtfun.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@Controller
+public class FormController {
+
+ @RequestMapping(value = "/jwt-csrf-form", method = GET)
+ public String csrfFormGet() {
+ return "jwt-csrf-form";
+ }
+
+ @RequestMapping(value = "/jwt-csrf-form", method = POST)
+ public String csrfFormPost(@RequestParam(name = "_csrf") String csrf, Model model) {
+
+ model.addAttribute("csrf", csrf);
+
+ return "jwt-csrf-form-result";
+ }
+}
diff --git a/jjwt/src/main/resources/templates/fragments/head.html b/jjwt/src/main/resources/templates/fragments/head.html
new file mode 100644
index 0000000000..ce76b0e655
--- /dev/null
+++ b/jjwt/src/main/resources/templates/fragments/head.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Nothing to see here, move along.
+
+
\ No newline at end of file
diff --git a/jjwt/src/main/resources/templates/jwt-csrf-form-result.html b/jjwt/src/main/resources/templates/jwt-csrf-form-result.html
new file mode 100644
index 0000000000..6547459c27
--- /dev/null
+++ b/jjwt/src/main/resources/templates/jwt-csrf-form-result.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
You made it!
+
+
BLARG
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jjwt/src/main/resources/templates/jwt-csrf-form.html b/jjwt/src/main/resources/templates/jwt-csrf-form.html
new file mode 100644
index 0000000000..dcdb664647
--- /dev/null
+++ b/jjwt/src/main/resources/templates/jwt-csrf-form.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file