导入依赖
<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>
数据库脚本
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`nameEN` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色英文名称',
`nameZh` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色中文名称',
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', '数据库管理员');
INSERT INTO `role` VALUES (2, 'ROLE_admin', '系统管理员');
INSERT INTO `role` VALUES (3, 'ROLE_user', '用户');
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户名',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户密码',
`enabled` tinyint(1) DEFAULT NULL COMMENT '是否启用',
`locked` tinyint(1) DEFAULT NULL COMMENT '是否被锁定',
`expired` tinyint(1) DEFAULT NULL COMMENT '账户是否过期',
`credentialsExpire` tinyint(1) DEFAULT NULL COMMENT '凭据是否过期',
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 '用户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
环境搭建完成。
实体类
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() { //返回用户的所有角色
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getNameEN()));
}
return authorities;
}
@Override
public boolean isAccountNonExpired() { //账户是否未过期
return expired;
}
@Override
public boolean isAccountNonLocked() { //账户是否未锁定
return locked;
}
@Override
public boolean isCredentialsNonExpired() { //凭证是否未过期
return credentialsExpire;
}
@Override
public boolean isEnabled() { //账户是否可用
return enabled;
}
}
在User中实现了Security中的UserDetails接口,重写了几个方法。并将enabled、locked、expired、credentialsExpire的get方法删除,isEnabled、
isAccountNonLocked、isAccountNonExpired、isCredentialsNonExpired这几个方法取而代之。
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;
/**
* 根据用户名查询用户信息
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.loadUserByUsername(username);
if(user == null) {
throw new UsernameNotFoundException("用户不存在");
}
user.setRoles(userMapper.getUserRoleById(user.getId())); //根据用户id查询角色
return user;
}
}
service中实现了UserDetailsService接口,重写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>
开始最重要的一步,配置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);
}
}
编写Controller开始测试
@GetMapping("/he")
public String he() {
return "hello Security";
}
由于我的mapper接口和mapper.xml是放在src/main/java下的
所以需要在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>
访问http://localhost:8081/he来到登录页面输入账号和密码
登录成功,自动跳转访问路径。
如果觉得对你所遇到的问题有所帮助的话,我深感荣幸。可以加个微信好友以后交流交流。