Spring Security

1.Spring Security框架简介

Spring 是非常流行和成功的 Java 应用开发框架,Spring Security 正是 Spring 家族中的 成员。Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方 案。

正如你可能知道的关于安全方面的两个主要区域是“认证”和“授权”(或者访问控 制),一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权 (Authorization)两个部分,这两点也是 Spring Security 重要核心功能。

(1)用户认证指的是:验证某个用户是否为系统中的合法主体,也就是说用户能否访问 该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认 证过程。通俗点说就是系统认为用户是否能登录

(2)用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户 所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以 进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的 权限。通俗点讲就是系统判断用户是否有权限去做某些事情。

2.开始SpringSecurity入门案例

2.1.创建项目

首先创建一个SpringBoot项目

 

 选择我们项目所需要的两个组件,在创建项目的时候会自动在pom文件中加入相关的依赖,不需要我们手动去添加依赖

 直接点击Fish创建项目

 打开pom文件可以发现SpringWeb和SpringSecurity的相关依赖已经自动添加进去了

 

 2.2、编写项目

在com.hopu路径下创建controller文件夹,创建TestController.java 文件,编写以下代码,接收浏览器发送的hello请求,返回hello,Spring Security!

@RestController
public class TesrController {
    @RequestMapping("/hello")
    public String hello(){
        return "hello,Spring Security!";
    }
}

为了防止端口号有冲突,在application.properties配置文件中将端口号更改为8888

#更改端口号为8888
server.port=8888

打开DemoApplication运行main方法,在浏览器输入localhost:8888/hello。访问得到的页面没有返回hello,Spring Security!而是出现了登录表单,这证明Security已经整合进去了,这是其自带的表单样式

用户名默认为user

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

 输入用户名和密码就可以访问了

 这样一个入门案例就写好了,我们会发现用户名被定死了,密码是控制台随机生成很不方便,对于我们的使用不够友好,下面我们就来讲解一下怎么去更改用户名和密码

3.设置登录的用户名和密码

3.1、方式一:通过application.properties

通过配置文件设置用户名和密码

spring.security.user.name=atguigu
spring.security.user.password=atguigu

3.2、方式二:通过配置类

开始前将之前通过方式一设置的用户名和密码注释掉

在com.hopu包下创建一个config包,创建一个名叫SecurityConfig的配置类

  •  在类上面加一个注解@Configuration
  • SecurityConfig类继承Security中提供的一个WebSecurityConfigurerAdapter类
  • 重写config方法;
@Configuration
public class  SecurityConfig extends WebSecurityConfigurerAdapter {
    //重写config方法
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //使用PasswordEncoder接口中的方法将密码加密
        BCryptPasswordEncoder passwordEncoder =new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123456");
        //使用auth来设置用户名和密码,roles里表示用户身份
        auth.inMemoryAuthentication().withUser("Lucy").password(password).roles("admin");
    }
    //因为加密密码默认使用PasswordEncoder接口,需要创建它的一个对象
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}

第三种方式自定义实现类设置

将之前的写的SecurityConfig配置类注释掉,方便对比

第一步创建配置类

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

package com.hopu.config;

import org.springframework.beans.factory.annotation.Autowired;
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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
    //注入UserDetailsService 实现类
    @Autowired
    private UserDetailsService userDetailsService;
    //重写config方法
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
    //因为加密密码默认使用PasswordEncoder接口,需要创建它的一个对象
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }

第二步编写实现类

在com.hopu包下创建service包,在service包下创建MyUserDetailsService实现类

 编写代码

  • 使用@Service注解将userDetailsService注入到这个实现类上
package com.hopu.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hopu.entity.Users;
import com.hopu.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    //由于权限是一个集合,所以用集合写权限
     List<GrantedAuthority> auths=                     
                  AuthorityUtils.commaSeparatedStringToAuthorityList("a1");
//User是security里的包,不是实现类
//第一个值是用户名,第二个值是密码,第三个值是权限,不能为空
return new User("lucy",newBCryptPasswordEncoder().encode("123"),auths);

后面进行测试

第四种方式

第一步创建数据库

创建数据库demo,并创建users表(表名需要跟后面调用的对象名相同,不然无法正常调用数据库中的数据)并添加数据

第二步:引入相关依赖

在pom中引入mybatis-plus和mysql的依赖,这两个依赖必须引入,lombok依赖可以不引入,不引入我们也可以靠代码实现它的功能,但是lombok可以简化代码

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3.3</version>
</dependency>
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
 </dependency>

第一次使用lombok需要手动下载其相关组件

由于我已经下好了lombok所以我这里没有下载按钮,没有下载的在箭头指向的位置会有按钮

 

第三步:编写实体类

  • 在com.hopu包下创建entity包,创建Users实体类,
  • 编写USers实体类,返回Users对象,Users对象有用户名密码和从操作权限
package com.hopu.entity;

import lombok.Data;

@Data
public class Users {
        private Integer id;
        private String username;
        private String password;
        private String authority;
}

@Data注释是lombok组件里的,自动生成get set等方法

第四步:整合mybatis-plus,创建接口,继承mybatis-plus

创建mapper包,在这个包下创建名为UsersMapper的接口

  • 让这个接口继承mybatis-plus中的BaseMapper接口,<>中加上泛型,就是实体类Users
  • BaseMapper接口里封装了针对数据库的增删改查的操作
  • 我们只需要继承BaseMapper接口,调用其中的方法就能做到增删改查的功能 
package com.hopu.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hopu.entity.Users;
import org.springframework.stereotype.Repository;

public interface UsersMapper extends BaseMapper<Users> {

}

 第五步:在MyUserDetailsService中调用mapper方法查询数据库进行认证

  • 将UsersMapper注入MyUserDetailsService中
  • 注入后发现usersMapper报错了,这是因为UsersMapper是接口,所以我们在UsersMapper的类上加上一个注解@Repository

 

  •  使用mybatis-plus中的构造器QueryWrapper查询数据库
  • 使用Users users=usersMapper.selectOne(wrapper);查询数据库得到一条记录
  • 将写死的用户名和密码改为从数据库中获取的用户名和密码
package com.hopu.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hopu.entity.Users;
import com.hopu.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    //注入UsersMapper 
    @Autowired
    private UsersMapper usersMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        Users users=usersMapper.selectOne(wrapper);
        if (users==null){
            throw  new UsernameNotFoundException("用户不存在");
        }

        List<GrantedAuthority> auths= AuthorityUtils.commaSeparatedStringToAuthorityList(users.getAuthority());
        return new User(users.getUsername(),new BCryptPasswordEncoder().encode(users.getPassword()),auths);
    }
}

最后进行测试即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值