Board logo

标题: 使用 Spring Security 保护 Web 应用的安全(2) [打印本页]

作者: look_w    时间: 2018-9-19 19:50     标题: 使用 Spring Security 保护 Web 应用的安全(2)

基本用户认证和授权本节从最基本的用户认证和授权开始对 Spring Security 进行介绍。一般来说,Web 应用都需要保存自己系统中的用户信息。这些信息一般保存在数据库中。用户可以注册自己的账号,或是由系统管理员统一进行分配。这些用户一般都有自己的角色,如普通用户和管理员之类的。某些页面只有特定角色的用户可以访问,比如只有管理员才可以访问 /admin 这样的网址。下面介绍如何使用 Spring Security 来满足这样基本的认证和授权的需求。
首先需要把 Spring Security 引入到 Web 应用中来,这是通过在 web.xml添加一个新的过滤器来实现的,如  所示。
清单 1. 在 web.xml 中添加 Spring Security 的过滤器
1
2
3
4
5
6
7
8
9
<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>




Spring Security 使用的是 Servlet 规范中标准的过滤器机制。对于特定的请求,Spring Security 的过滤器会检查该请求是否通过认证,以及当前用户是否有足够的权限来访问此资源。对于非法的请求,过滤器会跳转到指定页面让用户进行认证,或是返回出错信息。需要注意的是, 中虽然只定义了一个过滤器,Spring Security 实际上是使用多个过滤器形成的链条来工作的。
下一步是配置 Spring Security 来声明系统中的合法用户及其对应的权限。用户相关的信息是通过 org.springframework.security.core.userdetails.UserDetailsService 接口来加载的。该接口的唯一方法是 loadUserByUsername(String username),用来根据用户名加载相关的信息。这个方法的返回值是 org.springframework.security.core.userdetails.UserDetails 接口,其中包含了用户的信息,包括用户名、密码、权限、是否启用、是否被锁定、是否过期等。其中最重要的是用户权限,由 org.springframework.security.core.GrantedAuthority 接口来表示。虽然 Spring Security 内部的设计和实现比较复杂,但是一般情况下,开发人员只需要使用它默认提供的实现就可以满足绝大多数情况下的需求,而且只需要简单的配置声明即可。
在第一个示例应用中,使用的是数据库的方式来存储用户的信息。Spring Security 提供了 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 类来支持从数据库中加载用户信息。开发人员只需要使用与该类兼容的数据库表结构,就可以不需要任何改动,而直接使用该类。 中给出了相关的配置。
清单 2. 声明使用数据库来保存用户信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<bean id="dataSource"
   class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver" />
   <property name="url" value="jdbc:derby://localhost:1527/mycompany" />
   <property name="username" value="app" />
   <property name="password" value="admin" />
</bean>

<bean id="userDetailsService"
   class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
   <property name="dataSource" ref="dataSource" />
</bean>

<sec:authentication-manager>
   <sec:authentication-provider user-service-ref="userDetailsService" />
</sec:authentication-manager>




如  所示,首先定义了一个使用 Apache Derby 数据库的数据源,Spring Security 的 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 类使用该数据源来加载用户信息。最后需要配置认证管理器使用该 UserDetailsService。
接着就可以配置用户对不同资源的访问权限了。这里的资源指的是 URL 地址。配置的内容如  所示。sec 是 Spring Security 的配置元素所在的名称空间的前缀。
清单 3. 配置对不同 URL 模式的访问权限
1
2
3
4
5
6
7
<sec:http>
   <sec:intercept-url pattern="/president_portal.do**" access="ROLE_PRESIDENT" />
   <sec:intercept-url pattern="/manager_portal.do**" access="ROLE_MANAGER" />
   <sec:intercept-url pattern="/**" access="ROLE_USER" />
   <sec:form-login />
   <sec:logout />
</sec:http>




第一个示例应用中一共定义了三种角色:普通用户、经理和总裁,分别用 ROLE_USER、ROLE_MANAGER 和 ROLE_PRESIDENT 来表示。 中定义了访问不同的 URL 模式的用户所需要的角色。这是通过 <sec:intercept-url> 元素来实现的,其属性 pattern 声明了请求 URL 的模式,而属性 access 则声明了访问此 URL 时所需要的权限。需要按照 URL 模式从精确到模糊的顺序来进行声明。因为 Spring Security 是按照声明的顺序逐个进行比对的,只要用户当前访问的 URL 符合某个 URL 模式声明的权限要求,该请求就会被允许。如果把  中本来在最后的 URL 模式 /** 声明放在最前面,那么当普通用户访问 /manager_portal.do 的时候,该请求也会被允许。这显然是不对的。通过 <sec:form-login> 元素声明了使用 HTTP 表单验证。也就是说,当未认证的用户试图访问某个受限 URL 的时候,浏览器会跳转到一个登录页面,要求用户输入用户名和密码。<sec:logout> 元素声明了提供用户注销登录的功能。默认的注销登录的 URL 是 /j_spring_security_logout,可以通过属性 logout-url 来修改。
当完成这些配置并运行应用之后,会发现 Spring Security 已经默认提供了一个登录页面的实现,可以直接使用。开发人员也可以对登录页面进行定制。通过 <form-login> 的属性 login-page、login-processing-url 和 authentication-failure-url就可以定制登录页面的 URL、登录请求的处理 URL 和登录出现错误时的 URL 等。从这里可以看出,一方面 Spring Security 对开发中经常会用到的功能提供了很好的默认实现,另外一方面也提供了非常灵活的定制能力,允许开发人员提供自己的实现。
在介绍如何用 Spring Security 实现基本的用户认证和授权之后,下面介绍其中的核心对象。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0