Spring Security

安全简介

在 Web 开发中,安全一直是非常重要的一个方面。

  • 属于应用的非功能性需求

  • 应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:

    • 一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取;
    • 另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的调整,因而需要更多的开发时间,影响应用的发布进程。因此,从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中。
  • 市面上存在比较有名的:Shiro,Spring Security !

  • 安全框架有两个重要的概念,即认证(Authentication)和授权(Authorization).认证即确认用户可以访问当前的系统;授权即确定用户在当前系统下拥有的功能权限

Spring Security框架

简介

Spring Security官网地址

官网描述

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

  • Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于spring的应用程序的标准。

  • Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求

  • Spring Security是专门针对基于Spring的项目的安全框架,充分利用了依赖注入和AOP来实现安全功能。

  • 在认证(Authentication)和授权(Authorization)两个方面,Spring Security框架支持如下功能:

    • 在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。
    • 在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。

Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!

Spring Security中常用的类:

  • WebSecurityConfigurerAdapter:自定义Security策略

  • AuthenticationManagerBuilder:自定义认证策略

  • @EnableWebSecurity:开启WebSecurity模式

配置Spring Security

Spring Security的配置和Spring MVC的配置相似,只需要让配置类具有安全策略并开启WebSecurity模式即可。要实现这两步,则需要继承WebSecurityConfigurerAdapter类和加上@EnableWebSecurity注解。我们可以通过重写config方法来配置相关的安全策略。
例如:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
    }

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

1.用户认证

认证需要我们有一套用户数据来源,而授权则是对某个用户有相应的角色权限。我们通过重写

configure(AuthenticationManagerBuilder auth)

方法来实现定制。

  • 认证内存中的用户

    使用AuthenticationManagerBuilderinMemoryAuthentication方法即可添加在内存中的用户,并可给用户指定角色权限
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //其中passwordEncoder方法为password加密处理
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip2","vip3")
                .and()
                .withUser("user1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
                .and()
                .withUser("user2").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2")
                .and()
                .withUser("user3").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}//采用链式编程
  • 认证JDBC中的用户

    JDBC中的用户直接指定dataSource即可
@Autowired
DataSource dataSource;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource);
}

这代码看上去很奇怪,其实这里的SpringSecurity是默认了你的数据库结构。通过jdbcAuthentication的源码,我们可以看出在JdbcDaoImpl中定义了默认的用户及角色权限获取的SQL语句

public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled "
			+ "from users "
			+ "where username = ?";
public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority "
			+ "from authorities "
			+ "where username = ?";

当然我们可以自定义我们的查询用户和权限的SQL语句,例如:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("select username,password,enabled " +
                         "from users " +
                         "where username = ?")
                .authoritiesByUsernameQuery("select username,authority "
                        + "from authorities "
                        + "where username = ?");
}

2.请求授权

Spring Security通过重写

configure(HttpSecurity http)

方法来实现请求拦截。

@Override
    //请求授权
    protected void configure(HttpSecurity http) throws Exception {
        //首页都可访问,但是功能页只有权限的可以
        http.authorizeRequests()
                .antMatchers("/").permitAll()       //首页都可访问
                .antMatchers("/level1/**").hasRole("vip1")  //各模块的不同权限
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        //没有权限,进入自带的登录页面,   需要开启登录的页面
        // 开启自动配置的登录功能
                // /login 请求来到登录页
                // /login?error 重定向到这里表示登录失败
        http.formLogin();

        //开启注销功能
        http.logout();
    }

上述代码分析:

  • 通过authorizeRequests方法来开始请求权限配置
  • 请求匹配/*,permitAll方法为所有用户放行,所有用户都可访问
  • 请求匹配/level1/**,拥有vip1角色的用户可以访问
  • 请求匹配/level2/**,拥有vip2角色的用户可以访问
  • 请求匹配/level3/**,拥有vip3角色的用户可以访问

3.定制登录行为

拿一段代码演示:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/index")
                .failureUrl("/login?error")
                .permitAll()
                .and()
                .rememberMe()
                    .tokenValiditySeconds(1209600)
                    .key("myKey")
                .and()
                .logout()
                    .logoutUrl("/custom-logout")
                    .logoutSuccessUrl("/logout-success")
                    .permitAll();
}

上述代码分析:

  • 通过formLogin方法定制登录操作
  • 使用loginPage方法定制登录页面的访问地址
  • defaultSuccessUrl指定登录成功后转向的页面
  • failureUrl指定登录失败后转向的面
  • ememberMe开启cookie存储用户信息
  • tokenValiditySeconds指定cookie有效期为1209600秒,即2星期
  • key指定cookie中的私钥
  • 使用logout方法定制注销行为
  • logoutUrl指定注销的URL路径
  • logoutSuccessUrl指定注销成功后转向的页面

Spring Boot对Spring Security的支持

Spring Boot 针对Spring Security的自动配置在org.springframework.boot.autoconfigure.security.servlet包中。

主要通过SecurityAutoConfiguration和SecurityProperties来完成配置。

SecurityAutoConfiguration导入了SpringBootWebSecurityConfiguration中的配置。在SpringBootWebSecurityConfiguration中我们获得如下的自动配置:

  1. 自动配置了一个内存中的用户,账号为user,密码在程序启动时出现

  2. 忽略了/css/**,/js/**,/images/**和/favicon.ico等静态文件的拦截

  3. 自动配置的securityFilterChainRegistration的Bean

Spring Boot为我们做了如此多的配置,当我们需要自己拓展的配置时,只需配置类继承WebSecurityConfigurerAdapter类即可,无须使用@EnableWebSecurity注解,例如

public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值