servlet规范之安全(代码片段)

顧棟 顧棟     2023-03-24     117

关键词:

Security

文章是对 JSR-000340 JavaTM Servlet 3.1 Final Release的Java™ Servlet规范的翻译,尚未校准

文章目录


Web应用程序是由应用程序开发员创建的,他们将应用程序给予、出售或以其他方式转让给部署者以安装到运行环境中。应用程序开发人员将安全要求传达给部署者和部署系统。这些信息可以通过应用程序的部署描述符以声明的方式传达,也可以通过在应用程序代码中使用注解的方式传达,还可以通过 ServletRegistration接口的 setServletSecurity方法以编程方式传达。

本章描述了Servlet容器的安全机制和接口,以及用于传达应用程序安全要求的部署描述符、注解和编程机制。

简介

一个Web应用程序包含可以被许多用户访问的资源。这些资源经常公布在不受保护的开放网络,如互联网。在这样的环境中,大量的网络Web应用程序会有安全要求。

尽管质量保证和实施细节可能有所不同,但servlet容器有满足这些要求的机制和基础设施,它们有以下一些共同的特点。

  • Authentication(身份认证):通信实体向对方证明他们是代表被授权访问的特定身份行事的方法。
  • Access control for resources(资源访问控制):为了执行的完整性、保密性或可用性约束,将与资源的互动限制在用户或程序的集合中。
  • Data Integrity(数据的完整性):用来证明信息在传输过程中没有被第三方修改的手段。
  • Confidentiality or Data Privacy(保密性或数据隐私):用来确保信息只提供给被授权访问的用户的手段。

声明式安全

声明式安全指的是以应用程序的外部形式表达应用程序的安全模型或要求的方法,包括角色、访问控制和认证要求。部署描述符是Web应用程序中声明式安全的主要工具。

部署者将应用程序的逻辑安全要求映射到运行时环境特定的安全策略的表示上。在运行时,Servlet容器使用安全策略表示来执行认证和授权。

安全模型适用于Web应用程序的静态内容部分,以及应用程序中由客户端请求的Servlet和过滤器。不适用于当servlet使用RequestDispatcher调用静态资源或使用forwardinclude的servlet的场景。

编程式安全

当仅仅声明式安全是不足以表达应用的安全模型时,编程式安全被用于意识到安全的应用。编程式安全包括以下HttpServletRequest接口的方法:

  • authenticate
  • login
  • logout
  • getRemoteUser
  • isUserInRole
  • getUserPrincipal

login方法允许应用程序执行用户名和密码收集(作为基于表单的登录的替代)。

authenticate方法允许应用程序从无限制的请求上下文中启动容器对请求调用者的认证。

logout方法允许应用程序重置请求的调用者身份。

getRemoteUser方法返回容器与请求相关的远程用户(也就是调用者)的名字。

isUserInRole方法确定与请求相关的远程用户(也就是调用者)是否处于指定的安全角色。

getUserPrincipal方法确定远程用户(即调用者)的本名,并返回一个与远程用户对应的java.security.Principal对象。在getUserPrincipal返回的Principal上调用getName方法,会返回远程用户的名字。这些API允许servlets根据获得的信息做出业务逻辑决策。

如果没有用户被认证,getRemoteUser方法返回nullisUserInRole方法总是返回false,而getUserPrincipal方法返回null

isUserInRole方法需要一个 "String "参数,引用一个应用程序的角色。对于调用isUserInRole时使用的每个不同的角色引用,应在部署描述符中声明一个安全-角色-ref元素,其角色名称与该角色引用相对应。每个 security-role-ref 都应该包含一个 role-link 子元素,其值是应用程序嵌入式角色引用所链接的应用程序安全角色的名称。容器使用角色名称等于角色引用的 security-roleref 来确定要测试用户的成员身份的安全角色。

例如,将安全角色引用 "FOO "映射到安全角色的名字为 “manager”,其语法为:

<security-role-ref>
	<role-name>FOO</role-name>
	<role-link>manager</role-link>
</security-role-ref>

在这种情况下,如果一个由属于 "manager "安全角色的用户调用的servlet调用isUserInRole("FOO"),结果将是true。

如果在调用isUserInRole时使用的角色引用没有matching security-role-ref,容器必须默认测试用户是否属于role-name等于调用中使用的角色引用的安全角色。

角色名称 "*"决不能作为调用 isUserInRole 的参数。任何带有 "*"的对 isUserInRole的调用必须返回错误。如果要测试的安全角色的角色名是 “**”,并且应用程序没有声明具有角色名 "**"的应用程序安全角色,isUserInRole必须只在用户已被验证时返回 true;也就是说,只有当 getRemoteUsergetUserPrincipal都将返回一个非空的值时。否则,容器必须检查用户是否是应用角色的成员。

security-role-ref元素的声明告知部署者应用程序所使用的角色参考,以及必须为其定义映射。

编程式安全策略配置

本节定义了为配置Servlet容器强制执行的安全约束而提供的注释和apis。

@ServletSecurity注解

@ServletSecurity注解为定义访问控制约束提供了一种替代机制,相当于那些可以通过便携式部署描述符中的security-constraint元素或通过ServletRegistration接口的setServletSecurity方法以编程方式表示。Servlet容器必须支持对实现javax.servlet.Servlet接口的类(及其子类)使用@ServletSecurity注解。

package javax.servlet.annotation;

@Inherited
@Documented
@Target(value=TYPE)
@Retention(value=RUNTIME)
public @interface ServletSecurity 
	HttpConstraint value();
	HttpMethodConstraint[] httpMethodConstraints();

TABLE 13-1 The ServletSecurity Interface

ElementDescriptionDefault
valueHttpConstraint定义了应用于所有HTTP方法的保护,这些方法不在httpMethodConstraints所返回的数组中。@HttpConstraint
httpMethodConstrainHTTP方法特定的约束数组

@HttpConstraint

@HttpConstraint注解是在@ServletSecurity注解中使用的,用来表示适用于所有HTTP协议方法的安全约束,这些方法的相应@HttpMethodConstraint并没有出现在@ServletSecurity注解中。

对于特殊情况,即返回所有默认值的@HttpConstraint与至少一个返回所有默认值以外的@HttpMethodConstraint相结合,@HttpConstraint表示没有安全约束将被应用到任何HTTP协议方法上,否则安全约束将被应用。这个例外是为了确保对@HttpConstraint的这种潜在的非特定使用不会产生约束,这些约束将为这些方法明确地建立不受保护的访问;因为它们不会被约束所覆盖。

package javax.servlet.annotation;

@Documented
@Retention(value=RUNTIME)
public @interface HttpConstraint 
	ServletSecurity.EmptyRoleSemantic value();
	java.lang.String[] rolesAllowed();
	ServletSecurity.TransportGuarantee transportGuarantee();

TABLE 13-2 The HttpConstraint Interface

ElementDescriptionDefault
value默认的授权语义,适用于(仅)当roleAllowed返回一个空的数组。PERMIT
rolesAllowedAn array containing the names of the authorized roles一个包含授权角色名称的数组
transportGuarantee在连接的请求到达时必须满足的数据保护需求。NONE

@HttpMethodConstraint

@HttpMethodConstraint注解被用于@ServletSecurity注解中,以表示对特定HTTP协议消息的安全约束。

package javax.servlet.annotation;
@Documented
@Retention(value=RUNTIME)
public @interface HttpMethodConstraint 
	ServletSecurity.EmptyRoleSemantic value();
	java.lang.String[] rolesAllowed();
	ServletSecurity.TransportGuarantee transportGuarantee();

TABLE 13-3 The HttpMethodConstraint Interface

ElementDescriptionDefault
valueHTTP协议的方法名称
emptyRoleSemanticThe default authorization semantic that applies (only) when rolesAllowed returns an empty array.默认的授权语义,适用于(仅)当roleAllowed返回一个空数组时。PERMIT
rolesAllowedAn array containing the names of the authorized roles 一个包含授权角色名称的数组
transportGuarantee在连接的请求到达时必须满足的数据保护需求。NONE

@ServletSecurity注解可以在Servlet实现类上指定(即针对),其值由子类根据为@Inherited元注解定义的规则继承。在一个Servlet实现类中最多可以出现一个@ServletSecurity注解的实例,而且@ServletSecurity注解一定不能被指定在(即针对)一个Java方法上。

当一个或多个@HttpMethodConstraint注解被定义在一个@ServletSecurity注解中时,每个@HttpMethodConstraint定义了适用于@HttpMethodConstraint中确定的HTTP协议方法的security-constraint。除了它的@HttpConstraint返回所有默认值的情况,以及它至少包含一个@HttpMethodConstraint返回所有默认值以外的情况,@ServletSecurity注解定义了另一个 security-constraint,适用于所有HTTP协议方法,这些方法的相应@HttpMethodConstraint还没有被定义。

在便携式部署描述符中定义的 security-constraint元素对于约束中出现的所有 url-patterns都是权威的。

当便携式部署描述符中的security-constraint包括一个url-pattern,它与映射到@ServletSecurity注释的类的模式完全匹配,该注释必须对Servlet容器对该模式执行的约束没有影响。

metadata-complete=true 被定义为便携式部署描述符时,@ServletSecurity注解不适用于部署描述符中映射到(任何Servlet映射到)被注解类的任何 url-patterns

@ServletSecurity注解不适用于使用ServletContext接口的addServlet(String, Servlet)方法创建的ServletRegistrationurl-patterns,除非该Servlet是由ServletContext接口的createServlet方法构建。

除了上面列出的例外情况,当一个Servlet类被注解为@ServletSecurity时,该注解定义了适用于所有映射到该类的Servlet的url-patterns的安全约束。

当一个类没有被注解为@ServletSecurity时,应用于从该类映射出来的Servlet的访问策略是由相应的可移植部署描述符中适用的 "security-constraint "元素(如果有的话)建立的,如果没有这些元素,则由通过 ServletRegistration接口的 setServletSecurity方法为目标Servlet以编程方式建立的约束(如果有的话)建立。

Examples

下面的例子演示了ServletSecurity注释的用法。

CODE EXAMPLE 13-1 对于所有的HTTP方法,没有约束

@ServletSecurity
public class Example1 extends HttpServlet 

CODE EXAMPLE 13-2 适用于所有的HTTP方法,没有授权限制,需要保密传输

@ServletSecurity(@HttpConstraint(transportGuarantee = TransportGuarantee.CONFIDENTIAL))
public class Example2 extends HttpServlet 

CODE EXAMPLE 13-3 对于所有的HTTP方法,所有的访问被拒绝

@ServletSecurity(@HttpConstraint(EmptyRoleSemantic.DENY))
public class Example3 extends HttpServlet 

CODE EXAMPLE 13-4 对于所有的HTTP方法,auth-constraint要求是R1角色的成员。

@ServletSecurity(@HttpConstraint(rolesAllowed = "R1"))
public class Example4 extends HttpServlet 

CODE EXAMPLE 13-5 对于除GET和POST以外的所有HTTP方法,没有任何限制;对于GET和POST方法,需要加入R1角色的授权限制;对于POST,需要保密传输。

@ServletSecurity((httpMethodConstraints = 
@HttpMethodConstraint(value = "GET", rolesAllowed = "R1"),
@HttpMethodConstraint(value = "POST", rolesAllowed = "R1", transportGuarantee = TransportGuarantee.CONFIDENTIAL)
)
public class Example5 extends HttpServlet 

CODE EXAMPLE 13-6 对于所有的HTTP方法,除了GET auth-constraint要求加入R1角色;对于GET,没有任何约束。

@ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"),
                 httpMethodConstraints = @HttpMethodConstraint("GET"))
public class Example6 extends HttpServlet 

CODE EXAMPLE 13-7 对于除TRACE以外的所有HTTP方法,要求加入R1角色的auth-constraint;对于TRACE,拒绝所有访问。

@ServletSecurity(value = @HttpConstraint(rolesAllowed = "R1"),
                 httpMethodConstraints = @HttpMethodConstraint(value="TRACE",emptyRoleSemantic = EmptyRoleSemantic.DENY))
public class Example7 extends HttpServlet 

@ServletSecurity与security-constraint的映射

这一节描述了"@ServletSecurity"注解与它作为 "security-constraint "元素的等同表示的映射。它是为了方便使用容器现有的 “security-constraint"执行机制来执行。Servlet 容器对”@ServletSecurity"注解的执行必须与容器对本节中定义的映射所产生的 "security-constraint"元素的执行效果相当。

@ServletSecurity注解被用来定义一个独立于方法的@HttpConstraint,后面是一个零个或多个@HttpMethodConstraint规范的列表。这个独立于方法的约束被应用于所有没有定义HTTP方法特定约束的HTTP方法。

当没有包含@HttpMethodConstraint元素时,@ServletSecurity注解对应于一个包含web-resource-collection的单一security-constraint元素,该元素不包含http-method元素,因此与所有HTTP方法有关。

下面的例子描述了一个没有包含@HttpMethodConstraint注解的@ServletSecurity注解作为一个单一的security-constraint元素的表示。由相应的Servlet(注册)定义的url-pattern元素将包括在web-resource-collection中,任何包含的auth-constraintuser-data-constraint元素的存在和价值将由13.4.1.3节 "Mapping @HttpConstraint and @HttpMethodConstraint to XML."中定义的@HttpConstraint值来决定。

CODE EXAMPLE 13-8 mapping @ServletSecurity with no contained @HttpMethodConstraint

@ServletSecurity(@HttpConstraint(rolesAllowed = "Role1"))

<security-constraint>
	<web-resource-collection>
	<url-pattern>...</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<role-name>Role1</role-name>
	</auth-constraint>
</security-constraint>

当指定了一个或多个@HttpMethodConstraint元素时,独立于方法的约束对应于一个单一的security-constraint,包含一个web-resource-collection,其中包含http-method-omission,用于每个在@HttpMethodConstraint元素中命名的HTTP方法。如果独立于方法的约束返回所有的缺省值,并且至少有一个@HttpMethodConstraint不返回缺省值,那么必须不创建包含http-method-omission元素的security-constraint。每个@HttpMethodConstraint都对应于另一个security-constraint,它包含一个web-resource-collection,其中有一个http-method元素命名了相应的HTTP方法。

下面的例子描述了一个"@ServletSecurity"注解与一个包含的"@HttpMethodConstraint"到两个安全约束元素的映射。由相应的Servlet(注册)定义的url-pattern元素将包括在两个约束的web-resource-collection中,任何包含的auth-constraintuser-data-constraint元素的存在和价值将由相关的@HttpConstraint@HttpMethodConstraint值的映射决定,如第13.4.1.3节 "Mapping @HttpConstraint and @HttpMethodConstraint to XML."中所定义的。

CODE EXAMPLE 13-9 将@ServletSecurity与包含的@HttpMethodConstraint进行映射

@ServletSecurity(value=@HttpConstraint(rolesAllowed = "Role1"),
                 httpMethodConstraints = @HttpMethodConstraint(value = "TRACE",emptyRoleSemantic = EmptyRoleSemantic.DENY))
<security-constraint>
	<web-resource-collection>
		<url-pattern>...</url-pattern>
		<http-method-omission>TRACE</http-method-omission>
	</web-resource-collection>
	<auth-constraint>
		<role-name>Role1</role-name>
	</auth-constraint>
</security-constraint>
<security-constraint>
	<web-resource-collection>
		<url-pattern>...</url-pattern>
		<http-method>TRACE</http-method>
	</web-resource-collection>
	<auth-constraint/>
</security-constraint>

Mapping @HttpConstraint and @HttpMethodConstraint to XML.

本节描述了"@HttpConstraint"和"@HttpMethodConstraint"注解值(定义在"@ServletSecurity"中使用)与相应的 "auth-constraint"和 "user-data-constraint"表示的映射,这些注解共享一个相同的模型,用于表达在可移植部署描述符中使用的 "auth-constraint"和 "user-data-constraint "元素的等值。该模型由以下3个元素组成:

  • emptyRoleSemantic

    授权语义,要么是 “PERMIT”,要么是 “DENY”,在 "rolesAllowed "中没有指定角色时适用。这个元素的默认值是PERMITDENY不支持与非空的rolesAllowed列表相结合。

  • rolesAllowed

    一个包含授权角色名称的列表。当这个列表为空时,其含义取决于emptyRoleSemantic的值。当角色名称 "*"包含在允许的角色列表中时,没有特殊含义。当特殊的角色名称 "**"出现在rolesAllowed中时,它表示用户认证,与角色无关,是需要的,也是足够的。这个元素的默认值是一个空列表。

  • transportGuarantee

    数据保护要求,要么是 “NONE”,要么是 “CONFIDENTIAL”,必须由请求到达的连接来满足。这个元素在意义上等同于一个用户-数据-约束',包含一个传输保证’的相应值。这个元素的默认值是NONE。

下面的例子描述了上面描述的@HttpConstraint模型与web.xml中auth-constraintuser-data-constraint元素之间的对应关系。

CODE EXAMPLE 13-10 emptyRoleSemantic=PERMIT, rolesAllowed=, transportGuarantee=NONE

no constraints

CODE EXAMPLE 13-11 emptyRoleSemantic=PERMIT, rolesAllowed=, transportGuarantee=CONFIDENTIAL

<user-data-constraint>
	<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>

CODE EXAMPLE 13-12 emptyRoleSemantic=PERMIT, rolesAllowed=Role1, transportGuarantee=NONE

<auth-constraint>
<security-role-name>Role1</security-role-name>
</auth-constraint>

CODE EXAMPLE 13-13 emptyRoleSemantic=PERMIT, rolesAllowed=Role1, transportGuarantee=CONFIDENTIAL

<auth-constraint>
	<security-role-name>Role1</security-role-name>
</auth-constraint>
<user-data-constraint>
	<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>

CODE EXAMPLE 13-14 emptyRoleSemantic=DENY, rolesAllowed=, transportGuarantee=NONE

<auth-constraint/>

CODE EXAMPLE 13-15 emptyRoleSemantic=DENY, rolesAllowed=, transportGuarantee=CONFIDENTIAL

<auth-constraint/>
<user-data-constraint>
	<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>

setServletSecurity of ServletRegistration.Dynamic

setServletSecurity方法可以在ServletContextListener中使用,以定义应用于ServletRegistration的映射的安全约束。

Collection<String> setServletSecurity(ServletSecurityElement arg);

setServletSecurityjavax.servlet.ServletSecurityElement参数在结构和模型上类似于@ServletSecurity注释的ServletSecurity接口。因此,第13.4.1.2节 “Mapping @ServletSecurity to security-constraint”(第13-133页)中定义的映射,类似于将含有 "HttpConstraintElement "和 "HttpMethodConstraintElement"值的 "ServletSecurityElement security-constraint 安全约束 "表示。

setServletSecurity方法返回(可能是空的)URL模式的集合,这些URL模式已经是可移植部署描述符中security-constraint元素的确切目标(因此未受调用影响)。

如果获取 ServletRegistrationServletContext已经被初始化,该方法会抛出一个 IllegalStateException

当便携式部署描述符中的 "security-constraint "包括 “url-pattern”,与 "ServletRegistration"映射的模式完全匹配时,对 "ServletRegistration"的 "setServletSecurity"的调用必须对Servlet容器,对该模式实施的约束没有影响。

除了上面列出的例外情况,包括当Servlet类被注解为"@ServletSecurity"时,当 "setServletSecurity"在 "ServletRegistration"上被调用时,它建立了适用于注册的 "url-patterns"的安全限制。

安全角色

安全角色是由应用程序开发人员或汇编人员定义的用户的逻辑分组。当应用程序被部署时,角色由部署者映射到运行时环境中的委托人或组。servlet 容器根据委托人的安全属性,为与传入请求相关的委托人执行声明性或程序性安全。

这可以通过以下两种方式发生。

  1. 部署者将安全角色映射到操作环境中的用户组。从其安全属性中检索调用的委托人所属的用户组。只有当委托人属于被部署者映射为安全角色的用户组时,该委托人才处于安全角色中。
  2. 部署者将安全角色映射到安全策略域中的委托人名称。在这种情况下,调用的委托人的委托人名称将从其安全属性中检索出来。只有当委托人名称与安全角色被映射到的委托人名称相同时,该委托人才处于安全角色中。

Authentication

web客户端可以使用以下机制之一来验证用户对网络服务器的身份。

  • HTTP Basic Authentication HTTP基本认证
  • HTTP Digest Authentication HTTP摘要认证
  • HTTPS Client Authentication HTTPS客户端认证
  • Form Based Authentication 基于表格的认证

HTTP Basic Authentication

基于用户名和密码的HTTP基本认证,是HTTP/1.0规范中定义的认证机制。web服务器请求web客户端对用户进行认证。作为请求的一部分,web服务器传递用户要被认证的领域(一个字符串)。web客户端从用户那里获得用户名和密码,并将它们传送给web服务器。然后web服务器在指定的领域内对用户进行认证。

基本认证不是一个安全的认证协议。用户密码是以简单的base64编码发送的,而且目标服务器没有被认证。额外的保护措施可以缓解其中的一些问题:在一些部署场景中应用了安全的传输机制(HTTPS),或网络层面的安全(如IPSEC协议或VPN策略)。

HTTP Digest Authentication

与HTTP基本认证一样,HTTP摘要认证也是根据用户名和密码来认证用户。然而,与HTTP基本认证不同,HTTP摘要认证并不通过网络发送用户密码。在HTTP摘要认证中,客户端发送密码(和额外数据)的单向加密散列。尽管密码不在线路上发送,但HTTP摘要认证要求认证容器可以获得明文密码等价物,以便它可以通过计算预期的摘要来验证收到的认证器。Servlet容器应该支持HTTP_DIGEST认证。

Form Based Authentication

“login screen"的外观和感觉不能使用网络浏览器的内置认证机制来改变。本规范引入了一个必要的基于表单的认证机制,允许开发者控制登录屏幕的外观和感觉。

web应用程序部署描述符包含登录表格和错误页面的条目。登录表格必须包含用于输入用户名和密码的字段。这些字段必须分别命名为j_usernamej_password

当用户试图访问一个受保护的网络资源时,容器会检查用户的身份验证。如果用户通过了认证并拥有访问该资源的权限,所请求的网络资源就会被激活并返回对它的引用。如果用户没有被认证,就会发生以下所有的步骤。

  1. 用户被要求填写表格,包括用户名和密码字段。
  2. 客户端将表单发回服务器。
  3. 容器试图用表格中的信息来验证用户的身份。
  4. 如果认证失败,则使用转发或重定向返回错误页面,并且响应的状态代码被设置为200。错误页面包含关于失败的信息。
  5. 如果认证成功,客户端将被重定向到使用商店URL路径的资源。
  6. 当重定向和认证的请求到达容器时,容器会恢复请求和HTTP协议方法,并检查认证用户的principal,看它是否处于访问资源的授权角色。
  7. 如果用户被授权,则请求被容器接受以进行处理。

在步骤7中到达的重定向请求的HTTP协议方法可能与触发认证的请求的HTTP方法不同。因此,在步骤6的重定向之后,即使请求到达的HTTP方法不需要认证,表单认证器也必须处理重定向的请求。为了提高被重定向请求的HTTP方法的可预测性,容器应该使用303(SC_SEE_OTHER)状态代码进行重定向(在步骤6中),除非需要与HTTP 1.0用户代理的互操作性;在这种情况下,应该使用302状态代码。

当通过不受保护的传输进行时,基于表单的认证会受到一些与基本认证相同的漏洞的影响。

当触发认证的请求通过安全传输到达时,或登录页面受CONFIDENTIAL的用户数据约束时,登录页面必须返回给用户,并通过安全传输提交给容器。

登录页面应该受到 CONFIDENTIAL 的用户数据约束,而且 CONFIDENTIAL 的用户数据约束应该包含在包含认证要求的每个安全约束中。

HttpServletRequest接口的登录方法为应用程序控制其登录屏幕的外观和感觉提供了一种替代方法。

Login Form Notes

基于表单的登录和基于URL的会话跟踪在实施上可能会有问题。基于表单的登录应该只在会话由cookies或SSL会话信息维护时使用。

为了使认证适当地进行,登录表单的动作必须始终是j_security_check。这个限制是为了使登录表单无论对哪种资源都能工作,并避免要求服务器指定出站表单的动作字段。登录表单应该在密码表单字段上指定autocomplete=”off”

下面是一个例子,显示了该表单应该如何被编码到HTML页面中:

<form method=”POST” action=”j_security_check”>
	<input type=”text” name=”j_username”>
	<input type=”password” name=”j_password” autocomplete=”off”>
</form>

如果基于表单的登录是由于HTTP请求而被调用的,那么原始的请求参数必须被容器保留下来,以便在认证成功后将调用重定向到被请求的资源。

如果用户使用表单登录进行了认证并创建了一个 HTTP 会话,那么该会话的超时或无效会导致用户被注销,即后续请求必须导致用户被重新认证。注销的范围与认证的范围相同:例如,如果容器支持单点登录,如符合Java EE技术的Web容器,用户将需要在Web容器上托管的任何Web应用程序中重新进行认证。

HTTPS Client Authentication

使用HTTPS(HTTP over SSL)的终端用户认证是一种强认证机制。这种机制要求客户端拥有一个公钥证书(PKC)。目前,PKC在电子商务应用中很有用,也可用于浏览器内的单密码。

额外的容器认证机制

Servlet 容器应该提供公共接口,这些接口可用于集成和配置额外的 HTTP 消息层认证机制,以便由容器代表部署的应用程序使用。这些接口应该提供给容器供应商以外的其他各方使用(包括应用程序开发人员、系统管理员和系统集成商)。

为了促进额外的容器认证机制的可移植实施和集成,建议所有的Servlet容器都实施The Java Authentication SPI for Containers(即JSR 196)的Servlet容器配置文件。该SPI可在以下网站下载。http://www.jcp.org/en/jsr/detail?id=196

服务器对认证信息的跟踪

由于在运行时环境中角色被映射到的基础安全身份(如用户和组)是特定于环境的,而不是特定于应用程序的,所以最好是这样。

  1. 使登录机制和策略成为web应用程序部署环境的属性。
  2. 能够使用相同的认证信息来代表部署在同一容器中的所有应用程序的负责人
  3. 只有当安全策略域的边界被跨越时,才要求对用户进行重新认证。

因此,要求servlet容器在容器级别(而不是在Web应用级别)跟踪认证信息。这允许为一个网络应用程序认证的用户访问由容器管理的、允许相同安全身份的其他资源。

指定安全限制条件

安全约束是一种定义网络内容保护的声明性方式。安全约束将授权和或用户数据约束与网络资源的HTTP操作联系起来。安全约束在部署描述符中表示为 “security-constraint”,由以下元素组成。

  • web resource collection (web-resource-collection in deployment descriptor)
  • authorization constraint (auth-constraint in deployment descriptor)
  • user data constraint (user-data-constraint in deployment descriptor)

安全约束所适用的HTTP操作和Web资源(即受约束的请求)由一个或多个Web资源集合确定。一个网络资源集合由以下元素组成。

  • URL patterns (url-pattern in deployment descriptor)
  • HTTP methods (http-method or http-method-omission elements in the deployment descriptor)

一个授权约束建立了一个认证要求,并命名了允许执行受限请求的授权角色。一个用户必须是至少一个指定角色的成员,才能被允许执行受限制的请求。特殊角色名称*是部署描述符中定义的所有角色名称的简写。特殊角色名称**是对任何独立于角色的认证用户的缩写。当特殊角色名称 "**"出现在授权约束中时,它表示任何独立于角色的认证用户都被授权执行受约束的请求。一个没有角色名称的授权约束表示在任何情况下都不允许对受限请求的访问。一个授权约束由以下元素组成。

  • role name (role-name in deployment descriptor).

    用户数据约束确立了一项要求,即受约束的请求必须通过受保护的传输层连接接收。所需保护的强度由传输保证的值来定义。INTEGRAL的传输保证被用来建立内容完整性的要求,CONFIDENTIAL的传输保证被用来建立保密性的要求。
    传输保证 "NONE "表明,当在任何连接(包括不受保护的连接)上收到受限制的请求时,容器必须接受这些请求。容器可以针对INTEGRAL值施加保密的传输保证。一个用户数据约束由以下元素组成

  • transport guarantee (transport-guarantee in deployment descriptor)

    如果没有授权约束适用于一个请求,那么容器必须接受该请求而不要求用户认证。如果没有用户数据约束适用于一个请求,那么当通过任何连接(包括不受保护的连接)收到请求时,容器必须接受该请求。

组合约束

为了组合约束,当一个HTTP方法在一个 "web-resource-collection"中没有被命名,或者该集合在一个包含的 "http-method"元素中特别命名了该HTTP方法,或者该集合包含一个或多个 "http-method-omission"元素,而这些元素都没有命名该HTTP方法时,就可以说该HTTP方法出现在该集合内。

当一个url-pattern和HTTP方法对组合出现在多个安全约束中(即在一个web-resource-collection中),约束(对模式和方法)是通过组合单个约束来定义的。出现相同模式和方法的约束的组合规则如下。

将命名为角色或通过名称 "*"暗示角色的授权约束组合在一起,应产生各个约束中的角色名称的联合,作为允许的角色。命名为 "**"的授权约束应与命名或暗示角色的授权约束相结合,允许任何独立于角色的认证用户。一个不包含授权约束的安全约束应与命名或暗示角色的授权约束相结合,允许未经认证的访问。在特殊情况下,没有命名任何角色的授权约束应与任何其他约束相结合,以覆盖其影响并导致访问被排除。

适用于共同的 "url-pattern"和 "http-method"的 "user-data-constraints"的组合,应产生由各个约束接受的可接受的连接类型的联合。不包含 user-data-constraint的安全约束应与其他user-data-constraint相结合,使未受保护的连接类型成为可接受的连接类型。

Example

下面的例子说明了约束条件的组合及其转化为适用约束条件的表格。假设一个部署描述符包含以下安全约束。

<security-constraint>
	<web-resource-collection>
		<web-resource-name>precluded methods</web-resource-name>
		<url-pattern>/*</url-pattern>

servlet规范之部署描述符(代码片段)

DeploymentDescriptor文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准文章目录DeploymentDescriptor部署描述符元素部署描述符的处理规则部署描述符部署描述符示意图web-app元素descriptionElementdisplay-nameElementiconEl... 查看详情

servlet规范之servlet顶层接口(代码片段)

ServletInterface文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准文章目录ServletInterface请求处理方法HTTP特定的请求处理方法额外方法有条件的GET支持实例数关于单线程模型的注意事项Servlet生命周期加载... 查看详情

servlet规范之servletcontext(代码片段)

ServletContext文章目录ServletContextServletContext接口介绍ServletContext接口的范围初始化参数配置方法以编程方式添加和配置Servlets以编程方式添加和配置Filters以编程方式添加和配置Listeners以编程方式添加的servlet、Filters和Listeners的注释... 查看详情

servlet规范之应用生命周期事件(代码片段)

ApplicationLifecycleEvents文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准文章目录ApplicationLifecycleEvents介绍EventListenersEventTypesandListenerInterfacesAnExampleofListenerUseListenerClassConfiguration提供监听器类部署声明监... 查看详情

servlet规范之requests与servlets映射(代码片段)

MappingRequeststoServlets文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准文章目录MappingRequeststoServletsUseofURLPaths规范映射隐式映射示例映射本章所描述的映射技术是Web容器将客户端请求映射到servlets所需要... 查看详情

springboot之增加一个servlet(代码片段)

...roller基本上可以完成大部分需求,但是我们还可能会用到Servlet、Filter、Listener、Interceptor等等。 当使用Spring-Boot时,嵌入式Servlet容器通过扫描注解的方式注册Servlet、Filter和Servlet规范的所有监听器(如HttpSessionListener监听器)... 查看详情

javaweb核心之servletconfig(代码片段)

2ServletConfig2.1ServletConfig概述2.1.1基本概念它是Servlet的配置参数对象,在Servlet规范中,允许为每个Servlet都提供一些初始化配置。所以,每个Servlet都一个自己的ServletConfig。它的作用是在Servlet初始化期间,把一些配置信息传递给Serv... 查看详情

servlet规范之web应用(代码片段)

WebApplications文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准文章目录WebApplicationsWeb应用服务器中的Web应用与ServletContext的关系Web应用的要素部署层次结构目录结构应用程序目录结构示例Web应用程序归... 查看详情

javaweb核心之页面技术(代码片段)

2页面技术2.1JSP基础2.1.1JSP简介JSP全称是JavaServerPage,它和Servlet一样,也是sun公司推出的一套开发动态web资源的技术,称为JSP/Servlet规范。JSP的本质其实就是一个Servlet。2.1.2JSP和HTML以及Servlet的适用场景类别适用场景HTML只能开发静... 查看详情

servlet规范之注解与可插拔性(代码片段)

Annotationsandpluggability文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准文章目录Annotationsandpluggability注释和可插拔性@WebServlet@WebFilter@WebInitParam@WebListener@MultipartConfig其他注释/约定Pluggability... 查看详情

02_servlet规范(代码片段)

Servlet规范目录在右下角互联网通信流程图一.Servlet规范介绍:servlet规范来自于JAVAEE规范中的一种作用:1)在Servlet规范中,指定【动态资源文件】开发步骤2)在Servlet规范中,指定Http服务器调用动态资源文件规则3)在... 查看详情

servlet规范之预览

文章是对JSR-000340JavaTMServlet3.1FinalRelease的Java™Servlet规范的翻译,尚未校准Servlet3.1版本文章目录Servlet3.1版本什么是Servlet什么是Servlet容器示例将Servlets与其他技术进行比较与Java平台企业版的关系与JavaServlet规范2.5版兼容处理注... 查看详情

过滤器和拦截器的区别(代码片段)

Spring的拦截器与Servlet的过滤器有相似之处,二者都是AOP编程思想的体现,都可以实现权限的检查,日志记录等  ①使用范围不同: Filter是Servlet规范规定,只能用在web程序中,而拦截器,除了web程序,也可以用于Application,Swing程序中 ... 查看详情

servlet3.0规范注解规范(代码片段)

Servlet3.0规范(一)注解规范一、基本使用在Servlet3.0时支持注解启动,不再需要web.xml配制文件。1.1Servlet3.0注解Servlet3.0常用注解:@WebServlet@WebFilter@WebInitParam@WebListener@WebServlet("/hello")publicclassHelloServertextendsHttpServlet@Overrideprotectedvoid... 查看详情

javaee之javaweb核心之servlet

Servlet简介:Servlet运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。但servlet的实质就是java代码,通过java的API动态的向客户端输出内容servlet规范:包含三个技术点1)s... 查看详情

javaweb核心之servlet

一.servlet简介1.什么是servlet?Servlet运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。但servlet的实质就是java代码,通过java的API 动态的向客户端输出内容。servlet规范... 查看详情

servlet编程专题10之servlet3.0注解

- Servlet3.0规范是JavaEE6.0规范中的子规范。其要求运行环境最低是JDK6.0,Tomcat7.0。而之前学习的是Servlet2.5版本的规范,其是JavaEE5.0规范的子规范。其要求运行环境最低是JDK5.0,Tomcat5.0。- 在Eclipse中使用Serlvet3.0规范,则需要... 查看详情

linux加固安全之密码复杂度(代码片段)

...全要求也随之提升,单纯从单位制度,用户安全意识上来规范,并不能杜绝弱口令,必须从技术上要求用户定时修改复杂的密码,从而提高用户和系统的安全性。密码策略的2个基本一个密码最长使用期限,另一个是密码复杂度... 查看详情