对于最新的稳定版本,请使用 Spring Security 6.4.1! |
JSP 标记库
声明 Taglib
要使用任何标记,必须在 JSP 中声明安全 taglib:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
authorize 标签
此标签用于确定是否应评估其内容。
在 Spring Security 3.0 中,可以通过两种方式使用它[1].
第一种方法使用在 tag 的属性中指定的 web-security 表达式。
表达式评估将委托给应用程序上下文中定义的 (您应该在命名空间配置中启用 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 的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,则将评估标记正文,否则将跳过该 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
通过将属性设置为变量名称,可以将评估标记的布尔结果(无论它授予还是拒绝访问)存储在页面上下文范围变量中,从而避免在页面中的其他点复制和重新评估条件。var
禁用 Tag 授权以进行测试
在页面中为未经授权的用户隐藏链接并不会阻止他们访问 URL。
例如,他们可以直接在浏览器中输入它。
作为测试过程的一部分,您可能希望显示隐藏区域,以检查链接在后端是否确实受到保护。
如果将 system 属性设置为 ,则标记仍将运行,但不会隐藏其内容。
默认情况下,它还会用标签将内容括起来。
这允许您使用特定的 CSS 样式(例如不同的背景颜色)显示“隐藏”内容。
例如,尝试在启用此属性的情况下运行 “tutorial” 示例应用程序。spring.security.disableUISecurity
true
authorize
<span class="securityHiddenUI">…</span>
您还可以设置属性,以及是否要更改默认标签的周围文本(或使用空字符串将其完全删除)。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 轻松访问表单字段名称、标题名称和令牌值。
在此示例中使用 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