SpringBoot 2整合SpringSecurity权限管理(一)SpringSecurity介绍及简单搭建

本系列文章参考了大量文献资料,如杨传杰博客,江南一点雨等,感谢原作者。

本文默认版本:SpringBoot 2.1.9

概述

Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架。除了常规的认证(Authentication)和授权(Authorization)之外,Spring Security还提供了诸如ACLs,LDAP,JAAS,CAS等高级特性以满足复杂场景下的安全需求。另外,就目前而言,Spring Security和Shiro也是当前广大应用使用比较广泛的两个安全框架。

Spring Security 应用级别的安全主要包含两个主要部分,即登录认证(Authentication)和访问授权(Authorization),首先用户登录的时候传入登录信息,登录验证器完成登录认证并将登录认证好的信息存储到请求上下文,然后再进行其他操作,如在进行接口访问、方法调用时,权限认证器从上下文中获取登录认证信息,然后根据认证信息获取权限信息,通过权限信息和特定的授权策略决定是否授权。

实际上,在 Spring Boot 出现之前,Spring Security 就已经发展了多年了,但是使用的并不多,安全管理这个领域,一直是 Shiro 的天下。相对于 Shiro,在 SSM/SSH 中整合 Spring Security 都是比较麻烦的操作,所以,Spring Security 虽然功能比 Shiro 强大,但是使用反而没有 Shiro 多(Shiro 虽然功能没有 Spring Security 多,但是对于大部分项目而言,Shiro 也够用了)。

自从有了 Spring Boot 之后,Spring Boot 对于 Spring Security 提供了 自动化配置方案,可以零配置使用 Spring Security。

因此,一般来说,常见的安全管理技术栈的组合是这样的:

  • SSM + Shiro
  • Spring Boot/Spring Cloud + Spring Security

注意,这只是一个推荐的组合而已,如果单纯从技术上来说,无论怎么组合,都是可以运行的。

一、创建一个SpringBoot项目,引入SpringSecurity依赖

  1. pom.xml 中的 Spring Security 依赖:
<!-- spring security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

​ 只要加入依赖,项目的所有接口都会被自动保护起来。

注意:引入spring security依赖时,会自动启动spring security
禁用:@SpringBootApplication(exclude = {SecurityAutoConfiguration.class })

  1. 我们创建一个 HelloController:

    /**
     * @author ZHANGCHAO
     * @date 2020/3/11 10:34
     * @since 1.0.0
     */
    @RestController
    public class MainController {
        @GetMapping("/hello")
        public String login() {
            return "Hello World";
        }
    }
    
    

    启动项目–观察控制台

    20190709165723610

    默认情况下,登录的用户名是 user ,密码则是项目启动时随机生成的字符串,可以从启动的控制台日志中看到默认密码。

    访问 /hello ,会看到spring security使用了默认登录页面,默认用户user,密码就是上面的,输入用户密码成功访问。

    SpringBoot 2整合SpringSecurity权限管理(一)SpringSecurity介绍及简单搭建_第1张图片

    当用户从浏览器发送请求访问 /hello 接口时,服务端会返回 302 响应码,让客户端重定向到 /login 页面,用户在 /login 页面登录,登陆成功之后,就会自动跳转到 /hello 接口。

    另外,也可以使用 POSTMAN 来发送请求,使用 POSTMAN 发送请求时,可以将用户信息放在请求头中(这样可以避免重定向到登录页面):

    SpringBoot 2整合SpringSecurity权限管理(一)SpringSecurity介绍及简单搭建_第2张图片

通过以上两种不同的登录方式,可以看出,Spring Security 支持两种不同的认证方式:

  • 可以通过 form 表单来认证
  • 可以通过 HttpBasic 来认证

二、自定义登录用户和密码

随机生成的密码,每次启动时都会变。对登录的用户名/密码进行配置,有三种不同的方式:

  • 在 application.properties 中进行配置
  • 通过 Java 代码配置在内存中
  • 通过 Java 从数据库中加载
  1. 直接在 application.properties 文件中配置用户的基本信息:

    ## Spring Security配置
    spring.security.user.name=admin
    spring.security.user.password=666666
    

    配置完成后,重启项目,就可以使用这里配置的用户名/密码登录了。

  2. 在 Java 代码中配置用户名密码,首先需要我们创建一个 Spring Security 的配置类,集成自 WebSecurityConfigurerAdapter 类,如下:

    @Slf4j
    @EnableWebSecurity //开启web security配置 这是一个组合注解
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        /**
         * spring5.0之后,spring security必须设置加密方法否则会报
         * There is no PasswordEncoder mapped for the id "null"
         * @return 加密
         */
        @Bean
        public BCryptPasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder(4);
        }
        
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests() //需要授权的请求
                    .anyRequest().authenticated() //对任何一个请求,都需要认证
                    .and() //完成上一个配置,进行下一步配置
                    .httpBasic(); //开启httpBasic登录
        }
    }
    

    从 Spring5 开始,强制要求密码要加密,如果非不想加密,可以使用一个过期的 PasswordEncoder 的实例 NoOpPasswordEncoder,但是不建议这么做,毕竟不安全。

  3. 配置AuthenticationManager

    有两种方式:

    (1) 重写configure(AuthenticationManagerBuilder auth)

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

    (2) 注入 configureGlobal(AuthenticationManagerBuilder auth)

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {}
    

    说明: configureGlobal可以跨多个WebSecurityConfigurerAdapter;configure只能只能作用一个!

    如果你的应用只有唯一一个WebSecurityConfigurerAdapter,那么他们之间的差距可以被忽略,从方法名可以看出两者的区别:使用@Autowired注入的AuthenticationManagerBuilder是全局的身份认证器,作用域可以跨越多个WebSecurityConfigurerAdapter,以及影响到基于Method的安全控制;而 protected configure()的方式则类似于一个匿名内部类,它的作用域局限于一个WebSecurityConfigurerAdapter内部。

    最后启动应用,输入admin,666666成功通过验证。

三、自定义登录页面和退出页面

  1. 配置WebMvcConfig

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/home").setViewName("home");
            registry.addViewController("/main").setViewName("main");
            registry.addViewController("/").setViewName("home");
            registry.addViewController("/hello").setViewName("hello");
            registry.addViewController("/login").setViewName("login");
            
        }
    

    当项目中涉及大量的页面跳转,我们可以使用addViewControllers方法实现无业务逻辑跳转,从而减少控制器代码的编写。

    addViewControllers方法可以实现将一个请求直接映射为视图,不需要编写控制器来实现,从而简化了页面跳转。

  2. 在SecurityConfig中配置HttpSecurity

     @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests() //需要授权的请求
                    .antMatchers("/login","/home").permitAll() //过滤不需要认证的路径
                    .anyRequest().authenticated() //对任何一个请求,都需要认证
                    .and() //完成上一个配置,进行下一步配置
                    //.httpBasic();
                    .formLogin() //配置表单登录
                    .loginPage("/login") //设置登录页面
                    .and()
                    .logout() //登出
                    .logoutSuccessUrl("/home"); //设置退出页面
        }
    
  3. 在resources下新建目录templates,新建几个页面

    SpringBoot 2整合SpringSecurity权限管理(一)SpringSecurity介绍及简单搭建_第3张图片

四、简单搭建完成,启动测试

SpringBoot 2整合SpringSecurity权限管理(一)SpringSecurity介绍及简单搭建_第4张图片

SpringBoot 2整合SpringSecurity权限管理(一)SpringSecurity介绍及简单搭建_第5张图片

PS 愿你一生努力,一生被爱,想要的都拥有,得不到的都释怀,更多干货,请来我的个人主页

你可能感兴趣的:(spring,boot,shiro,spring,java)