一、设计数据库表
1.库security
2.user表
3.role表
4.user_role表
Bcrypt密码生成计算器 https://www.jisuan.mobi/p163u3BN66Hm6JWx.html
二、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</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-web</artifactId>
</dependency>
三、数据库配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:mysql:///security spring.datasource.username = root spring.datasource.password = kangxg198811
四、创建实体类
1.Role
public class Role {
private Integer id;
private String name;
private String nameZh;
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setNameZh(String nameZh) {
this.nameZh = nameZh;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getNameZh() {
return nameZh;
}
@Override
public String toString() {
return "{" +
"id=" + id +
", name='" + name + '\'' +
", nameZh='" + nameZh + '\'' +
'}';
}
}
2.User
@ApiModel(value = "用户实体类",description = "用户信息描述类")
public class User implements UserDetails {
private Integer id;
@ApiModelProperty(value="用户名")
private String username;
@ApiModelProperty(value="用户密码")
private String password;
private boolean enabled;
private boolean locked;
private List<Role> roles;
@Override //获取当前用户对象所具有的角色信息
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 password;
}
@Override//获取当前用户对象的用户名
public String getUsername() {
return username;
}
public Integer getId() {
return id;
}
public List<Role> getRoles() {
return roles;
}
@Override//当前账户是否过期
public boolean isAccountNonExpired(){
return true;
}
@Override//当前账户是否锁定
public boolean isAccountNonLocked()
{
return !locked;
}
@Override//当前账户密码是否过期
public boolean isCredentialsNonExpired()
{
return true;
}
@Override//当前账户是否可用
public boolean isEnabled() {
return enabled;
}
public boolean isLocked() {
return locked;
}
public void setUsername(String username) {
this.username = username;
}
public void setId(Integer id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
@Override
public String toString() {
return "{" +
"id=" + id +
", name='" + username + '\'' +
", password='" + password + '\'' +
", enabled=" + enabled +
", locked=" + locked +
'}';
}
}
五、创建UserService
@CrossOrigin
@Service
public class UserService implements UserDetailsService {
@Resource
UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
User user = userMapper.loadUserByUsername(username);
//动过登录输入的用户名去数据库查找用户,如果没有找到就抛出一个异常
if (user == null)
{
throw new UsernameNotFoundException("账户不存在!");
}
//如果查找到了就继续查找该用户所具有到角色信息,并将 获取到到user对象返回,再由系统提供到DaoAuthenticationProvider
类去对比密码是否正确
user.setRoles(userMapper.getUserRolesByUid(user.getId()));
return user;
}
}
六、UserMapper和UserMapper.xml
@Mapper
public interface UserMapper {
User loadUserByUsername(String username);
List<Role> getUserRolesByUid(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">
<!-- namespace 表示命名空间 -->
<mapper namespace="com.kxg.swagger.mapper.UserMapper">
<select id="loadUserByUsername" resultType="com.kxg.swagger.entity.User">
select * from user where username =#{username}
</select>
<select id="getUserRolesByUid" resultType="com.kxg.swagger.entity.Role">
select * from role r,user_role ur where r.id =ur.rid and ur.uid=#{id}
</select>
</mapper>
七、配置Spring Security
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
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")
.antMatchers("/db/**").hasRole("dba")
.antMatchers("/user/**").hasRole("user")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login_page")
.loginProcessingUrl("/login")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException, JsonProcessingException {
Object principal = authentication.getPrincipal();
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
httpServletResponse.setStatus(200);
Map<String,Object> map = new HashMap<>();
map.put("status",200);
map.put("msg",principal);
ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException, IOException {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
httpServletResponse.setStatus(200);
Map<String,Object> map = new HashMap<>();
map.put("status",401);
if (e instanceof LockedException)
{
map.put("msg","账户被锁定,登录失败!");
}
else if(e instanceof BadCredentialsException)
{
map.put("msg","账户名或密码输入错误,登录失败!");
}
else if(e instanceof DisabledException)
{
map.put("msg","账户被禁用,登录失败!");
}
else if(e instanceof AccountExpiredException)
{
map.put("msg","账户已过期,登录失败!");
}
else if(e instanceof CredentialsExpiredException)
{
map.put("msg","密码已过期,登录失败!");
}
else {
map.put("msg","登录失败!");
}
ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.permitAll()
.and()
.csrf()
.disable();
}
}