Spring-Security使用总结

1.介绍
Spring Security是基于Spring的提供声明式事务安全保护的安全性框架,提供了完整的安全性解决方案,能够在web请求级别和方法调用级别处理身份证验证和授权。充分使用了DI和AOP。
*web请求级别:使用servlet过滤器保护web请求并限制URL级别的访问
*方法调用级别:使用AOP保护方法调用,确保具有适当权限的用户采用访问安全保护的方法

*** 框架的核心组件
SecurityContextHolder:提供对SecurityContext的访问
SecurityContext,:持有Authentication对象和其他可能需要的信息
AuthenticationManager 其中可以包含多个AuthenticationProvider
ProviderManager对象为AuthenticationManager接口的实现类
AuthenticationProvider 主要用来进行认证操作的类 调用其中的authenticate()方法去进行认证操作
Authentication:Spring Security方式的认证主体
GrantedAuthority:对认证主题的应用层面的授权,含当前用户的权限信息,通常使用角色表示
UserDetails:构建Authentication对象必须的信息,可以自定义,可能需要访问DB得到
UserDetailsService:通过username构建UserDetails对象,通过loadUserByUsername根据userName获取UserDetail对象 (可以在这里基于自身业务进行自定义的实现 如通过数据库,xml,缓存获取等)


2.Web请求级别的保护
对于请求级别的安全来说,主要是通过保护一个或多个URL,使得只有特定的用户才能访问,并其他用户访问该URL的内容,本文主要是基于springmvc下整合Spring security模块。
2.1声明代理Servlet过滤器
在web.xml中加入过滤器

1
2 springSecurityFilterChain
3
4 org.springframework.web.filter.DelegatingFilterProxy
5

6

DelegatingFilterProxy是一个代理的Servelt过滤器,它主要负责将工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个已经注册在Spring应用的上下文,且该bean的Id便是上面的名字,即springSecurityFilterChain.

springSecurityFilterChain,也可称为FilterChainProxy.它可以链接任意多个其他的过滤器,根据这些过滤器提供不同的安全特性.但是你并不需要在spring配置文件中配置该过滤器的bean和它所链接的其他过滤器.
2.2配置最小化的web安全性和拦截请求

1
2
3

在spring的配置文件中加入这段代码可以拦截站点/admin分支行下的所有URL请求.并限制只有具备"ROLE_ADMIN"权限的用户才可以访问,"ROLE_ADMIN"是自定义的一个权限.pattern默认使用的是Ant格式。如果需要使用正则表达式则在http 元素的path-type设置为regex。能够拦截请求,主要是对指定的URL进行保护,如果用户具有访问指定的URL的权限则通过否则拒绝。

元素将自动创建一个FilterChainProxy以及链中所有的过滤器bean.同时会将FilterChainProxy的bean托管给配置在web.xml的DelegatingFilterProxy.设置auto-config="true"会自动生成一个登陆界面,可以通过http://localhost:8080/你的项目名称/spring_security_login.设置为ture也等价于下面的配置:


 

  



Spring security 3.0以后加入了对SpEL的支持,可以将元素的use-expressions设置为"true"便可使用SpEL。


..


2.3 通过表单安全登陆

虽然元素设置auto-config="true",可以自动生成一个自动登陆页面。当一般开始都是采用自定义的登陆界面。所以需要进行下面配置:



login-page="/login" authentication-failure-url="/login?login_error=t">

在自定义的登录界面中将表单提交地址设置为"/static/j_spring_security_check",同时需要将用户名输入框和密码输入框name分别设置为j_username和j_password 。有些应用中往往会设置记住密码,方便用户访问应用,不需要每次都登录。实现该功能只需要在元素中加入:


静态页面中加入:

2.4 强制请求使用https

https传输数据比较安全,如将用户,密码提交可以使用https保证数据传输的安全。可以进行以下设置,保证每次对指定URL请求,Spring Security都会自动重定向为https请求。不管用户访问时是否加入https.

3. 保护视图

Spring Security提供jsp标签库,支持视图级别的保护,这个标签库包含3个标签:

  1. :如果认证用户具有权限列表中的某一个权限,那么这个标签范围的内容将显示。
  2. : 访问当前用户认证对象的属性。一般用户显示当前用户的用户名之类的。具有的用户认证信息有:
  • authorities:一组用于用户所授予的GrantedAuthority对象
  • credentials:核实用户的凭据
  • detail:认证的附加信息(IP地址,会话ID等)
  • principal:用户的主要信息对象

3.: 如果当前用户满足特定全新,则显示标签范围的内容。例:

 Hello 
如果当前用户有ROLE_ADMIN权限,则显示这部分内容

除了使用access来指定权限外还可以根据url设置具体权限,即在拦截请求中指定的url的权限。

 如果当前用户有/admin/对应的权限,则显示这部分内容 

4.认证用户
 前面提到很多用户对象和用户权限的问题,他们的关系和定义就是通过认证用户来定义的。 Spring Security提供了以下认证策略:

  • 内存用户存储库,即显示的配置在spring配置文件中。
  • 基于jdbc的用户存储库
  • 基于LDAP的用户存储库
  • OpenID 分散式用户身份识别系统
  • 中心认证服务(CAS)
  • X.509证书
  • 基于JAAS的提供者

这里主要是介绍基于spirng配置和jdbc的。

4.1 配置内存用户存储库

首先建立一个用户服务,配置所有用户和权限信息。然后交给认证管理器管理,认证管理器会将认证的任务交给一个或多个认证提供者。





......




另一种方式将认证提供者和用户服务装配在一起,适用于只有一种用户服务:  






......

4.2 基于数据库进行认证

这个是最常用的是用户认证,因为很多应用都是采用数据库存储用户数据。Spring Security提供了.如果只指定了 data-source-ref得数据源,那么spring security会自己为我们写sql语句从数据库中查找用户和权限信息。但一般情况下,提供的查询语句并不能和我们的数据库对应上,所以我们需要自己写sql语句。主要包括以下属性:

  • users-by-username-query:根据用户名查询用户名,密码以及是否可用状态
  • authorities-by-username-query:根据用户名查询用户被用户名和授权的权限。
  • group-authorities-by-username-query:根据用户名查询用户组的权限。 
     
          users-by-username="select username,password, true from user where username=?"
          authories-by-username-query="select username,role from user_role where username=?" />


5.保护方法调用

spring security的方法级别的保护是基于Spring AOP技术。首先需要在spring配置文件中加以下配置,才能使spring Security保护那些使用相关注解的方法。

spring Security支持4种方法级别安全性的方法:

  1. 使用@Secured注解方法,这是spring自带的注解方法。@Secured("")内部的字符串不具有SpEL特性,只能是具体的权限。
  2. 使用@JSR-250 @RelosAllowed注解的方法。作用和使用方法与@Secured一样,不同在于它不是spring框架的,所以可以做到和spring框架的解耦。
  3. 使用Spring 方法调用前和调用后注解方法。这些方法支持SpEL.
  4. 匹配一个或多个明确声明的切点方法。

5.1 @Secured和 @RelosAllowed

@Secured("ROLE_ADMIN")
public void addUser(User user){
...
}
@RolesAllowed("ROLE_ADMIN")
public void updateUser(User user){
...
}

5.2 使用Spring 方法调用前和调用后注解方法

可以使用SpEL方法有四种:

  1. @PreAuthorize: 在方法调用前,基于表达式计算结果来限制方法访问
  2. @PostAuthorize: 允许方法调用,但是如果表达式结果为fasle则抛出异常
  3. @PostFilter :允许方法调用,但必须按表达式过滤方法结果。
  4. @PreFilter:允许方法调用,但必须在进入方法前过滤输入值

@PreAuthorize("hasRole('ROLE_ADMIN')")
public void addUser(User user){
//如果具有权限 ROLE_ADMIN 访问该方法
....
}

//returnObject可以获取返回对象user,判断user属性username是否和访问该方法的用户对象的用户名一样。不一样则抛出异常。
@PostAuthorize("returnObject.user.username==principal.username")
public User getUser(int userId){
//允许进入
...
return user;
}

//将结果过滤,即选出性别为男的用户
@PostFilter("returnObject.user.sex=='男' ")
public List getUserList(){
//允许进入
...
return user;
}

举例清单

5.3 匹配一个或多个明确声明的切点方法

为多个方法设置相同的授权检查,spring security提供了 元素。配置如下:


6. Spring security 相关初始化后设置

使用默认登录地址:/login

登录成功跳转地址:/hello

登出地址:/logout

除了登录地址为其他都需要校验:anyRequest().authenticated()

不拦截路径中包含/test的请求:antMatchers("/test").permitAll()

通过内存方式设置用户名密码和角色:admin,admin和USER

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            //不拦截路径中包含test的请求
            .antMatchers("/", "/test").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().successForwardUrl("/hello").permitAll()
            .and()
            .logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll()
            .and()
            .httpBasic();
    http.csrf().disable();
}

@Override
public void configure(WebSecurity web) throws Exception{
    super.configure(web);
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .inMemoryAuthentication()
            .withUser("admin").password("admin").roles("USER");
    //在内存中创建了一个用户,该用户的名称为user,密码为password,用户角色为USER
}

}

你可能感兴趣的:(Spring-Security使用总结)