Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/stateless_csrf_upon_login' into develop
- Loading branch information
Showing
25 changed files
with
719 additions
and
212 deletions.
There are no files selected for viewing
43 changes: 0 additions & 43 deletions
43
...on/src/main/java/org/cloudfoundry/identity/uaa/security/web/DelegatingRequestMatcher.java
This file was deleted.
Oops, something went wrong.
105 changes: 105 additions & 0 deletions
105
common/src/main/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* ****************************************************************************** | ||
* * 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.web; | ||
|
||
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; | ||
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 = 300; | ||
|
||
private RandomValueStringGenerator generator = new RandomValueStringGenerator(6); | ||
private String parameterName = DEFAULT_CSRF_COOKIE_NAME; | ||
private String headerName = DEFAULT_CSRF_HEADER_NAME; | ||
private int cookieMaxAge = DEFAULT_COOKIE_MAX_AGE; | ||
|
||
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); | ||
if (expire) { | ||
csrfCookie.setMaxAge(0); | ||
} else { | ||
csrfCookie.setMaxAge(getCookieMaxAge()); | ||
} | ||
response.addCookie(csrfCookie); | ||
} | ||
|
||
@Override | ||
public CsrfToken loadToken(HttpServletRequest request) { | ||
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
.../src/test/java/org/cloudfoundry/identity/uaa/web/CookieBasedCsrfTokenRepositoryTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* ****************************************************************************** | ||
* * 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.web; | ||
|
||
import org.junit.Test; | ||
import org.springframework.mock.web.MockHttpServletRequest; | ||
import org.springframework.mock.web.MockHttpServletResponse; | ||
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; | ||
import org.springframework.security.web.csrf.CsrfToken; | ||
|
||
import javax.servlet.http.Cookie; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotNull; | ||
|
||
public class CookieBasedCsrfTokenRepositoryTests { | ||
|
||
@Test | ||
public void testGetHeader_and_Parameter_Name() throws Exception { | ||
CookieBasedCsrfTokenRepository repo = new CookieBasedCsrfTokenRepository(); | ||
assertEquals(CookieBasedCsrfTokenRepository.DEFAULT_CSRF_COOKIE_NAME, repo.getParameterName()); | ||
repo.setParameterName("testcookie"); | ||
assertEquals("testcookie", repo.getParameterName()); | ||
|
||
assertEquals(CookieBasedCsrfTokenRepository.DEFAULT_CSRF_HEADER_NAME, repo.getHeaderName()); | ||
repo.setHeaderName("testheader"); | ||
assertEquals("testheader", repo.getHeaderName()); | ||
|
||
repo.setGenerator(new RandomValueStringGenerator() { | ||
@Override | ||
public String generate() { | ||
return "token-id"; | ||
} | ||
}); | ||
|
||
CsrfToken token = repo.generateToken(new MockHttpServletRequest()); | ||
assertEquals("testheader", token.getHeaderName()); | ||
assertEquals("testcookie", token.getParameterName()); | ||
assertEquals("token-id", token.getToken()); | ||
} | ||
|
||
@Test | ||
public void testSave_and_Load_Token() throws Exception { | ||
CookieBasedCsrfTokenRepository repo = new CookieBasedCsrfTokenRepository(); | ||
MockHttpServletRequest request = new MockHttpServletRequest(); | ||
MockHttpServletResponse response = new MockHttpServletResponse(); | ||
CsrfToken token = repo.generateToken(request); | ||
repo.saveToken(token, request, response); | ||
|
||
Cookie cookie = response.getCookie(token.getParameterName()); | ||
assertNotNull(cookie); | ||
assertEquals(token.getToken(), cookie.getValue()); | ||
assertEquals(true, cookie.isHttpOnly()); | ||
|
||
request.setCookies(cookie); | ||
|
||
CsrfToken saved = repo.loadToken(request); | ||
assertEquals(token.getToken(), saved.getToken()); | ||
assertEquals(token.getHeaderName(), saved.getHeaderName()); | ||
assertEquals(token.getParameterName(), saved.getParameterName()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.