springboot+springsecurity+mysql数据库认证和授权

首先是依赖
springboot是2.1.9 springsecurity是5.1.6

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.song</groupId>
    <artifactId>springsecuritydemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springsecuritydemo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.20</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

配置文件
主要是配置数据源信息和指定*Mapper.xml文件的配置

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/springsecuritydemo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=qjfy
mybatis.mapper-locations=classpath:/mapper/*.xml

数据库
有三张表 分别是role、user、user_role
用户表
springboot+springsecurity+mysql数据库认证和授权_第1张图片
实体类
springsecurity要求创建的user类实现UserDetails类并重写其中的方法

User.java

public class User implements UserDetails {

    private Integer id;
    private String username;
    private String password;
    private boolean enabled;
    private boolean locked;
    private List<Role> roles;

	//将该用户的角色信息存入这个集合中
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> list = new ArrayList<>();
        for (Role role : roles) {
            list.add(new SimpleGrantedAuthority(role.getName()));
        }
        return list;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }
	//判断账户是否没有过期
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
  	//判断账户是否没有被锁
    @Override
    public boolean isAccountNonLocked() {
        return !locked;
    }
	//判断当前账户密码是否没有过期
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
	//判断当前账户是否可用
    @Override
    public boolean isEnabled() {
        return enabled;
    }
//省略getter和setter方法

Role.java

@Data
public class Role {
    private Integer id;
    private String name;
    private String nameZh;
}

springsecurity要求创建的UserService需要实现UserDetailsService并实现其中的loadUserByUsername方法。

UserService.java

@Service("userService")
public class UserServiceImpl implements UserDetailsService {

    @Autowired
    UserMapper userMapper;
	//通过查询数据库加载登陆用户的信息,在用户登陆时自动调用
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    	//加载用户信息
        User user = userMapper.loadUserByUsername(s);
        if(user == null){
            throw new UsernameNotFoundException("账户不存在");
        }
        //通过用户id在数据库中查询该用户的所有角色信息,并存入user对象中
        user.setRoles(userMapper.getRolesByUserId(user.getId()));
        //返回的user对象会由后续的DaoAuthenticationProvider类去对比登陆的密码是否正确
        return user;
    }
}

UserMapper.java 和 UserMapper.xml

@Repository("userMapper")
public interface UserMapper {

    User loadUserByUsername(String s);

    List<Role> getRolesByUserId(Integer id);
}

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.song.springsecuritydemo.mapper.UserMapper">
    <select id="loadUserByUsername" resultType="com.song.springsecuritydemo.pojo.User">
        select * from user where username=#{username};
    </select>

    <select id="getRolesByUserId" resultType="com.song.springsecuritydemo.pojo.Role">
        select * from role r ,user_role ur where r.id=ur.rid and ur.uid=#{id};
    </select>
</mapper>

配置springsecurity
springsecurity 5.x以后,不需要开发者指定加密方式,在数据库中存储密码的时候指定加密方式即可:({bcrypt}$2a 10 10 10IJiwCaDbDpWgLcFD/G1Dd.DUAAZXIL99kaa3Op1zS4pvypPe4Ft/6),并按如下passwordEncoder()方法即可。PasswordEncoderFactorids这个类中集成了很多的加密方式,在对比密码时根据密码前的加密方式id再选择对应的加密方法对象。如果在数据库中没有指定id,就会报错:There is no PasswordEncoder mapped for the id “null”。

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserServiceImpl userService;
	
	//密码加密
    @Bean
    PasswordEncoder passwordEncoder(){
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
	//指定UserService
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }
	//基于Url的授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/db/**").hasRole("dba")
                .antMatchers("/user/**").hasRole("user")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login").permitAll()
                .and()
                .csrf().disable();
    }
}

授权方式除了url授权还有基于注解方式的授权。在springsecurity的配置类上加注解:@EnableGlobalMethodSecurity。在service的方法上加上@Secured或@preAuthorize注解并配置权限即可。
最后创建controller就可以验证认证授权了。

你可能感兴趣的:(springboot+springsecurity+mysql数据库认证和授权)