本节包括的所有内容均与源代码无关,但对所创建产品的安全性仍然至关重要。因为本节涉及的问题与源代码没有直接关系,所以我们将它与其他章节分开。
<servlet>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/helloworld*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/servlet*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/mservlet*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>-1</session-timeout>
</session-config>
<session-timeout>
标签为 Web 应用程序中的所有会话定义了默认会话超时间隔。如果缺少 <session-timeout>
标签,则由容器设置默认超时。web.xml
中缺少 Servlet 名称或 Servlet 名称重复是一项错误。每个 Servlet 都应具有唯一名称 (servlet-name
) 和相应映射 (servlet-mapping
)。web.xml
中的以下条目显示了几种错误的 Servlet 定义。
<!-- No <servlet-name> specified: -->
<servlet>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Empty <servlet-name> node: -->
<servlet>
<servlet-name/>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Duplicate <servlet-name> nodes: -->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-name>Servlet</servlet-name>
<servlet-class>com.class.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<login-config>
元素用于配置用户如何对应用程序进行身份验证。缺少身份验证方法意味着应用程序不了解如何应用授权限制,因为任何用户都无法登录。使用 <auth-method>
标签(<login-config>
的子标签)指定身份验证方法。BASIC
、FORM
、DIGEST
和CLIENT_CERT
。BASIC
表示 HTTP 基本身份验证。FORM
表示基于表单的身份验证。DIGEST
与 BASIC 身份验证类似;但是,DIGEST 会对密码进行加密。CLIENT_CERT
要求客户端具备公钥证书并使用 SSL/TLS。
<web-app>
<!-- servlet declarations -->
<servlet>...</servlet>
<!-- servlet mappings-->
<servlet-mapping>...</servlet-mapping>
<!-- security-constraints-->
<security-constraint>...</security-constraint>
<!-- login-config goes here -->
<!-- security-roles -->
<security-role>...</security-role>
</web-app>
web.xml
安全限制通常用于基于角色的访问控制,但可选 user-data-constraint
元素可指定传输保证,防止采用不安全的方式传输内容。<user-data-constraint>
标签内的 <transport-guarantee>
标签定义了通信处理方式。传输保证分为三个级别:NONE
意味着应用程序不需要任何传输保证。INTEGRAL
意味着应用程序要求在客户端与服务器之间发送数据期间不可在传输过程中更改数据。CONFIDENTIAL
意味着应用程序要求在传输内容期间防止其他实体观察传输内容。INTEGRAL
或 CONFIDENTIAL
意味着需要 SSL/TLS。如果忽略 <user-data-constraint>
和 <transport-guarantee>
标签,则传输保证默认为 NONE
。
<security-constraint>
<web-resource-collection>
<web-resource-name>Storefront</web-resource-name>
<description>Allow Customers and Employees access to online store front</description>
<url-pattern>/store/shop/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>Anyone</description>
<role-name>anyone</role-name>
</auth-constraint>
</security-constraint>
AuthenticationFilter
的筛选器映射。由于缺少定义,筛选器 AuthenticationFilter
不会应用于指定的 URL 模式 /secure/*
,而且可能导致运行时异常。
<filter>
<description>Compresses images to 64x64</description>
<filter-name>ImageFilter</filter-name>
<filter-class>com.ImageFilter</filter-class>
</filter>
<!-- AuthenticationFilter is not defined -->
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/secure/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ImageFilter</filter-name>
<servlet-name>ImageServlet</servlet-name>
</filter-mapping>
role-name
的安全限制会阻止对其保护的所有资源进行合法访问。auth-constraint
中定义的 role-name
缺少 security-role
可能表示配置过时。role-name
,但未在 security-role
中对其进行定义。
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPage</web-resource-name>
<description>Admin only pages</description>
<url-pattern>/auth/noaccess/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>Administrators only</description>
<role-name>admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>INTEGRAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
web.xml
中定义的 Servlet。web.xml
中的以下条目可定义 ExampleServlet
,但无法定义相应的 Servlet 映射。
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>ExampleServlet</servlet-name>
<servlet-class>com.class.ExampleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>EmployeeRecord</ejb-name>
<home>com.wombat.empl.EmployeeRecordHome</home>
<remote>com.wombat.empl.EmployeeRecord</remote>
...
</entity>
...
</enterprise-beans>
</ejb-jar>
ANYONE
角色授予调用 EJB 方法的权限。ANYONE
角色的访问权限的方法权限,这表明未充分考虑应用程序的访问控制,或者应用程序的结构无法实现合理的访问控制限制。ANYONE
权限来调用名为 getSalary()
的 Employee
EJB 方法。
<ejb-jar>
...
<assembly-descriptor>
<method-permission>
<role-name>ANYONE</role-name>
<method>
<ejb-name>Employee</ejb-name>
<method-name>getSalary</method-name>
</method-permission>
</assembly-descriptor>
...
</ejb-jar>
--anonymous-auth=true
标记允许匿名请求。
...
spec:
containers:
- command:
- kube-apiserver
...
- --anonymous-auth=true
...
--audit-log-path
标记的情况下启动 Kubernetes API 服务器。
...
spec:
containers:
- command:
- kube-apiserver
- --authorization-mode=RBAC
image: example.domain/kube-apiserver-amd64:v1.6.0
...
--basic-auth-file=<filename>>
标记以使用 HTTP 基本身份验证。
...
kind: Pod
...
spec:
containers:
- command:
- kube-apiserver
- --basic-auth-file=<filename>
image: example.domain/kube-apiserver-amd64:v1.6.0
livenessProbe:
...