626.11524978.js 13.0 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1
(window.webpackJsonp=window.webpackJsonp||[]).push([[626],{1057:function(t,e,a){"use strict";a.r(e);var r=a(56),s=Object(r.a)({},(function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"jsp标记库"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#jsp标记库"}},[t._v("#")]),t._v(" JSP标记库")]),t._v(" "),a("h2",{attrs:{id:"宣布taglib"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#宣布taglib"}},[t._v("#")]),t._v(" 宣布Taglib")]),t._v(" "),a("p",[t._v("要使用任何标记,你必须在JSP中声明安全性taglib:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>\n')])])]),a("h2",{attrs:{id:"授权标签"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#授权标签"}},[t._v("#")]),t._v(" 授权标签")]),t._v(" "),a("p",[t._v("此标记用于确定是否应该对其内容进行评估。在 Spring Security3.0中,可以用两种方式"),a("sup",{staticClass:"footnote"},[t._v("["),a("a",{staticClass:"footnote",attrs:{id:"_footnoteref_1",href:"#_footnotedef_1",title:"View footnote."}},[t._v("1")]),t._v("]")]),t._v("。第一种方法使用"),a("RouterLink",{attrs:{to:"/authorization/expression-based.html#el-access-web"}},[t._v("Web安全表达式")]),t._v(",在标记的"),a("code",[t._v("access")]),t._v("属性中指定。表达式求值将委托给在应用程序上下文中定义的"),a("code",[t._v("SecurityExpressionHandler<FilterInvocation>")]),t._v("(你应该在"),a("code",[t._v("<http>")]),t._v("名称空间配置中启用Web表达式,以确保此服务可用)。所以,举个例子,你可能")],1),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('<sec:authorize access="hasRole(\'supervisor\')">\n\nThis content will only be visible to users who have the "supervisor" authority in their list of <tt>GrantedAuthority</tt>s.\n\n</sec:authorize>\n')])])]),a("p",[t._v("当与 Spring Security的PermissionEvaluator结合使用时,该标记还可以用于检查权限。例如:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("<sec:authorize access=\"hasPermission(#domain,'read') or hasPermission(#domain,'write')\">\n\nThis content will only be visible to users who have read or write permission to the Object found as a request attribute named \"domain\".\n\n</sec:authorize>\n")])])]),a("p",[t._v("一个常见的要求是只显示一个特定的链接,如果用户实际上被允许单击它的话。我们怎样才能事先确定某件事是否会被允许?这个标记也可以在另一种模式下操作,这种模式允许你将特定的URL定义为一个属性。如果允许用户调用该URL,则将计算标记主体,否则将跳过该标记主体。所以你可能会有一些类似的东西")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('<sec:authorize url="/admin">\n\nThis content will only be visible to users who are authorized to send requests to the "/admin" URL.\n\n</sec:authorize>\n')])])]),a("p",[t._v("要使用此标记,还必须在应用程序上下文中有"),a("code",[t._v("WebInvocationPrivilegeEvaluator")]),t._v("的实例。如果使用名称空间,将自动注册一个名称空间。这是"),a("code",[t._v("DefaultWebInvocationPrivilegeEvaluator")]),t._v("的一个实例,该实例为提供的URL创建一个虚拟Web请求,并调用安全拦截器查看请求是成功还是失败。这允许你委派到使用"),a("code",[t._v("<http>")]),t._v("命名空间配置中的"),a("code",[t._v("intercept-url")]),t._v("声明定义的访问控制设置,并节省了在JSP中复制信息(例如所需的角色)的时间。这种方法还可以与"),a("code",[t._v("method")]),t._v("属性结合,提供HTTP方法,以进行更具体的匹配。")]),t._v(" "),a("p",[t._v("通过将"),a("code",[t._v("var")]),t._v("属性设置为变量名,可以将计算标记(无论是授予还是拒绝访问)的布尔结果存储在页面上下文范围变量中,从而避免了在页面的其他点重复和重新计算条件的需要。")]),t._v(" "),a("h3",{attrs:{id:"禁用标记授权以进行测试"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#禁用标记授权以进行测试"}},[t._v("#")]),t._v(" 禁用标记授权以进行测试")]),t._v(" "),a("p",[t._v("在页面中为未经授权的用户隐藏链接并不会阻止他们访问该URL。例如,他们可以直接在浏览器中输入。作为测试过程的一部分,你可能想要显示隐藏的区域,以检查链接是否真的在后端得到了保护。如果将系统属性"),a("code",[t._v("spring.security.disableUISecurity")]),t._v("设置为"),a("code",[t._v("true")]),t._v(",则"),a("code",[t._v("authorize")]),t._v("标记仍将运行,但不会隐藏其内容。默认情况下,它还会用"),a("code",[t._v('<span class="securityHiddenUI">…​</span>')]),t._v("标记包围内容。这允许你以特定的CSS样式(例如不同的背景颜色)显示“隐藏”内容。例如,尝试在启用此属性的情况下运行“tutorial”示例应用程序。")]),t._v(" "),a("p",[t._v("如果你想从默认的"),a("code",[t._v("span")]),t._v("标记中更改周围的文本(或使用空字符串完全删除它),还可以设置属性"),a("code",[t._v("spring.security.securedUIPrefix")]),t._v(""),a("code",[t._v("spring.security.securedUISuffix")]),t._v("")]),t._v(" "),a("h2",{attrs:{id:"身份验证标记"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#身份验证标记"}},[t._v("#")]),t._v(" 身份验证标记")]),t._v(" "),a("p",[t._v("此标记允许访问存储在安全上下文中的当前"),a("code",[t._v("Authentication")]),t._v("对象。它在JSP中直接呈现对象的属性。因此,例如,如果"),a("code",[t._v("Authentication")]),t._v(""),a("code",[t._v("principal")]),t._v("属性是 Spring Security的"),a("code",[t._v("UserDetails")]),t._v("对象的实例,那么使用"),a("code",[t._v('<sec:authentication property="principal.username" />')]),t._v("将呈现当前用户的名称。")]),t._v(" "),a("p",[t._v("当然,在这种情况下没有必要使用JSP标记,有些人更喜欢在视图中尽可能少地保留逻辑。你可以访问MVC控制器中的"),a("code",[t._v("Authentication")]),t._v("对象(通过调用"),a("code",[t._v("SecurityContextHolder.getContext().getAuthentication()")]),t._v("),并将数据直接添加到模型中,以便由视图进行呈现。")]),t._v(" "),a("h2",{attrs:{id:"accesscontrolist标签"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#accesscontrolist标签"}},[t._v("#")]),t._v(" AccessControlist标签")]),t._v(" "),a("p",[t._v("此标记仅在与 Spring Security的ACL模块一起使用时有效。它检查指定域对象所需权限的逗号分隔列表。如果当前用户拥有所有这些权限,那么将对标记主体进行评估。如果他们不这么做,就会被跳过。一个例子可能是")]),t._v(" "),a("table",[a("thead",[a("tr",[a("th"),t._v(" "),a("th",[t._v("一般来说,这个标记应该被认为是废弃的。"),a("br"),t._v("而不是使用"),a("a",{attrs:{href:"#taglibs-authorize"}},[t._v("授权标签")]),t._v("")])])]),t._v(" "),a("tbody")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('<sec:accesscontrollist hasPermission="1,2" domainObject="${someObject}">\n\nThis will be shown if the user has all of the permissions represented by the values "1" or "2" on the given object.\n\n</sec:accesscontrollist>\n')])])]),a("p",[t._v("这些权限被传递给在应用程序上下文中定义的"),a("code",[t._v("PermissionFactory")]),t._v(",将它们转换为ACL"),a("code",[t._v("Permission")]),t._v("实例,因此它们可以是工厂支持的任何格式-它们不必是整数,它们可以是"),a("code",[t._v("READ")]),t._v(""),a("code",[t._v("WRITE")]),t._v("之类的字符串。如果没有找到"),a("code",[t._v("PermissionFactory")]),t._v(",将使用"),a("code",[t._v("DefaultPermissionFactory")]),t._v("的实例。应用程序上下文中的"),a("code",[t._v("AclService")]),t._v("将用于为所提供的对象加载"),a("code",[t._v("Acl")]),t._v("实例。将使用所需的权限调用"),a("code",[t._v("Acl")]),t._v(",以检查是否已授予所有权限。")]),t._v(" "),a("p",[t._v("该标记还支持"),a("code",[t._v("var")]),t._v("属性,与"),a("code",[t._v("authorize")]),t._v("标记的方式相同。")]),t._v(" "),a("h2",{attrs:{id:"csrfinput标记"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#csrfinput标记"}},[t._v("#")]),t._v(" csrfinput标记")]),t._v(" "),a("p",[t._v("如果启用了CSRF保护,则此标记将插入一个隐藏的表单字段,其中包含CSRF保护令牌的正确名称和值。如果未启用CSRF保护,则此标记不输出任何内容。")]),t._v(" "),a("p",[t._v("Spring 通常情况下,Security会自动为你使用的任何"),a("code",[t._v("<form:form>")]),t._v("标记插入一个CSRF窗体字段,但是如果由于某种原因你无法使用"),a("code",[t._v("<form:form>")]),t._v(""),a("code",[t._v("csrfInput")]),t._v("是一个方便的替换。")]),t._v(" "),a("p",[t._v("你应该将此标记放置在HTML"),a("code",[t._v("<form></form>")]),t._v("块中,在该块中你通常会放置其他输入字段。不要将此标记放置在 Spring "),a("code",[t._v("<form:form></form:form>")]),t._v("块中。 Spring 安全自动处理 Spring 表单。")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('\t<form method="post" action="/do/something">\n\t\t<sec:csrfInput />\n\t\tName:<br />\n\t\t<input type="text" name="name" />\n\t\t...\n\t</form>\n')])])]),a("h2",{attrs:{id:"csrfmetatags标签"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#csrfmetatags标签"}},[t._v("#")]),t._v(" CSRFmetatags标签")]),t._v(" "),a("p",[t._v("如果启用了CSRF保护,则此标记将插入包含CSRF保护令牌窗体域和头名称以及CSRF保护令牌值的元标记。这些元标记对于在应用程序的JavaScript中使用CSRF保护非常有用。")]),t._v(" "),a("p",[t._v("你应该将"),a("code",[t._v("csrfMetaTags")]),t._v("放在HTML"),a("code",[t._v("<head></head>")]),t._v("块中,在该块中你通常会放置其他元标记。使用此标记后,就可以使用JavaScript轻松地访问表单字段名、标头名和令牌值。本例中使用了jQuery来简化任务。")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v('<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<title>CSRF Protected JavaScript Page</title>\n\t\t<meta name="description" content="This is the description for this page" />\n\t\t<sec:csrfMetaTags />\n\t\t<script type="text/javascript" language="javascript">\n\n\t\t\tvar csrfParameter = $("meta[name=\'_csrf_parameter\']").attr("content");\n\t\t\tvar csrfHeader = $("meta[name=\'_csrf_header\']").attr("content");\n\t\t\tvar csrfToken = $("meta[name=\'_csrf\']").attr("content");\n\n\t\t\t// using XMLHttpRequest directly to send an x-www-form-urlencoded request\n\t\t\tvar ajax = new XMLHttpRequest();\n\t\t\tajax.open("POST", "https://www.example.org/do/something", true);\n\t\t\tajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded data");\n\t\t\tajax.send(csrfParameter + "=" + csrfToken + "&name=John&...");\n\n\t\t\t// using XMLHttpRequest directly to send a non-x-www-form-urlencoded request\n\t\t\tvar ajax = new XMLHttpRequest();\n\t\t\tajax.open("POST", "https://www.example.org/do/something", true);\n\t\t\tajax.setRequestHeader(csrfHeader, csrfToken);\n\t\t\tajax.send("...");\n\n\t\t\t// using JQuery to send an x-www-form-urlencoded request\n\t\t\tvar data = {};\n\t\t\tdata[csrfParameter] = csrfToken;\n\t\t\tdata["name"] = "John";\n\t\t\t...\n\t\t\t$.ajax({\n\t\t\t\turl: "https://www.example.org/do/something",\n\t\t\t\ttype: "POST",\n\t\t\t\tdata: data,\n\t\t\t\t...\n\t\t\t});\n\n\t\t\t// using JQuery to send a non-x-www-form-urlencoded request\n\t\t\tvar headers = {};\n\t\t\theaders[csrfHeader] = csrfToken;\n\t\t\t$.ajax({\n\t\t\t\turl: "https://www.example.org/do/something",\n\t\t\t\ttype: "POST",\n\t\t\t\theaders: headers,\n\t\t\t\t...\n\t\t\t});\n\n\t\t<script>\n\t</head>\n\t<body>\n\t\t...\n\t</body>\n</html>\n')])])]),a("p",[t._v("如果不启用CSRF保护,"),a("code",[t._v("csrfMetaTags")]),t._v("将不输出任何内容。")]),t._v(" "),a("hr"),t._v(" "),a("p",[a("a",{attrs:{href:"#_footnoteref_1"}},[t._v("1")]),t._v("。还支持 Spring Security2.0中的遗留选项,但不推荐。")]),t._v(" "),a("p",[a("RouterLink",{attrs:{to:"/spring-security/cors.html"}},[t._v("Spring’s CORS Support")]),a("RouterLink",{attrs:{to:"/configuration/java.html"}},[t._v("Java Configuration")])],1)])}),[],!1,null,null,null);e.default=s.exports}}]);