SEC-2325: Polish CSRF Tag support

- Rename csrfField to csrfInput
- Make AbstractCsrfTag package scope
- rename FormFieldTag to CsrfInputTag
- rename MetaTagsTag to CsrfMetaTagsTag
- removed whitespace from tag output so output is
  minimized & improving browser performance
- Update @since
- changed test names to be more meaningful
This commit is contained in:
Rob Winch 2014-03-07 15:25:57 -06:00
parent a3e0475998
commit 32d3e29c65
8 changed files with 39 additions and 39 deletions

View File

@ -3139,7 +3139,7 @@ The last step is to ensure that you include the CSRF token in all PATCH, POST, P
</form> </form>
---- ----
An easier approach is to use <<the-csrffield-tag,the csrfField tag>> from the Spring Security JSP tag library. An easier approach is to use <<the-csrfInput-tag,the csrfInput tag>> from the Spring Security JSP tag library.
[NOTE] [NOTE]
==== ====
@ -5037,17 +5037,17 @@ The permissions are passed to the `PermissionFactory` defined in the application
This tag also supports the `var` attribute, in the same way as the `authorize` tag. This tag also supports the `var` attribute, in the same way as the `authorize` tag.
=== The csrfField Tag === The csrfInput Tag
If CSRF protection is enabled, this tag inserts a hidden form field with the correct name and value for the CSRF protection token. If CSRF protection is not enabled, this tag outputs nothing. If CSRF protection is enabled, this tag inserts a hidden form field with the correct name and value for the CSRF protection token. If CSRF protection is not enabled, this tag outputs nothing.
Normally Spring Security automatically inserts a CSRF form field for any `<form:form>` tags you use, but if for some reason you cannot use `<form:form>`, `csrfField` is a handy replacement. Normally Spring Security automatically inserts a CSRF form field for any `<form:form>` tags you use, but if for some reason you cannot use `<form:form>`, `csrfInput` is a handy replacement.
You should place this tag within an HTML `<form></form>` block, where you would normally place other input fields. Do NOT place this tag within a Spring `<form:form></form:form>` block—Spring Security handles Spring forms automatically. You should place this tag within an HTML `<form></form>` block, where you would normally place other input fields. Do NOT place this tag within a Spring `<form:form></form:form>` block—Spring Security handles Spring forms automatically.
[source,xml] [source,xml]
---- ----
<form method="post" action="/do/something"> <form method="post" action="/do/something">
<sec:csrfField /> <sec:csrfInput />
Name:<br /> Name:<br />
<input type="text" name="name" /> <input type="text" name="name" />
... ...

View File

@ -25,10 +25,10 @@ import java.io.IOException;
/** /**
* An abstract tag for handling CSRF operations. * An abstract tag for handling CSRF operations.
* *
* @since 3.2.1 * @since 3.2.2
* @author Nick Williams * @author Nick Williams
*/ */
public abstract class AbstractCsrfTag extends TagSupport { abstract class AbstractCsrfTag extends TagSupport {
@Override @Override
public int doEndTag() throws JspException { public int doEndTag() throws JspException {

View File

@ -22,14 +22,14 @@ import org.springframework.security.web.csrf.CsrfToken;
* A JSP tag that prints out a hidden form field for the CSRF token. See the JSP Tab Library documentation for more * A JSP tag that prints out a hidden form field for the CSRF token. See the JSP Tab Library documentation for more
* information. * information.
* *
* @since 3.2.1 * @since 3.2.2
* @author Nick Williams * @author Nick Williams
*/ */
public class FormFieldTag extends AbstractCsrfTag { public class CsrfInputTag extends AbstractCsrfTag {
@Override @Override
public String handleToken(CsrfToken token) { public String handleToken(CsrfToken token) {
return "<input type=\"hidden\" name=\"" + token.getParameterName() + "\" value=\"" + token.getToken() + return "<input type=\"hidden\" name=\"" + token.getParameterName() + "\" value=\"" + token.getToken() +
"\" />\n"; "\" />";
} }
} }

View File

@ -22,15 +22,15 @@ import org.springframework.security.web.csrf.CsrfToken;
* A JSP tag that prints out a meta tags holding the CSRF form field name and token value for use in JavaScrip code. * A JSP tag that prints out a meta tags holding the CSRF form field name and token value for use in JavaScrip code.
* See the JSP Tab Library documentation for more information. * See the JSP Tab Library documentation for more information.
* *
* @since 3.2.1 * @since 3.2.2
* @author Nick Williams * @author Nick Williams
*/ */
public class MetaTagsTag extends AbstractCsrfTag { public class CsrfMetaTagsTag extends AbstractCsrfTag {
@Override @Override
public String handleToken(CsrfToken token) { public String handleToken(CsrfToken token) {
return "<meta name=\"_csrf_parameter\" content=\"" + token.getParameterName() + "\" />\n" + return "<meta name=\"_csrf_parameter\" content=\"" + token.getParameterName() + "\" />" +
" <meta name=\"_csrf_header\" content=\"" + token.getHeaderName() + "\" />\n" + "<meta name=\"_csrf_header\" content=\"" + token.getHeaderName() + "\" />" +
" <meta name=\"_csrf\" content=\"" + token.getToken() + "\" />\n"; "<meta name=\"_csrf\" content=\"" + token.getToken() + "\" />";
} }
} }

View File

@ -200,8 +200,8 @@
where you would normally place other <input>s. Do NOT place this tag within a Spring <form:form></form:form> where you would normally place other <input>s. Do NOT place this tag within a Spring <form:form></form:form>
block—Spring Security handles Spring forms automatically. block—Spring Security handles Spring forms automatically.
]]></description> ]]></description>
<name>csrfField</name> <name>csrfInput</name>
<tag-class>org.springframework.security.taglibs.csrf.FormFieldTag</tag-class> <tag-class>org.springframework.security.taglibs.csrf.CsrfInputTag</tag-class>
<body-content>empty</body-content> <body-content>empty</body-content>
</tag> </tag>
@ -218,7 +218,7 @@
tag outputs nothing. tag outputs nothing.
]]></description> ]]></description>
<name>csrfMetaTags</name> <name>csrfMetaTags</name>
<tag-class>org.springframework.security.taglibs.csrf.MetaTagsTag</tag-class> <tag-class>org.springframework.security.taglibs.csrf.CsrfMetaTagsTag</tag-class>
<body-content>empty</body-content> <body-content>empty</body-content>
</tag> </tag>

View File

@ -36,9 +36,9 @@ public class AbstractCsrfTagTests {
} }
@Test @Test
public void testDoEndTag01() throws JspException, UnsupportedEncodingException { public void noCsrfDoesNotRender() throws JspException, UnsupportedEncodingException {
this.tag.handleReturn = "fooBarBazQux"; this.tag.handleReturn = "shouldNotBeRendered";
int returned = this.tag.doEndTag(); int returned = this.tag.doEndTag();
@ -47,7 +47,7 @@ public class AbstractCsrfTagTests {
} }
@Test @Test
public void testDoEndTag02() throws JspException, UnsupportedEncodingException { public void hasCsrfRendersReturnedValue() throws JspException, UnsupportedEncodingException {
CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789"); CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789");
this.request.setAttribute(CsrfToken.class.getName(), token); this.request.setAttribute(CsrfToken.class.getName(), token);
@ -62,7 +62,7 @@ public class AbstractCsrfTagTests {
} }
@Test @Test
public void testDoEndTag03() throws JspException, UnsupportedEncodingException { public void hasCsrfRendersDifferentValue() throws JspException, UnsupportedEncodingException {
CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789"); CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789");
this.request.setAttribute(CsrfToken.class.getName(), token); this.request.setAttribute(CsrfToken.class.getName(), token);

View File

@ -10,36 +10,36 @@ import static org.junit.Assert.*;
/** /**
* @author Nick Williams * @author Nick Williams
*/ */
public class FormFieldTagTests { public class CsrfInputTagTests {
public FormFieldTag tag; public CsrfInputTag tag;
@Before @Before
public void setUp() { public void setUp() {
this.tag = new FormFieldTag(); this.tag = new CsrfInputTag();
} }
@Test @Test
public void testHandleToken01() { public void handleTokenReturnsHiddenInput() {
CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789"); CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789");
String value = this.tag.handleToken(token); String value = this.tag.handleToken(token);
assertNotNull("The returned value should not be null.", value); assertNotNull("The returned value should not be null.", value);
assertEquals("The output is not correct.", assertEquals("The output is not correct.",
"<input type=\"hidden\" name=\"_csrf\" value=\"abc123def456ghi789\" />\n", "<input type=\"hidden\" name=\"_csrf\" value=\"abc123def456ghi789\" />",
value); value);
} }
@Test @Test
public void testHandleToken() { public void handleTokenReturnsHiddenInputDifferentTokenValue() {
CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "csrfParameter", "fooBarBazQux"); CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "csrfParameter", "fooBarBazQux");
String value = this.tag.handleToken(token); String value = this.tag.handleToken(token);
assertNotNull("The returned value should not be null.", value); assertNotNull("The returned value should not be null.", value);
assertEquals("The output is not correct.", assertEquals("The output is not correct.",
"<input type=\"hidden\" name=\"csrfParameter\" value=\"fooBarBazQux\" />\n", "<input type=\"hidden\" name=\"csrfParameter\" value=\"fooBarBazQux\" />",
value); value);
} }
} }

View File

@ -10,40 +10,40 @@ import static org.junit.Assert.*;
/** /**
* @author Nick Williams * @author Nick Williams
*/ */
public class MetaTagsTagTests { public class CsrfMetaTagsTagTests {
public MetaTagsTag tag; public CsrfMetaTagsTag tag;
@Before @Before
public void setUp() { public void setUp() {
this.tag = new MetaTagsTag(); this.tag = new CsrfMetaTagsTag();
} }
@Test @Test
public void testHandleToken01() { public void handleTokenRendersTags() {
CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789"); CsrfToken token = new DefaultCsrfToken("X-Csrf-Token", "_csrf", "abc123def456ghi789");
String value = this.tag.handleToken(token); String value = this.tag.handleToken(token);
assertNotNull("The returned value should not be null.", value); assertNotNull("The returned value should not be null.", value);
assertEquals("The output is not correct.", assertEquals("The output is not correct.",
"<meta name=\"_csrf_parameter\" content=\"_csrf\" />\n" + "<meta name=\"_csrf_parameter\" content=\"_csrf\" />" +
" <meta name=\"_csrf_header\" content=\"X-Csrf-Token\" />\n" + "<meta name=\"_csrf_header\" content=\"X-Csrf-Token\" />" +
" <meta name=\"_csrf\" content=\"abc123def456ghi789\" />\n", "<meta name=\"_csrf\" content=\"abc123def456ghi789\" />",
value); value);
} }
@Test @Test
public void testHandleToken02() { public void handleTokenRendersTagsDifferentToken() {
CsrfToken token = new DefaultCsrfToken("csrfHeader", "csrfParameter", "fooBarBazQux"); CsrfToken token = new DefaultCsrfToken("csrfHeader", "csrfParameter", "fooBarBazQux");
String value = this.tag.handleToken(token); String value = this.tag.handleToken(token);
assertNotNull("The returned value should not be null.", value); assertNotNull("The returned value should not be null.", value);
assertEquals("The output is not correct.", assertEquals("The output is not correct.",
"<meta name=\"_csrf_parameter\" content=\"csrfParameter\" />\n" + "<meta name=\"_csrf_parameter\" content=\"csrfParameter\" />" +
" <meta name=\"_csrf_header\" content=\"csrfHeader\" />\n" + "<meta name=\"_csrf_header\" content=\"csrfHeader\" />" +
" <meta name=\"_csrf\" content=\"fooBarBazQux\" />\n", "<meta name=\"_csrf\" content=\"fooBarBazQux\" />",
value); value);
} }
} }