導(dǎo)入依賴(lài)
<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.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
數(shù)據(jù)庫(kù)腳本
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`nameEN` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色英文名稱(chēng)',
`nameZh` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色中文名稱(chēng)',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `role` VALUES (1, 'ROLE_dba', '數(shù)據(jù)庫(kù)管理員');
INSERT INTO `role` VALUES (2, 'ROLE_admin', '系統(tǒng)管理員');
INSERT INTO `role` VALUES (3, 'ROLE_user', '用戶(hù)');
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用戶(hù)名',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用戶(hù)密碼',
`enabled` tinyint(1) DEFAULT NULL COMMENT '是否啟用',
`locked` tinyint(1) DEFAULT NULL COMMENT '是否被鎖定',
`expired` tinyint(1) DEFAULT NULL COMMENT '賬戶(hù)是否過(guò)期',
`credentialsExpire` tinyint(1) DEFAULT NULL COMMENT '憑據(jù)是否過(guò)期',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `user` VALUES (1, 'root', '$2a$10$Ch8lK9.urrzsihbr3y9.ruEeWFe0s35JabDkhZt12q.x2bmrIAK7S', 1, 0, 0, 0);
INSERT INTO `user` VALUES (2, 'admin', '$2a$10$NhYY27nG1V8LW4qLW5jfje/MwYpU/f6inh7X5rt/KJmJ1/tSUI9Nm', 1, 0, 0, 0);
INSERT INTO `user` VALUES (3, 'gong', '$2a$10$Z.YoIEK/Y1LTKOBBcI0U8Os/3nwe3gYsbRjoJnAiNIqbygIalYw2O', 1, 0, 0, 0);
CREATE TABLE `user_role` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`uid` int(11) DEFAULT NULL COMMENT '用戶(hù)id',
`rid` int(11) DEFAULT NULL COMMENT '角色id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `user_role` VALUES (1, 1, 1);
INSERT INTO `user_role` VALUES (2, 1, 2);
INSERT INTO `user_role` VALUES (3, 2, 2);
INSERT INTO `user_role` VALUES (4, 3, 3);
密碼明文都為123。
在yml中配置連接地址(我在pom中將mysql版本修改為了5.1.47)
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/gongj?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false
username: root
password: 980402
driver-class-name: com.mysql.jdbc.Driver
環(huán)境搭建完成。
實(shí)體類(lèi)
User
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class User implements UserDetails{
private Integer id;
private String username;
private String password;
private Boolean enabled;
private Boolean locked;
private Boolean expired;
private Boolean credentialsExpire;
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public void setExpired(Boolean expired) {
this.expired = expired;
}
public void setCredentialsExpire(Boolean credentialsExpire) {
this.credentialsExpire = credentialsExpire;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() { //返回用戶(hù)的所有角色
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getNameEN()));
}
return authorities;
}
@Override
public boolean isAccountNonExpired() { //賬戶(hù)是否未過(guò)期
return expired;
}
@Override
public boolean isAccountNonLocked() { //賬戶(hù)是否未鎖定
return locked;
}
@Override
public boolean isCredentialsNonExpired() { //憑證是否未過(guò)期
return credentialsExpire;
}
@Override
public boolean isEnabled() { //賬戶(hù)是否可用
return enabled;
}
}
在User中實(shí)現(xiàn)了Security中的UserDetails接口,重寫(xiě)了幾個(gè)方法。并將enabled、locked、expired、credentialsExpire的get方法刪除,isEnabled、
isAccountNonLocked、isAccountNonExpired、isCredentialsNonExpired這幾個(gè)方法取而代之。
Role
public class Role {
private Integer id;
private String nameEN;
private String nameZh;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNameEN() {
return nameEN;
}
public void setNameEN(String nameEN) {
this.nameEN = nameEN;
}
public String getNameZh() {
return nameZh;
}
public void setNameZh(String nameZh) {
this.nameZh = nameZh;
}
}
Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.gongj.secuitydb.entity.User;
import com.gongj.secuitydb.mapper.UserMapper;
@Service
public class UserSerivice implements UserDetailsService{
@Autowired
UserMapper userMapper;
/**
* 根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.loadUserByUsername(username);
if(user == null) {
throw new UsernameNotFoundException("用戶(hù)不存在");
}
user.setRoles(userMapper.getUserRoleById(user.getId())); //根據(jù)用戶(hù)id查詢(xún)角色
return user;
}
}
service中實(shí)現(xiàn)了UserDetailsService接口,重寫(xiě)loadUserByUsername方法。
Mapper
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.gongj.secuitydb.entity.Role;
import com.gongj.secuitydb.entity.User;
public interface UserMapper {
@Select("select * from user where username = #{username}")
User loadUserByUsername(String username);
List<Role> getUserRoleById(Integer id);
}
xml
<?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.gongj.securitydb.mapper.UserMapper">
<select id="getUserRoleById" resultType="com.gongj.securitydb.entity.Role">
select r.* from user_role ur ,role r where ur.uid = #{id} and ur.rid = r.id
</select>
</mapper>
開(kāi)始最重要的一步,配置Security
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.gongj.secuitydb.service.UserSerivice;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
UserSerivice userService;
@Bean
PasswordEncoder PasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
}
編寫(xiě)Controller開(kāi)始測(cè)試
@GetMapping("/he")
public String he() {
return "hello Security";
}
由于我的mapper接口和mapper.xml是放在src/main/java下的

image.png
所以需要在pom的build中指定mapper加載路徑
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>
**/**.xml
</include>
</includes>
</resource>
</resources>
</build>
訪問(wèn)http://localhost:8081/he來(lái)到登錄頁(yè)面輸入賬號(hào)和密碼

image.png
登錄成功,自動(dòng)跳轉(zhuǎn)訪問(wèn)路徑。

image.png
如果覺(jué)得對(duì)你所遇到的問(wèn)題有所幫助的話,我深感榮幸。可以加個(gè)微信好友以后交流交流。

image.png