为什么会有 Http security 这么个东西存在?
- 为了阻止假用户冒充真实用户访问网站,所以需要 认证(authentication)。
- 为了阻止真实用户访问本不是他应该访问的页面,所以需要授权(authorization)。
- 为了阻止真实用户与网站之间传输的信息被第三方窃听到,所以需要加密(encryption)。
Spring Security是一个强大的、可根据需求高度自定义的用户认证和访问控制框架。Spring Security 怎么保证所有向
Spring application 发送请求的用户必须先通过认证?怎么保证用户可以通过表单或者 http
的方式进行认证。解决的办法是Spring
Security中有个WebSecurityConfigurerAdapter类,程序员通过继承这个类并重写
configure(HttpSecurity http) 方法就可以按照场景需求自定义认证和授权。HttpSecurity是Spring Security Config用于配置http请求安全控制的安全构建器(类似于Spring
Security
XML配置中的http命名空间配置部分),它的构建目标是一个SecurityFilterChain,实现类使用DefaultSecurityFilterChain。该目标SecurityFilterChain最终会被Spring
Security的安全过滤器FilterChainProxy所持有和应用于相应的http请求的安全控制。
// 这是源码中默认的 认证 和 授权 的配置。
protected void configure(HttpSecurity http) throws Exception {
this.logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
((HttpSecurity)((HttpSecurity)((AuthorizedUrl)http.authorizeRequests().anyRequest()).authenticated().and()).formLogin().and()).httpBasic();
}
这个配置规定了以下三点:
- 若要给应用程序发送请求,则发送请求的用户必须先通过认证。
- 允许用户采用表单登录的方式进行认证。
- 允许用户采用 HTTP 基本的认证方式进行认证。
Java配置和表单登录
当配置表单登录后,就需要一个登录页面供用户填写 用户名 和 密码。Spring Secrity
默认了一个页面,如果你觉得它很丑,也可以自己写一个,使用 loginPage(“/login”)
声明自定义的登录页面所在位置。当用户第一次访问 web 应用时会自动跳转到默认登录界面或者用户自定义的登录界面。
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll();
}
在这个demo中,loginPage(“/login”)指定了登录页的URL,并允许所有的用户(包括没认证的)访问登录页,formLogin().permitAll()方法允许所有用户访问这个URL。
认证请求应用程序的每个URL都要求用户通过认证,我们可以通过给http.authorizeRequests()方法添加子方法的方式为每个URL指定自定义要求。例如:
//请求授权验证
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() 1
.antMatchers("/resources/**", "/signup", "/about").permitAll() 2
.antMatchers("/admin/**").hasRole("ADMIN") 3
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") 4
.anyRequest().authenticated() 5
.and()
// ...
.formLogin();
}
**http.authorizeRequests()**下添加了多个匹配器,每个匹配器用来控制不同的URL接受不同的用户访问。简单讲,http.authorizeRequests()就是在进行请求的权限配置。 所有用户都可以访问以/resources/**开头的URL,和/signup、/about两个URL。 拥有ADMIN角色的用户可以访问以/admin/开头的URL。hasRole(String):如果当前用户有String表示的角色,则返回True。 同时拥有ADMIN和DBA角色的用户可以访问以/db/**开头的URL。 access(String):当String为true时才可进行访问。 所有没被匹配器匹配到的URL都需用户通过认证。 and()返回一个SecurityBuilder。Spring Security支持两种认证方式:formLogin()和httpBasic()。
安全构建器HttpSecurity和WebSecurity的区别是 :
WebSecurity不仅通过HttpSecurity定义某些请求的安全控制,也通过其他方式定义其他某些请求可以忽略安全控制;
HttpSecurity仅用于定义需要安全控制的请求(当然HttpSecurity也可以指定某些请求不需要安全控制);
可以认为HttpSecurity是WebSecurity的一部分,WebSecurity是包含HttpSecurity的更大的一个概念;
注意 : 这里是从语义上讲,而不是从实现层面的表示形式上讲;
构建目标不同
WebSecurity构建目标是整个Spring Security安全过滤器FilterChainProxy,
而HttpSecurity的构建目标仅仅是FilterChainProxy中的一个SecurityFilterChain。