对于最新的稳定版本,请使用 Spring Security 6.4.1! |
JSP 标记库
声明 Taglib
要使用任何标记,必须在 JSP 中声明安全 taglib:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
authorize 标签
此标签用于确定是否应评估其内容。 在 Spring Security 3.0 中,可以通过两种方式使用它。
Spring Security 2.0 中的遗留选项也受支持,但不鼓励使用。 |
第一种方法使用 web-security 表达式,该表达式在 tag 的属性中指定。
表达式评估被委托给应用程序上下文中定义的 (您应该在命名空间配置中启用 Web 表达式以确保此服务可用)。
因此,例如,您可能有:access
SecurityExpressionHandler<FilterInvocation>
<http>
<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 的 tag 结合使用时,该标签还可用于检查权限:PermissionEvaluator
<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>
一个常见的要求是仅显示特定链接,假设实际上允许用户单击它。 我们如何提前确定某些事情是否被允许?此标记还可以在替代模式下运行,该模式允许您将特定 URL 定义为属性。 如果允许用户调用该 URL,则会评估标记正文。否则,将跳过该选项。 所以你可能有这样的情况:
<sec:authorize url="/admin">
This content will only be visible to users who are authorized to send requests to the "/admin" URL.
</sec:authorize>
要使用此标签,您还必须在应用程序上下文中有一个 的实例。
如果您使用的是命名空间,则会自动注册一个命名空间。
这是 的一个实例,它为提供的 URL 创建一个虚拟 Web 请求,并调用安全侦听器来查看请求是成功还是失败。
这样,您就可以委托使用名称空间配置中的声明定义的访问控制设置,并且无需在 JSP 中复制信息(例如所需的角色)。
您还可以将此方法与属性(提供 HTTP 方法,例如 )结合使用,以实现更具体的匹配。WebInvocationPrivilegeEvaluator
DefaultWebInvocationPrivilegeEvaluator
intercept-url
<http>
method
POST
通过将属性设置为变量名称,可以将评估标记的布尔结果(无论它授予还是拒绝访问权限)存储在页面上下文范围变量中,从而避免在页面中的其他点复制和重新评估条件。var
禁用 Tag 授权以进行测试
在页面中为未经授权的用户隐藏链接不会阻止他们访问 URL。
例如,他们可以直接在浏览器中输入它。
作为测试过程的一部分,您可能希望显示隐藏区域,以检查链接在后端是否确实受到保护。
如果将 system 属性设置为 ,则标记仍会运行,但不会隐藏其内容。
默认情况下,它还用标记将内容括起来。
这样,您就可以使用特定的 CSS 样式(如不同的背景色)显示“隐藏”内容。
例如,尝试运行“tutorial”示例应用程序,并启用此属性。spring.security.disableUISecurity
true
authorize
<span class="securityHiddenUI">…</span>
如果要更改 default 标签的周围文本(或使用空字符串将其完全删除),您还可以设置 and 属性。spring.security.securedUIPrefix
spring.security.securedUISuffix
span
authentication 标签
此标记允许访问存储在安全上下文中的当前对象。
它直接在 JSP 中呈现对象的属性。
因此,例如,如果 the property 的 is 是 Spring Security 对象的实例,则 using 将呈现当前用户的名称。Authentication
principal
Authentication
UserDetails
<sec:authentication property="principal.username" />
当然,这种事情没有必要使用 JSP 标记,有些人喜欢在视图中保留尽可能少的逻辑。
您可以访问 MVC 控制器中的对象(通过调用 ),并将数据直接添加到模型中,以便视图进行渲染。Authentication
SecurityContextHolder.getContext().getAuthentication()
accesscontrollist 标签
此标签仅在与 Spring Security 的 ACL 模块一起使用时有效。 它检查指定域对象所需权限的逗号分隔列表。 如果当前用户具有所有这些权限,则会评估标记正文。 如果没有,则跳过它。
通常,此标记应被视为已弃用。 请改用 The 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>
权限被传递给应用程序上下文中定义的,将它们转换为 ACL 实例,因此它们可以是工厂支持的任何格式。它们不必是整数。它们可以是字符串,例如 或 。
如果未找到,则使用 的实例。
from the application context 用于加载所提供对象的实例。
使用所需的权限调用 ,以检查是否授予了所有权限。PermissionFactory
Permission
READ
WRITE
PermissionFactory
DefaultPermissionFactory
AclService
Acl
Acl
此 tag 也支持 the attribute,其方式与 tag 相同。var
authorize
csrfInput 标记
如果启用了 CSRF 保护,则此标记会插入一个隐藏的表单字段,该字段具有 CSRF 保护令牌的正确名称和值。 如果未启用 CSRF 保护,则此标签不会输出任何内容。
通常, Spring Security 会自动为您使用的任何标签插入 CSRF 表单字段,但是如果由于某种原因您无法使用,则是一个方便的替代。<form:form>
<form:form>
csrfInput
您应该将此标签放在 HTML 块中,您通常会在其中放置其他输入字段。
不要将此标签放在 Spring 块中。
Spring Security 会自动处理 Spring 表单。
下面的清单显示了一个示例:<form></form>
<form:form></form:form>
<form method="post" action="/do/something">
<sec:csrfInput />
Name:<br />
<input type="text" name="name" />
...
</form>
csrfMetaTags 标签
如果启用了 CSRF 保护,则此标签将插入包含 CSRF 保护令牌表单字段和标头名称以及 CSRF 保护令牌值的 meta 标签。 这些 meta 标记对于在应用程序中的 JavaScript 中使用 CSRF 保护很有用。
您应该放置在 HTML 块中,您通常会在其中放置其他 meta 标记。
使用此标签后,您可以通过 JavaScript 访问表单字段名称、标头名称和 Token 值。
在此示例中使用 JQuery 来简化任务。
下面的清单显示了一个示例:csrfMetaTags
<head></head>
<!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