Spring Security (一) --------- Spring Security 入门


一、Spring Security 简介

Spring Security 是基于 Spring 的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权。在 Spring Framework 基础上,Spring Security 充分利用了 依赖注入 (DI) 和面向切面编程 (AOP) 功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。是一个轻量级的安全框架。它与 Spring MVC 有很好地集成。

Spring Security 核心功能

  • 认证 (你是谁,用户/设备/系统 )
  • 验证 (你能干什么,也叫权限控制/授权,允许执行的操作)

Spring Security 原理

基于 Filter、Servlet、AOP 实现身份认证和权限验证

二、入门案例

1. 案例一

初探

A、创建 Maven 项目

B、加入 SpringBoot 与 SpringSecurity 依赖

<!--加入 spring boot -->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-parent</artifactId>
	<version>2.0.6.RELEASE</version>
</parent>
<!--web 开发相关依赖-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring security-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

C、创建应用启动类

public class FirstApplication {
	public static void main(String[] args) {
		SpringApplication.run(FirstApplication.class,args);
	}
}

D、创建 Controller,接收请求

@RestController
public class HelloSecurityController {
    @RequestMapping("/hello")
    public String sayHello() {
        return "Hello SpringSecurity";
    }
}      

E、框架生成的用户

用户名: user

密码: 在启动项目时,生成的临时密码,uuid

日志中生成的密码:

generated security password: 9717464c-fafd-47b3-9995-2c18b24f7336

F、自定义用户名和密码

需要在 SpringBoot 配置文件中设置登录的用户名和密码。

在 resource 目录下面创建 SpringBoot 配置文件 application.yml(application.properties)

spring:
  security:
     user:
        name: fancy
        password: aszhuo123

name: 自定义用户名称
password: 自定义密码

G、关闭验证

//排除 Secuirty 的配置,让他不启用
@SpringBootApplication(exclude={SecurityAutoConfiguration.class})
public class FirstApplication {}

2. 案例二

使用内存中的用户信息

使用 WebSecurityConfigurerAdapter 控制安全管理的内容。

如何使用:

继承 WebSecurityConfigurerAdapter,重写方法。实现自定义的认证信息。重写下面的方法。

protected void configure(AuthenticationManagerBuilder auth)

Spring Security 5 版本要求密码比较加密,否则报错

java.lang.IllegalArgumentException: There is no PasswordEncodermapped for the id "null"

实现密码加密

A、创建用来加密的实现类,选择一种加密算法

@Bean
public PasswordEncoder passwordEncoder() {
    // 创建 PasswordEncoder 的实现类,实现类是加密算法
    return new BCryptPasswordEncoder();
}

给每个密码加密

PasswordEncoder pe  = passwordEncoder();
pe.encode("123456");

完整代码

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @EnableGlobalMethodSecurity:启用方法级别的认证
 *      prePostEnabled:boolean 默认是false
 *          true:表示可以使用@PreAuthorize注解 和 @PostAuthorize
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    //在方法中配置 用户和密码的信息, 作为登录的数据
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        PasswordEncoder pe = passwordEncoder();

        //定义两个角色 normal, admin
        auth.inMemoryAuthentication()
                .withUser("zhangsan")
                .password(pe.encode("123456"))
                .roles("normal");

        auth.inMemoryAuthentication()
                .withUser("lisi")
                .password(pe.encode("123456"))
                .roles("normal");
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password(pe.encode("admin"))
                .roles("admin","normal");

    }

    //创建密码的加密类
    @Bean
    public PasswordEncoder passwordEncoder(){
        //创建PasawordEncoder的实现类, 实现类是加密算法
        return new BCryptPasswordEncoder();
    }

}

注解:

@Configuration :表示当前类是一个配置类( 相当于是 spring 的 xml 配置文件),在这个类方法的返回值是 Java 对象,这些对象放入到 Spring 容器中。

@EnableWebSecurity :表示启用 Spring Security 安全框架的功能

@Bean :把方法返回值的对象,放入到 Spring 容器中

3. 案例三

基于角色 Role 的身份认证, 同一个用户可以有不同的角色。同时可以开启对方法级别的认证。

步骤:

A、设置用户的角色

继承 WebSecurityConfigurerAdapter

重写 configure 方法,指定用户的 roles

auth.inMemoryAuthentication()
           .withUser("admin")
           .password(pe.encode("admin"))
           .roles("admin", "normal");

B、在类的上面加入启用方法级别的注解

@EnableGlobalMethodSecurity(prePostEnabled = true

C、在处理器方法的上面加入角色的信息

指定方法可以访问的角色列表

@RequestMapping("/helloUser")
@PreAuthorize(value = "hasAnyRole('admin', 'normal')")
public String helloCommonUser() {
    return "Hello 拥有normal、admin 角色的用户"
}

使用 @PreAuthorize 指定在方法之前进行角色的认证

hasAnyRole('角色名称1', ... '角色名称N')

4. 案例四

从数据库 mysql 中获取用户的身份信息 (用户名称,密码,角色)

A、在 Spring Security 框架对象用户信息的表示类是 UserDetails。

UserDetails 是一个接口,高度抽象的用户信息类(相当于项目中的User 类)

User 类:是 UserDetails 接口的实现类, 构造方法有三个参数:username,password, authorities

需要向 spring security 提供 User 对象, 这个对象的数据来自数据库的查询。

B、实现 UserDetailsService 接口

重写方法 UserDetails loadUserByUsername(String var1) 在方法中获取数据库中的用户信息, 也就是执行数据库的查询,条件是用户名称。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在森林中麋了鹿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值