servlet-integrations-jsp-taglibs.md 9.3 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
# JSP Tag Libraries

## Declaring the Taglib

To use any of the tags, you must have the security taglib declared in your JSP:

```
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
```

## The authorize Tag

This tag is used to determine whether its contents should be evaluated or not.
In Spring Security 3.0, it can be used in two ways <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup>.
The first approach uses a [web-security expression](../authorization/expression-based.html#el-access-web), specified in the `access` attribute of the tag.
The expression evaluation will be delegated to the `SecurityExpressionHandler<FilterInvocation>` defined in the application context (you should have web expressions enabled in your `<http>` namespace configuration to make sure this service is available).
So, for example, you might have

```
<sec:authorize access="hasRole('supervisor')">

This content will only be visible to users who have the "supervisor" authority in their list of <tt>GrantedAuthority</tt>s.

</sec:authorize>
```

When used in conjunction with Spring Security’s PermissionEvaluator, the tag can also be used to check permissions.
For example:

```
<sec:authorize access="hasPermission(#domain,'read') or hasPermission(#domain,'write')">

This content will only be visible to users who have read or write permission to the Object found as a request attribute named "domain".

</sec:authorize>
```

A common requirement is to only show a particular link, if the user is actually allowed to click it.
How can we determine in advance whether something will be allowed? This tag can also operate in an alternative mode which allows you to define a particular URL as an attribute.
If the user is allowed to invoke that URL, then the tag body will be evaluated, otherwise it will be skipped.
So you might have something like

```
<sec:authorize url="/admin">

This content will only be visible to users who are authorized to send requests to the "/admin" URL.

</sec:authorize>
```

To use this tag there must also be an instance of `WebInvocationPrivilegeEvaluator` in your application context.
If you are using the namespace, one will automatically be registered.
This is an instance of `DefaultWebInvocationPrivilegeEvaluator`, which creates a dummy web request for the supplied URL and invokes the security interceptor to see whether the request would succeed or fail.
This allows you to delegate to the access-control setup you defined using `intercept-url` declarations within the `<http>` namespace configuration and saves having to duplicate the information (such as the required roles) within your JSPs.
This approach can also be combined with a `method` attribute, supplying the HTTP method, for a more specific match.

The Boolean result of evaluating the tag (whether it grants or denies access) can be stored in a page context scope variable by setting the `var` attribute to the variable name, avoiding the need for duplicating and re-evaluating the condition at other points in the page.

### Disabling Tag Authorization for Testing

Hiding a link in a page for unauthorized users doesn’t prevent them from accessing the URL.
They could just type it into their browser directly, for example.
As part of your testing process, you may want to reveal the hidden areas in order to check that links really are secured at the back end.
If you set the system property `spring.security.disableUISecurity` to `true`, the `authorize` tag will still run but will not hide its contents.
By default it will also surround the content with `<span class="securityHiddenUI">…​</span>` tags.
This allows you to display "hidden" content with a particular CSS style such as a different background colour.
Try running the "tutorial" sample application with this property enabled, for example.

You can also set the properties `spring.security.securedUIPrefix` and `spring.security.securedUISuffix` if you want to change surrounding text from the default `span` tags (or use empty strings to remove it completely).

## The authentication Tag

This tag allows access to the current `Authentication` object stored in the security context.
It renders a property of the object directly in the JSP.
So, for example, if the `principal` property of the `Authentication` is an instance of Spring Security’s `UserDetails` object, then using `<sec:authentication property="principal.username" />` will render the name of the current user.

Of course, it isn’t necessary to use JSP tags for this kind of thing and some people prefer to keep as little logic as possible in the view.
You can access the `Authentication` object in your MVC controller (by calling `SecurityContextHolder.getContext().getAuthentication()`) and add the data directly to your model for rendering by the view.

## The accesscontrollist Tag

This tag is only valid when used with Spring Security’s ACL module.
It checks a comma-separated list of required permissions for a specified domain object.
If the current user has all of those permissions, then the tag body will be evaluated.
If they don’t, it will be skipped.
An example might be

|   |In general this tag should be considered deprecated.<br/>Instead use the [The authorize Tag](#taglibs-authorize).|
|---|-----------------------------------------------------------------------------------------------------------------|

```
<sec:accesscontrollist hasPermission="1,2" domainObject="${someObject}">

This will be shown if the user has all of the permissions represented by the values "1" or "2" on the given object.

</sec:accesscontrollist>
```

The permissions are passed to the `PermissionFactory` defined in the application context, converting them to ACL `Permission` instances, so they may be any format which is supported by the factory - they don’t have to be integers, they could be strings like `READ` or `WRITE`.
If no `PermissionFactory` is found, an instance of `DefaultPermissionFactory` will be used.
The `AclService` from the application context will be used to load the `Acl` instance for the supplied object.
The `Acl` will be invoked with the required permissions to check if all of them are granted.

This tag also supports the `var` attribute, in the same way as the `authorize` 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.

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.

```
	<form method="post" action="/do/something">
		<sec:csrfInput />
		Name:<br />
		<input type="text" name="name" />
		...
	</form>
```

## The csrfMetaTags Tag

If CSRF protection is enabled, this tag inserts meta tags containing the CSRF protection token form field and header names and CSRF protection token value.
These meta tags are useful for employing CSRF protection within JavaScript in your applications.

You should place `csrfMetaTags` within an HTML `<head></head>` block, where you would normally place other meta tags.
Once you use this tag, you can access the form field name, header name, and token value easily using JavaScript.
JQuery is used in this example to make the task easier.

```
<!DOCTYPE html>
<html>
	<head>
		<title>CSRF Protected JavaScript Page</title>
		<meta name="description" content="This is the description for this page" />
		<sec:csrfMetaTags />
		<script type="text/javascript" language="javascript">

			var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
			var csrfHeader = $("meta[name='_csrf_header']").attr("content");
			var csrfToken = $("meta[name='_csrf']").attr("content");

			// using XMLHttpRequest directly to send an x-www-form-urlencoded request
			var ajax = new XMLHttpRequest();
			ajax.open("POST", "https://www.example.org/do/something", true);
			ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded data");
			ajax.send(csrfParameter + "=" + csrfToken + "&name=John&...");

			// using XMLHttpRequest directly to send a non-x-www-form-urlencoded request
			var ajax = new XMLHttpRequest();
			ajax.open("POST", "https://www.example.org/do/something", true);
			ajax.setRequestHeader(csrfHeader, csrfToken);
			ajax.send("...");

			// using JQuery to send an x-www-form-urlencoded request
			var data = {};
			data[csrfParameter] = csrfToken;
			data["name"] = "John";
			...
			$.ajax({
				url: "https://www.example.org/do/something",
				type: "POST",
				data: data,
				...
			});

			// using JQuery to send a non-x-www-form-urlencoded request
			var headers = {};
			headers[csrfHeader] = csrfToken;
			$.ajax({
				url: "https://www.example.org/do/something",
				type: "POST",
				headers: headers,
				...
			});

		<script>
	</head>
	<body>
		...
	</body>
</html>
```

If CSRF protection is not enabled, `csrfMetaTags` outputs nothing.

---

[1](#_footnoteref_1). The legacy options from Spring Security 2.0 are also supported, but discouraged.

[Spring’s CORS Support](cors.html)[Java Configuration](../configuration/java.html)