spring security核心功能

spring security核心功能

用户认证+用户授权

一,相关:

1.Shiro权限认证和登录框架

Apache旗下的轻量级权限控制框架

2.spring security权限认证和登录框架

和spring无缝整合 全面的权限控制 专门为web开发而设计 旧版本不能脱离web环境使用 新版本对整个框架进行了分层抽取,分成了核心模块和web模块。单独引入核心模块就可以脱离web环境 重量级

二,spring security最重要的两个接口

1.UserDetailsService接口

查询数据库用户名和密码过程

*创建类继承UsernamePasswordAuthenticationFilter,重写三个方法

*创建实现类UserDetailService,编写查询数据过程,返回User对象,这个User对象是安全框架提供对象

2.PasswordEncoder接口

数据加密接口,用于返回User对象里面密码加密

三,设置登录的用户名和密码

1.通过配置文件

#   配置端口
server.port=8111
#   配置用户名
spring.security.user.name=atguigu
#   配置用户密码
spring.security.user.password=atguigu

2.通过配置类

package com.example.config;
​
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
​
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    /**
     * @param auth
​
     * @description :重写方法,设置用户名和密码
     * @date : 2023/2/27 10:27
     * @author : 09zhj
     * @since : JDK 1.8
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
//        加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//        调用方法进行加密
        String password = passwordEncoder.encode("123");
//        设置用户名和密码
  auth.inMemoryAuthentication().withUser("lucy").password(password).roles("admin");
    }
//        创建加密接口对象
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}

3.自定义编写实现类设置

3.1第一步 创建配置类,设置使用哪个UserDetailsService实现类

package com.example.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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
​
/**
 * @author : 09zhj
 * @description :自定义编写实现类设置用户名和密码
 * @date : 2023/2/27 12:59
 * @since : JDK 1.8
 */
@Configuration
public class SecurityConfigDemo extends WebSecurityConfigurerAdapter {
​
    @Autowired
    private UserDetailsService userDetailsService;
​
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
    //        创建加密接口对象
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}

3.2第二步 编写实现类,返回User对象,User对象有用户名密码和操作权限

package com.example.service;
​
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 {
​
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        return new User("mary",
                new BCryptPasswordEncoder().encode("123"),auths);
    }
}

四,查询数据库完成用户认证

1.整合MyBatisPlus完成数据库操作

1.1 第一步,引入相关依赖

<!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
<!--mysql数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
<!--lombok小辣椒-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

1.2 第二步,创建数据库和数据库表

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `username` varchar(255) DEFAULT NULL COMMENT '用户名',
  `password` varchar(255) DEFAULT NULL COMMENT '用户密码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1.3 第三步,创建表对应的实体类

package com.example.entity;
​
import lombok.Data;
​
@Data
public class Users {
    private Integer id;
    private String username;
    private String password;
​
}

1.4 第四步,整合mp,创建接口,继承mp的接口

public interface UsersMapper extends BaseMapper<Users> {
​
}

1.5 第五步,在MyUserDetailsService调用mapper里面的方法查询数据库进行用户认证

package com.example.service;
​
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.entity.Users;
import com.example.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 {
    @Autowired
    private UsersMapper usersMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        调用usersMapper方法查询数据库,根据用户名查询数据库
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
//        where username=?
        wrapper.eq("username",username);
        Users users = usersMapper.selectOne(wrapper);
//        判断进if,数据库没有用户名,认证失败
        if (users == null){
            throw new UsernameNotFoundException("用户名不存在!");
        }
        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("role");
//       从查询数据库返回users对象,得到用户名和密码,返回
        return new User(users.getUsername(),
                new BCryptPasswordEncoder().encode(users.getPassword()),auths);
    }
}

1.6 第六步,启动类加注解

package com.example;
​
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
​
@SpringBootApplication
@MapperScan("com.example.mapper")
public class SpringbootSecurityApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(SpringbootSecurityApplication.class, args);
    }
​
}

1.7 第七步,配置数据库信息

#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db1?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456

五,自定义设置登录页面(不需要认证可以访问)

1.在配置类中实现相关的配置

package com.example.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;
​
/**
 * @author : 09zhj
 * @description :自定义编写实现类设置用户名和密码
 * @date : 2023/2/27 12:59
 * @since : JDK 1.8
 */
@Configuration
public class SecurityConfigDemo extends WebSecurityConfigurerAdapter {
​
    @Autowired
    private UserDetailsService userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
    //        创建加密接口对象
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
​
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin() //自定义自己编写的登陆页面
                .loginPage("/login.html") //登录页面设置
                .loginProcessingUrl("/user/login") //登录访问路径
                .defaultSuccessUrl("/test/index").permitAll() //登录成功之后,跳转路径
                .and().authorizeRequests()
                    .antMatchers("/","/test/hello","/user/login").permitAll() //设置哪些路径可以直接访问,不需要认证
                .anyRequest().authenticated()
                .and().csrf().disable(); //关闭csrf防护
    }
}

1.1 html5

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <form action="/user/login" method="post">
      用户名:<input type="text" name="username"/>
    <br/>
      密码:<input type="text" name="password"/>
    <br/>
    <input type="submit" value="login"/>
  </form>
</body>
</html>

六,基于角色或权限进行访问控制

1.hasAuthority方法

如果当前的主题具有指定的权限,则返回true,否则返回false

1.1在配置类设置当前访问地址有哪些权限

//             当前登录用户,只有具有admins权限才可以访问这个路径 --"/test/index"
                .antMatchers("/test/index").hasAuthority("admins")

1.2在UserDetailsService,把返回User对象设置权限

        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("admins");

2.hasAnyAuthority方法

1.1在配置类设置当前访问地址有哪些权限

//hasAnyAuthority多个权限  
.antMatchers("/test/index").hasAnyAuthority("admins,manager")

1.2在UserDetailsService,把返回User对象设置权限

        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("admins");

3.hasRole方法

1.1在配置类设置当前访问地址有哪些权限

//                 3.hasRole方法
                .antMatchers("/test/index").hasRole("sale")

1.2在UserDetailsService,把返回User对象设置权限

       //这里要注意看看源码格式,有没有加前缀
       List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("admins,sale");

4.hasAnyRole方法

猜你喜欢

转载自blog.csdn.net/weixin_70855192/article/details/130802088