2.1 创建一个项目

03-入门案例.png

image.png
image.png


引入相关依赖

pom文件中添加如下依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-security</artifactId>
  8. </dependency>

添加一个配置类:

@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.formLogin() // 表单登录 
        .and() 
        .authorizeRequests() // 认证配置 
        .anyRequest() // 任何请求 
        .authenticated(); // 都需要身份验证 
    }
}

2.2 运行这个项目

访问 localhost:8080
image.png

默认的用户名:user

密码在项目启动的时候在控制台会打印,注意每次启动的时候密码都回发生变化!
image.png

输入用户名,密码,这样表示可以访问了,404 表示我们没有这个控制器,但是我们可以 访问了。

image.png

2.3 权限管理中的相关概念


2.3.1 主体

英文单词:principal

使用系统的用户或设备或从其他系统远程登录的用户等等。简单说就是谁使用系 统谁就是主体。

2.3.2 认证

英文单词:authentication

权限管理系统确认一个主体的身份,允许主体进入系统。简单说就是“主体”证 明自己是谁。

笼统的认为就是以前所做的登录操作。

2.3.3 授权

英文单词:authorization

将操作系统的“权力”“授予”“主体”,这样主体就具备了操作系统中特定功能的能力。

所以简单来说,授权就是给用户分配权限。

2.4 添加一个控制器进行访问


package com.atguigu.controller; 
@Controller 
public class IndexController { 
    @GetMapping("index") 
    @ResponseBody 
    public String index(){ 
            return "success"; 
    } 
}

image.png

2.5 SpringSecurity 基本原理

02-SpringSecurity基本原理.png

SpringSecurity 本质是一个过滤器链:

从启动是可以获取到过滤器链:

org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter org.springframework.security.web.context.SecurityContextPersistenceFilter org.springframework.security.web.header.HeaderWriterFilter org.springframework.security.web.csrf.CsrfFilter org.springframework.security.web.authentication.logout.LogoutFilter org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter org.springframework.security.web.savedrequest.RequestCacheAwareFilter org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter org.springframework.security.web.authentication.AnonymousAuthenticationFilter org.springframework.security.web.session.SessionManagementFilter org.springframework.security.web.access.ExceptionTranslationFilter org.springframework.security.web.access.intercept.FilterSecurityInterceptor

代码底层流程:重点看三个过滤器:
FilterSecurityInterceptor:是一个方法级的权限过滤器, 基本位于过滤链的最底部。
image.png
super.beforeInvocation(fi) 表示查看之前的 filter 是否通过。

fi.getChain().doFilter(fi.getRequest(), fi.getResponse());表示真正的调用后台的服务。

ExceptionTranslationFilter:是个异常过滤器,用来处理在认证授权过程中抛出的异常
image.png

UsernamePasswordAuthenticationFilter :对/login 的 POST 请求做拦截,校验表单中用户 名,密码。

image.png

2.6 UserDetailsService 接口讲解

当什么也没有配置的时候,账号和密码是由 Spring Security 定义生成的。而在实际项目中 账号和密码都是从数据库中查询出来的。 所以我们要通过自定义逻辑控制认证逻辑。

如果需要自定义逻辑时,只需要实现 UserDetailsService 接口即可。接口定义如下:

image.png

  • 返回值 UserDetails

这个类是系统默认的用户“主体

// 表示获取登录用户所有权限 Collection<? extends GrantedAuthority> getAuthorities(); // 表示获取密码 String getPassword(); // 表示获取用户名 String getUsername(); // 表示判断账户是否过期 boolean isAccountNonExpired(); // 表示判断账户是否被锁定 boolean isAccountNonLocked(); // 表示凭证{密码}是否过期 boolean isCredentialsNonExpired(); // 表示当前用户是否可用 boolean isEnabled();

以下是 UserDetails 实现类
image.png

以后我们只需要使用 User 这个实体类即可!

image.png

  • 方法参数 username

表示用户名。此值是客户端表单传递过来的数据。默认情况下必须叫 username,否则无法接收。

2.7 PasswordEncoder 接口讲解


// 表示把参数按照特定的解析规则进行解析 
String encode(CharSequence rawPassword); 
// 表示验证从存储中获取的编码密码与编码后提交的原始密码是否匹配。如果密码匹 配,则返回 true;如果不匹配,则返回 false。第一个参数表示需要被解析的密码。第二个 参数表示存储的密码。 
boolean matches(CharSequence rawPassword, String encodedPassword); 
// 表示如果解析的密码能够再次进行解析且达到更安全的结果则返回true,否则返回 false。默认返回 false。 
default boolean upgradeEncoding(String encodedPassword) { 
    return false; 
}

image.png

接口实现类BCryptPasswordEncoder 是 Spring Security 官方推荐的密码解析器,平时多使用这个解析器。

BCryptPasswordEncoder 是对 bcrypt 强散列方法的具体实现。是基于 Hash 算法实现的单 向加密。可以通过 strength 控制加密强度,默认 10.

  • 查用方法演示
@Test 
public void test01(){ 
    // 创建密码解析器 
    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); 
    // 对密码进行加密 
    String atguigu = bCryptPasswordEncoder.encode("atguigu"); 
    // 打印加密之后的数据 
    System.out.println("加密之后数据:\t"+atguigu); 
    //判断原字符加密后和加密之前是否匹配 
    boolean result = bCryptPasswordEncoder.matches("atguigu", atguigu); 
    // 打印比较结果 
    System.out.println("比较结果:\t"+result); 
}


2.8 SpringBoot 对 Security 的自动配置

https://docs.spring.io/springsecurity/site/docs/5.3.4.RELEASE/reference/html5/#servlet-hello