Spring Security

1. 简介

Spring Security是Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。

一般来说中大型的项目都是使用SpringSecurity来做安全框架,小项目用Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。

一般Web应用都需要进行认证授权

认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户

授权:经过认证后判断当前用户是否有权限进行某个操作

  • 功能权限
  • 访问权限
  • 菜单权限
  • ..拦截器、过滤器:大量原生代码~

认证和授权是SpringSecurityf作为安全框架的核心功能。

先认识几个类,有个印象:

  • WebSecurityConfigurerAdapter:自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式

2. 快速入门

1.1 准备工作

  • 首先搭建一个简单的SpringBoot工程

    • 设置父工程,添加依赖

      <parent>
          <version>2.7.4</version>
          <artifactId>spring-boot-starter-parent</artifactId>
          <groupId>org.springframework.boot</groupId>
      </parent>
      
      <dependencies>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
      
    • 创建启动类

      @SpringBootApplication
      public class SecurityApplication {
          public static void main(String[] args) {
              SpringApplication.run(SecurityApplication.class,args);
          }
      }
      
    • 创建Controller

      package com.mark.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * @ClassName HelloController
       * @Description TODO
       * @Author Mark
       * @Date 2022/9/28 20:11
       * @Version 1.0
       */
      @Controller
      public class RouterController {
          @RequestMapping({"/", "/index"})
          public String index() {
              return "index";
          }
      
          @RequestMapping("/toLogin")
          public String toLogin() {
              return "views/login";
          }
      
          @RequestMapping("/level1/{id}")
          public String level1(@PathVariable("id") int id) {
              return "views/level1/" + id;
          }
      
          @RequestMapping("/level2/{id}")
          public String level2(@PathVariable("id") int id) {
              return "views/level2/" + id;
          }
      
          @RequestMapping("/level3/{id}")
          public String level3(@PathVariable("id") int id) {
              return "views/level3/" + id;
          }
      }
      
      

1.2 初识SpringSecurity

  • 导包:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
  • 配置类Security Java Configuration:

    @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 {
        	...
      	}
    }
    
  • 自定义Security授权策略:

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //链式编程
          	//首页所有人可以访问,功能页只有有权限的人才能访问
          	//请求授权的规则
            http.authorizeRequests()
              	.antMatchers("/").permitAll()
              	//只有vip1用户可访问/level1/**
                .antMatchers("/level1/**").hasRole("vip1")
              	//只有vip2用户可访问/level2/**
                 .antMatchers("/level2/**").hasRole("vip2")
              	//只有vip3用户可访问/level3/**
                 .antMatchers("/level3/**").hasRole("vip3");
          	//没有权限默认跳转到登录页面:/login
            //http.formLogin();
            //登录页面跳转到/toLogin
            http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login");
        }
    }
    

    authorizeRequests():认证请求

    antMatchers():添加地址

    permitAll():所有人都可访问

    hasRole():只有xx用户可访问

    loginProcessingUrl默认的用户名和密码为username和password,若前端字段非username和password,则接受不到数据,因此需添加以下方法实现对应字段接收:

    http.formLogin().loginPage("/toLogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login");

  • 自定义认证策略:

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //认证,SpringBoot 2.1.x 可以直接使用
        //jdbc认证:auth.jdbcAuthentication()
        //从内存中认证,正常应该从数据库中读取
        auth.inMemoryAuthentication()
          	.withUser("Mark").password("123456").roles("vip1","vip2")
          	.and()
            .withUser("root").password("123456").roles("vip1","vip2","vip3")
            .and()
            .withUser("Java").password("123456").roles("vip1");
         
    }
    

    withUser():添加用户名为xx的用户

    password():设置密码

    roles("vip1","vip2","vip3"):设置用户权限类别

    • SpringBoot 2.1.x 可以直接使用,在SpringSecurity 5.0+中,新增了很多加密方式,不能使用明文密码,要使用密码编码:PasswordEncoder

      auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                      .withUser("Mark").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                      .and()
                      .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                      .and()
                      .withUser("Java").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
      

1.3 注销

  1. 在configure(HttpSecurity http)中添加http.logout();即可。访问的是/logout端口

  2. logout的其他功能

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        http.formLogin();
      
      	//防止网站攻击
        //关闭防止跨站请求的功能,登录失败可能存在的原因
        http.csrf().disable();
    
        //开启注销功能:/logout
        http.logout()
                //清空所有的cookie和session
                .deleteCookies("remove").invalidateHttpSession(true);
                //注销后跳转到首页
                .logoutSuccessUrl("/");
    }
    

1.4 记住登录状态功能开启

  • 在configure(HttpSecurity http)中添加http.rememberMe();即可

    • 会保存cookie,默认保存两周
  • 接收前端记住登陆状态按钮name参数:

    http.rememberMe().rememberMeParameter("remember");

posted @   风吹头蛋凉OvO  阅读(116)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示