16. 确保流动

安全性是任何应用中一个重要的概念。终端用户不应仅凭猜测URL就能访问网站的任何部分。网站中敏感区域必须确保只处理授权请求。Spring Security是一个经过验证的安全平台,可以在多个层面与您的应用集成。本节重点关注确保流程执行的安全。spring-doc.cadn.net.cn

16.1. 如何确保流量?

确保流量是一个三步过程:spring-doc.cadn.net.cn

  1. 配置Spring Security并设置认证和授权规则。spring-doc.cadn.net.cn

  2. 在流定义中注注安全元素以定义安全规则。spring-doc.cadn.net.cn

  3. 添加SecurityFlowExecutionListener处理安全规则。spring-doc.cadn.net.cn

每一步都必须完成,否则流安全规则将不适用。spring-doc.cadn.net.cn

16.2. 该担保元素

担保元素指定其包含元素应在完全进入前应用授权检查。在已安全流执行的每个阶段,这一检查最多只能发生一次。spring-doc.cadn.net.cn

一个流程可以分为三个阶段:流、状态和转移。在每种情况下,语法担保元素是相同的。 这担保元素位于其所保护的元素内部。例如,要保护一个状态,担保元素直接出现在该状态内,具体如下:spring-doc.cadn.net.cn

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

16.2.1. 安全属性

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

<secured attributes="ROLE_USER" />

默认情况下,是基于权威的授权管理器用于判断用户是否被允许访问。如果您的应用程序没有使用授权角色,则需要覆盖该作。spring-doc.cadn.net.cn

16.2.2. 匹配类型

匹配有两种类型:任何.任何如果用户获得至少一项所需的安全属性,则允许访问。只有当用户获得所有所需的安全属性时,才允许访问。spring-doc.cadn.net.cn

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

该属性为可选。如果未定义,默认值为任何.spring-doc.cadn.net.cn

火柴只有当使用默认访问决策管理器时,属性才会被尊重。spring-doc.cadn.net.cn

16.3. 该SecurityFlowExecutionListener

仅仅在流程中定义安全规则并不能保护流程。你还必须定义一个SecurityFlowExecutionListener在Webflow配置中,并将其应用到流执行器中,具体如下:spring-doc.cadn.net.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" />

如果申请部分内容被拒绝访问,则访问拒绝例外被抛出。该异常后来被 Spring Security 捕获并用来提示用户进行认证。重要的是允许该异常在执行栈中不受限制地向上移动。否则,终端用户可能不会被提示进行认证。spring-doc.cadn.net.cn

16.3.1. 自定义授权管理器

如果你的应用使用非基于角色的权限,你需要配置自定义授权经理. 你可以覆盖AuthorityAuthorizationManager默认使用 这授权管理器初始化器安全监听器上的财产。 例如:spring-doc.cadn.net.cn

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

16.4. 配置 Spring Security

Spring Security 提供了强大的配置选项。由于每个应用和环境都有其独特的安全要求,Spring Security 参考文档是学习可用选项的最佳来源。spring-doc.cadn.net.cn

两者正派Booking-MVC示例应用程序配置为使用 Spring Security。配置需要在 Spring 和web.xml水平。spring-doc.cadn.net.cn

16.4.1. Spring配置

Spring配置定义了http具体内容(如受保护的URL和登录/登出机制)以及认证提供者. 对于示例应用,会配置本地认证提供商。以下示例为网页流配置了 Spring Security:spring-doc.cadn.net.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配置

web.xml文件,AFilter定义为拦截所有请求。该过滤器监听登录和注出请求并相应处理。它还捕获AccesDeniedException实例,并将用户重定向到登录页面。以下示例定义了此类过滤器:spring-doc.cadn.net.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>