16. 保护流

安全性对于任何应用程序来说都是一个重要的概念。 最终用户不应仅通过猜测 URL 来访问网站的任何部分。 站点的敏感区域必须确保仅处理授权请求。 Spring Security 是一个经过验证的安全平台,可以在多个级别与您的应用程序集成。 本节重点介绍如何保护流执行。spring-doc.cn

16.1. 如何保护流?

保护流的过程分为三个步骤:spring-doc.cn

  1. 使用身份验证和授权规则配置 Spring Security。spring-doc.cn

  2. 使用安全元素对流定义进行批注以定义安全规则。spring-doc.cn

  3. 添加 以处理安全规则。SecurityFlowExecutionListenerspring-doc.cn

必须完成这些步骤中的每一个,否则不会应用流安全规则。spring-doc.cn

16.2. 元素secured

该元素指定其包含元素应在完全进入之前应用授权检查。 在受保护的流执行的每个阶段,这种情况可能不会多次发生。securedspring-doc.cn

可以保护流的三个阶段:流、状态和转换。 在每种情况下,元素的语法都是相同的。 该元素位于它所保护的元素内。 例如,为了保护某个状态,该元素直接出现在该状态内,如下所示:securedsecuredsecuredspring-doc.cn

<view-state id="secured-view">
    <secured attributes="ROLE_USER" />
    ...
</view-state>

16.2.1. 安全属性

的值是 Spring Security 授权属性的逗号分隔列表。 通常,这些是特定的安全角色。 Spring Security 访问决策管理器将这些属性与用户授予的属性进行比较。attributesspring-doc.cn

<secured attributes="ROLE_USER" />

默认情况下,使用基于权限的 API 来确定是否允许用户访问。 如果您的应用程序未使用授权角色,则需要覆盖此字段。AuthorizationManagerspring-doc.cn

16.2.2. 匹配类型

有两种类型的匹配可用:和 . 如果至少向用户授予了一个必需的安全属性,则允许访问。 仅当向用户授予每个必需的安全属性时,才允许访问。anyallanyallspring-doc.cn

<secured attributes="ROLE_USER, ROLE_ANONYMOUS" match="any" />

此属性是可选的。 如果未定义,则默认值为 。anyspring-doc.cn

仅当使用缺省访问决策管理器时,才会考虑该属性。matchspring-doc.cn

16.3. 使用SecurityFlowExecutionListener

在流中定义安全规则本身并不能保护流。 您还必须在 webflow 配置中定义 a 并将其应用于流执行器,如下所示:SecurityFlowExecutionListenerspring-doc.cn

<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
    <webflow:flow-execution-listeners>
        <webflow:listener ref="securityFlowExecutionListener" />
    </webflow:flow-execution-listeners>
</webflow:flow-executor>

<bean id="securityFlowExecutionListener"
      class="org.springframework.webflow.security.SecurityFlowExecutionListener" />

如果拒绝访问应用程序的某个部分,则会引发 an。 此异常稍后由 Spring Security 捕获,并用于提示用户进行身份验证。 允许此异常不受抑制地在执行堆栈中向上移动,这一点很重要。 否则,系统可能不会提示最终用户进行身份验证。AccessDeniedExceptionspring-doc.cn

16.3.1. 自定义授权管理器

如果您的应用程序使用不基于角色的颁发机构,则需要配置自定义 . 您可以通过 Security 侦听器上的属性。例如:AuthorizaitonManagerAuthorityAuthorizationManagerauthorizationManagerInitializerspring-doc.cn

@Bean
SecurityFlowExecutionListener securityFlowExecutionListener() {
	SecurityFlowExecutionListener listener = new SecurityFlowExecutionListener();
	listener.setAuthorizationManagerInitializer(securityRule -> {
		// ...
	});
	return listener;
}

16.3.2. 自定义访问决策管理器

Spring Security 的已弃用,并将在未来版本中删除。 因此,建议改为配置 一个。 但是,如果必须使用 ,则可以设置安全侦听器的属性 或覆盖 protected 方法。AccessDecisionManagerAuthorizationManagerAccessDecisionManageraccessDecisionManagercreateAccessDecisionManager(SecurityRule)spring-doc.cn

要了解有关 Spring Security 的 API 的更多信息,请参阅 Spring Security 参考文档AuthorizationManagerspring-doc.cn

16.4. 配置 Spring Security

Spring Security 具有强大的配置选项。 由于每个应用程序和环境都有自己的安全要求,因此 Spring Security 参考文档是了解可用选项的最佳场所。spring-doc.cn

和 sample 应用程序都配置为使用 Spring Security。 Spring 和 level 都需要配置。booking-facesbooking-mvcweb.xmlspring-doc.cn

16.4.1. Spring 配置

Spring 配置定义了细节(例如受保护的 URL 和登录/注销机制)和 . 对于示例应用程序,配置了本地身份验证提供程序。 以下示例为 Web 流配置 Spring Security:httpauthentication-providerspring-doc.cn

<security:http auto-config="true">
    <security:form-login login-page="/spring/login"
                         login-processing-url="/spring/loginProcess"
                         default-target-url="/spring/main"
                         authentication-failure-url="/spring/login?login_error=1" />
    <security:logout logout-url="/spring/logout" logout-success-url="/spring/logout-success" />
</security:http>

<security:authentication-provider>
    <security:password-encoder hash="md5" />
    <security:user-service>
        <security:user name="keith" password="417c7382b16c395bc25b5da1398cf076"
                       authorities="ROLE_USER,ROLE_SUPERVISOR" />
        <security:user name="erwin" password="12430911a8af075c6f41c6976af22b09"
                       authorities="ROLE_USER,ROLE_SUPERVISOR" />
        <security:user name="jeremy" password="57c6cbff0d421449be820763f03139eb"
                       authorities="ROLE_USER" />
        <security:user name="scott" password="942f2339bf50796de535a384f0d1af3e"
                       authorities="ROLE_USER" />
    </security:user-service>
</security:authentication-provider>

16.4.2. 配置web.xml

在该文件中,定义了 a 来拦截所有请求。 此筛选器侦听登录和注销请求并相应地处理它们。 它还捕获实例并将用户重定向到登录页面。 以下示例定义了此类筛选器:web.xmlfilterAccesDeniedExceptionspring-doc.cn

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>