JSP Tag Libraries
Declaring the Taglib
要使用任何这些标签,您必须在您的 JSP 中声明 security 标记库:
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
此标签用于确定是否应计算其内容。在 Spring Security 3.0 中,它可以按照两种方式使用。
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.
Spring Security 2.0 中的旧有选项也受支持,但建议不要使用。 The legacy options from Spring Security 2.0 are also supported, but discouraged. |
第一种方法使用 web-security expression,这是在标签的 access`属性中指定的。表达式求值委托给应用程序上下文中定义的 `SecurityExpressionHandler<FilterInvocation>
(您应该在 `<http>`名称空间配置中启用 Web 表达式,以确保此服务可用)。因此,例如,您可能拥有:
The first approach uses a web-security expression, which is specified in the access
attribute of the tag.
The expression evaluation is 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>
当与 Spring Security 的 PermissionEvaluator
结合使用时,该标签还可用于检查权限:
When used in conjunction with Spring Security’s PermissionEvaluator
, the tag can also be used to check permissions:
<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 show only a particular link, assuming the user is actually allowed to click it. How can we determine in advance whether something is allowed? This tag can also operate in an alternative mode that lets you define a particular URL as an attribute. If the user is allowed to invoke that URL, the tag body is evaluated. Otherwise, it is 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>
要使用此标签,您还必须在您的应用程序上下文中拥有 WebInvocationPrivilegeEvaluator
的实例。如果您正在使用命名空间,则会自动注册一个。这是 DefaultWebInvocationPrivilegeEvaluator
的一个实例,它为提供的网址创建虚拟 Web 请求,并调用安全拦截器来查看请求是否会成功或失败。这允许您委托给您通过使用 <http>
命名空间配置中的 intercept-url
声明定义的访问控制设置,并且不必在 JSP 中重复信息(如必需的角色)。您还可以将此方法与 method
属性(提供 HTTP 方法,如 POST
)结合使用,以进行更具体的匹配。
To use this tag, you must also have an instance of WebInvocationPrivilegeEvaluator
in your application context.
If you are using the namespace, one is automatically 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 lets you delegate to the access-control setup you defined by using intercept-url
declarations within the <http>
namespace configuration and saves having to duplicate the information (such as the required roles) within your JSPs.
You can also combine this approach with a method
attribute (supplying the HTTP method, such as POST
) for a more specific match.
您可以通过将 var
属性设置为变量名称,将计算标签的布尔结果(无论是授权访问还是拒绝访问)存储在页面上下文范围变量中,从而避免在页面的其他位置重复和重新计算条件的需要。
You can store the Boolean result of evaluating the tag (whether it grants or denies access) 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
为未经授权的用户隐藏页面中的链接并不能阻止他们访问该网址。例如,他们可以将其直接键入浏览器。作为测试过程的一部分,您可能希望显示隐藏区域,以检查链接是否确实已在后端得到保护。如果您将 spring.security.disableUISecurity
系统属性设置为 true
,则 authorize
标签仍然会运行,但不会隐藏其内容。默认情况下,它还会用 <span class="securityHiddenUI">…</span>
标签将内容包围起来。这使您能够以特定的 CSS 样式(如不同的背景色)显示 “hidden” 内容。例如,尝试运行 “tutorial” 示例应用程序,并启用此属性。
Hiding a link in a page for unauthorized users does not 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, to check that links really are secured at the back end.
If you set the spring.security.disableUISecurity
system property to true
, the authorize
tag still runs but does not hide its contents.
By default, it also surrounds the content with <span class="securityHiddenUI">…</span>
tags.
This lets you to display “hidden” content with a particular CSS style, such as a different background color.
Try running the “tutorial” sample application, for example, with this property enabled.
如果您想更改默认 span
标签中的环绕文本(或使用空字符串将其完全删除),您还可以设置 spring.security.securedUIPrefix
和 spring.security.securedUISuffix
属性。
You can also set the spring.security.securedUIPrefix
and spring.security.securedUISuffix
properties if you want to change surrounding text from the default span
tags (or use empty strings to remove it completely).
The authentication Tag
此标签允许访问存储在安全上下文中中的当前 Authentication
对象。它直接在 JSP 中呈现该对象的属性。因此,例如,如果 Authentication
的 principal
属性是 Spring Security 的 UserDetails
对象的一个实例,那么使用 <sec:authentication property="principal.username" />
将显示当前用户的名称。
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" />
renders the name of the current user.
当然,对于这类操作,没有必要使用 JSP 标签,并且有些人更希望在视图中尽可能少地包含逻辑。您可以在 MVC 控制器中访问 Authentication
对象(通过调用 SecurityContextHolder.getContext().getAuthentication()
),并将数据直接添加到模型中以供视图呈现。
Of course, it is not 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
本标签仅在与 Spring Security 的 ACL 模块配合使用时才有效。它会检查指定域对象所需权限的逗号分隔列表。如果当前用户拥有所有这些权限,则评估标签正文。如果他们没有权限,则跳过标签正文。
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, the tag body is evaluated. If they do not, it is skipped.
总的来说,此标签应被视为已弃用。改用 The authorize Tag。
In general, this tag should be considered deprecated. Instead, use the The authorize Tag.
下面的清单显示了一个示例:
The following listing shows an example:
<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>
权限会传递给在应用程序上下文中定义的 PermissionFactory
,将其转换成 ACL Permission
实例,以便可以采用工厂支持的任何格式。它们不必是整数。它们可以是字符串,如 READ
或 WRITE
。如果没有找到 PermissionFactory
,则使用 DefaultPermissionFactory
实例。应用程序上下文的 AclService
用于加载所提供对象的 Acl
实例。使用 Acl
通过加载所需权限来检查是否全部授予了这些权限。
The permissions are passed to the PermissionFactory
defined in the application context, converting them to ACL Permission
instances, so they may be any format that is supported by the factory. They do not have to be integers. They could be strings such as READ
or WRITE
.
If no PermissionFactory
is found, an instance of DefaultPermissionFactory
is used.
The AclService
from the application context is used to load the Acl
instance for the supplied object.
The Acl
is invoked with the required permissions to check if all of them are granted.
此标签还支持 var
属性,与 authorize
标签的方式相同。
This tag also supports the var
attribute, in the same way as the authorize
tag.
The csrfInput Tag
如果启用了 CSRF 保护,此标签会使用正确的名称和值插入隐藏的表单字段以进行 CSRF 保护令牌。如果 CSRF 保护未启用,此标签不输出任何内容。
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.
通常情况下,Spring Security 会自动插入用于任何 <form:form>
标签的 CSRF 表单字段,但如果您由于某种原因无法使用 <form:form>
,csrfInput
是一个方便的替换项。
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.
您应该将此标签放置在 HTML <form></form>
块内,通常放置其他输入字段的位置。不要将此标签放在 Spring <form:form></form:form>
块内。Spring Security 会自动处理 Spring 表单。以下清单显示了一个示例:
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.
The following listing shows an example:
<form method="post" action="/do/something">
<sec:csrfInput />
Name:<br />
<input type="text" name="name" />
...
</form>
The csrfMetaTags Tag
如果启用了 CSRF 保护,此标签会插入包含 CSRF 保护令牌表单字段和标头名称,以及 CSRF 保护令牌值的元标签。这些元标签适用于在您应用程序的 JavaScript 中使用 CSRF 保护。
If CSRF protection is enabled, this tag inserts meta tags that contain 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.
您应该将 csrfMetaTags
放置在 HTML <head></head>
块内,通常放置其他元标签的位置。一旦使用此标签,您便可以使用 JavaScript 访问表单字段名称、标头名称和令牌值。该示例使用了 JQuery 来简化任务。以下清单显示了一个示例:
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 by using JavaScript.
JQuery is used in this example to make the task easier.
The following listing shows an example:
<!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>
如果未启用 CSRF 保护,csrfMetaTags
不输出任何内容。
If CSRF protection is not enabled, csrfMetaTags
outputs nothing.