之前使用的全是基于内存的认证,这里使用基于数据库的认证。
设计数据表
这里设计数据表
创建项目
添加如下依赖
添加driud连接池依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency>
完整的pom如下
<?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.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> ? <properties> <java.version>1.8</java.version> </properties> ? <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</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.3</version> </dependency> ? <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </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>
配置数据库
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource username: root password: ABCcba20170607 url: jdbc:mysql://cdb-1yfd1mlm.cd.tencentcdb.com:10056/test
创建对应的实体类
package com.example.demo.domain; ? import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; ? import java.util.ArrayList; import java.util.Collection; import java.util.List; ? 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 // 实体类和SpringSecurity转换 public Collection<? extends GrantedAuthority> getAuthorities() { List<SimpleGrantedAuthority> authorities = new ArrayList<>(); for (Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getName())); } return authorities; } ? @Override public String getPassword() { return null; } ? @Override public String getUsername() { return null; } ? @Override public boolean isAccountNonExpired() { return false; } ? @Override public boolean isAccountNonLocked() { return false; } ? @Override public boolean isCredentialsNonExpired() { return false; } ? @Override public boolean isEnabled() { return false; } ? public Integer getId() { return id; } ? public void setId(Integer id) { this.id = id; } ? public void setUsername(String username) { this.username = username; } ? public void setPassword(String password) { this.password = password; } ? public Boolean getEnabled() { return enabled; } ? public void setEnabled(Boolean enabled) { this.enabled = enabled; } ? public Boolean getLocked() { return locked; } ? public void setLocked(Boolean locked) { this.locked = locked; } ? public List<Role> getRoles() { return roles; } ? public void setRoles(List<Role> roles) { this.roles = roles; } } package com.example.demo.domain; ? public class Role { private Integer id; private String name; private String nameZh; ? public Integer getId() { return id; } ? public void setId(Integer id) { this.id = id; } ? public String getName() { return name; } ? public void setName(String name) { this.name = name; } ? public String getNameZh() { return nameZh; } ? public void setNameZh(String nameZh) { this.nameZh = nameZh; } }
创建UserService
package com.example.demo.mapper; ? import com.example.demo.domain.Role; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.graalvm.compiler.nodeinfo.StructuralInput; import org.springframework.security.core.userdetails.User; ? import java.util.List; ? @Mapper public interface UserMapper { @Select("select * from user where username=#{username}") public User loadUserByUsername(String username); ? @Select("select * from role r, user_role ur where r.id = ur.rid and ur.uid = #{id}") public List<Role> getUserRoleByUid(Integer id); }
配置Spring Security
package com.example.demo.config; ? import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.Bean; 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.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; ? ? @Configurable public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; ? @Bean PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } ? @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService); } ? @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("admin") .anyRequest().authenticated() .and() .formLogin() .loginProcessingUrl("/login").permitAll() .and() .csrf().disable(); } }
至此完成。