/* * ****************************************************************************** * * Cloud Foundry * * Copyright (c) [2009-2015] Pivotal Software, Inc. All Rights Reserved. * * * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * * You may not use this product except in compliance with the License. * * * * This product includes a number of subcomponents with * * separate copyright notices and license terms. Your use of these * * subcomponents is subject to the terms and conditions of the * * subcomponent's license, as noted in the LICENSE file. * ****************************************************************************** */ package org.cloudfoundry.identity.uaa.security.web; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; import org.springframework.security.web.csrf.CsrfFilter; 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.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CookieBasedCsrfTokenRepository implements CsrfTokenRepository { public static final String DEFAULT_CSRF_HEADER_NAME = "X-CSRF-TOKEN"; public static final String DEFAULT_CSRF_COOKIE_NAME = "X-Uaa-Csrf"; public static final int DEFAULT_COOKIE_MAX_AGE = 60 * 60 * 24 *30; // 22 characters of the 62-ary codec gives about 131 bits of entropy, 62 ^ 22 ~ 2^ 130.9923 private RandomValueStringGenerator generator = new RandomValueStringGenerator(22); private String parameterName = DEFAULT_CSRF_COOKIE_NAME; private String headerName = DEFAULT_CSRF_HEADER_NAME; private int cookieMaxAge = DEFAULT_COOKIE_MAX_AGE; private boolean secure; public int getCookieMaxAge() { return cookieMaxAge; } public void setCookieMaxAge(int cookieMaxAge) { this.cookieMaxAge = cookieMaxAge; } public String getHeaderName() { return headerName; } public void setHeaderName(String headerName) { this.headerName = headerName; } public String getParameterName() { return parameterName; } public void setParameterName(String parameterName) { this.parameterName = parameterName; } public void setGenerator(RandomValueStringGenerator generator) { this.generator = generator; } public RandomValueStringGenerator getGenerator() { return generator; } @Override public CsrfToken generateToken(HttpServletRequest request) { String token = generator.generate(); return new DefaultCsrfToken(getHeaderName(), getParameterName(), token); } @Override public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) { boolean expire = false; if (token==null) { token = generateToken(request); expire = true; } Cookie csrfCookie = new Cookie(token.getParameterName(), token.getToken()); csrfCookie.setHttpOnly(true); csrfCookie.setSecure(secure || request.getProtocol().equals("https")); if (expire) { csrfCookie.setMaxAge(0); } else { csrfCookie.setMaxAge(getCookieMaxAge()); } response.addCookie(csrfCookie); } @Override public CsrfToken loadToken(HttpServletRequest request) { boolean requiresCsrfProtection = CsrfFilter.DEFAULT_CSRF_MATCHER.matches(request); if(requiresCsrfProtection) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : request.getCookies()) { if (getParameterName().equals(cookie.getName())) { return new DefaultCsrfToken(getHeaderName(), getParameterName(), cookie.getValue()); } } } } return null; } public boolean isSecure() { return secure; } public void setSecure(boolean secure) { this.secure = secure; } }