基于Spittr应用
一、Spring Security简介
Spring Security是为基于Spring的应用程序提供声明式安全保护的安全 性框架。Spring Security提供了完整的安全性解决方案,它能够在Web 请求级别和方法调用级别处理身份认证和授权。因为基于Spring框 架,所以Spring Security充分利用了依赖注入(dependency injection, DI)和面向切面的技术。
不管你想使用Spring Security保护哪种类型的应用程序,第一件需要做 的事就是将Spring Security模块添加到应用程序的类路径下,一共有11个模块,应用程序的类路径下至少要包含Core和Configuration这两个模块。
二、过滤Web请求
Spring Security借助一系列Servlet Filter来提供各种安全性功能。DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做 的工作并不多。只是将工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个<bean>注册在Spring应用的上下文中, 如下图所示:
可以在web.xml进行配置,也可用Java配置。
三、编写简单的安全性配置
1.启用Web安全性功能的最简单配置
SecurityWebInitializer.java
1 package myspittr.config; 2 3 import org.springframework.context.annotation.Configuration; 4 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 5 import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; 6 7 @Configuration 8 @EnableWebSecurity // 启用SpringMVC安全性 9 public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer { 10 11 }
@EnableWebSecurity注解将会启用Web安全功能。Spring Security必须配置在一个实现了 WebSecurityConfigurer的bean中,或者(简单起见)扩展WebSecurityConfigurerAdapter。在Spring应用上下文中, 任何实现了WebSecurityConfigurer的bean都可以用来配置Spring Security。但如果想指定Web安全的细节,这要通过重载WebSecurityConfigurerAdapter中的一个或多个方法来实现。我们可以通过重载WebSecurityConfigurerAdapter的三 个configure()方法来配置Web安全性,这个过程中会使用传递进来的参数设置行为。
SecuritfConfig.java
1 package myspittr.config; 2 3 import org.springframework.context.annotation.Configuration; 4 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 7 8 @Configuration 9 @EnableWebSecurity 10 public class SecuritfConfig extends WebSecurityConfigurerAdapter { 11 12 @Override 13 protected void configure(HttpSecurity http) throws Exception { 14 15 http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic(); 16 17 } 18 }
这个简单的默认配置指定了该如何保护HTTP请求,以及客户端认证 用户的方案。通过调用authorizeRequests()和anyRequest().authenticated()就会要求所有进入应用的 HTTP请求都要进行认证。它也配置Spring Security支持基于表单的登录以及HTTP Basic方式的认证。同时,因为我们没有重 载configure(AuthenticationManagerBuilder)方法,所以 没有用户存储支撑认证过程。没有用户存储,实际上就等于没有用户。所以,在这里所有的请求都需要认证,但是没有人能够登录成功。
为了让Spring Security满足应用的需求,还需要再添加一点配置。具体来讲,我们需要:
-
-
- 配置用户存储;
- 指定哪些请求需要认证,哪些请求不需要认证,以及所需要的权限;
- 提供一个自定义的登录页面,替代原来简单的默认登录页。
-
除了Spring Security的这些功能,我们可能还希望基于安全限制,有选择性地在Web视图上显示特定的内容。接下来首先介绍用户认证,即配置用户存储。
四、用户认证
1.使用基于内存的用户存储进行登录认证
因为安全配置类扩展了 WebSecurityConfigurerAdapter,因此配置用户存储的最简单 方式就是重载configure()方法,并以AuthenticationManagerBuilder作为传入参数。AuthenticationManagerBuilder有多个方法可以用来配置 Spring Security对认证的支持。通过inMemoryAuthentication() 方法,可以启用、配置并任意填充基于内存的用户存储。
SecuritfConfig.java
1 package myspittr.config; 2 3 import org.springframework.context.annotation.Configuration; 4 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 5 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 9 @Configuration 10 @EnableWebSecurity 11 public class SecuritfConfig extends WebSecurityConfigurerAdapter { 12 13 DataConfig dataConfig = new DataConfig(); 14 15 @Override 16 protected void configure(AuthenticationManagerBuilder auth) throws Exception { 17 // // TODO Auto-generated method stub 18 // 启用内存用户存储 19 auth.inMemoryAuthentication().withUser("user").password("password").roles("USER").and().withUser("admin") 20 .password("password").roles("USER", "ADMIN"); 21 22 } 23 24 @Override 25 protected void configure(HttpSecurity http) throws Exception { 26 27 http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic(); 28 29 } 30 }
configure()方法中的 AuthenticationManagerBuilder使用构造者风格的接口来构建认证配置。通过简单地调用inMemoryAuthentication()就能启用内存用户存储。调用withUser()方法为内存用户存储添加新的用户,这个方法的参数是username。withUser()方法返回的是UserDetailsManagerConfigurer.UserDetailsBuilder, 这个对象提供了多个进一步配置用户的方法,包括设置用户密码的 password()方法以及为给定用户授予一个或多个角色权限的 roles()方法。
上述程序中,添加了两个用户,“user”和“admin”,密码均为“password”。“user”用户具有USER角色,而“admin”用户具有 ADMIN和USER两个角色。我们可以看到,and()方法能够将多个用户的配置连接起来除了password()、roles()和and()方法以外,还有其他的几个方法可以用来配置内存用户存储中的用户信息。下表描述了 UserDetailsManagerConfigurer.UserDetailsBuilder对象所有可用的方法。
方法 | 描述 |
accountExpired(boolean) | 定义账号是否已经过期 |
accountLocked(boolean) | 定义账号是否已经锁定 |
and() | 用来连接配置 |
authorities(List<? extends GrantedAuthority>) | 授予某个用户一项或多项权限 |
authorities(GrantedAuthority) | 授予某个用户一项或多项权限 |
authorities(String) | 授予某个用户一项或多项权限 |
credentialsExpired(boolean) | 定义凭证是否已经过期 |
disabled(boolean) | 定义账号是否已被禁用 |
password(String) | 定义用户的密码 |
roles(String) | 授予某个用户一项或多项角色 |
当输入用户名和密码后才能进入应用首页。
2.基于数据库表进行认证
用户数据通常会存储在关系型数据库中,并通过JDBC进行访问。为 了配置Spring Security使用以JDBC为支撑的用户存储,我们可以使用jdbcAuthentication()方法,所需的最少配置如下所示:
我们必须要配置的只是一个DataSource,这样的话,就能访问关系 型数据库了。在这里,DataSource是通过自动装配的技巧得到的。
3.配置自定义的用户服务
五、拦截请求
1.web应用路径保护
2.强制通道的安全性
3.防止跨站请求伪造
六、视图保护