权限表的设计
用户表: user
2.角色表:role
3.用户角色关联表:user_role
uid 表示 用户表中的id rid表示 角色表中的id
用户登陆成功之后,可以拿到id ,然后根据uid去找rid,通过rid就可以找到角色表中的角色了
2.实体类的创建
1:注意事项,实现UserDetails接口,里面有7个方法需要全部实现,
2:数据库中的角色需要以”_”下划线开头,否找需要在SimpleGrantedAuthority 中添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 package cn.m5f.bean;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; public Integer getId () { return id; } public void setId (Integer id) { this .id = id; } @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; } public void setUsername (String username) { this .username = username; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { List<SimpleGrantedAuthority> authorities = new ArrayList<>(); for (Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getName())); System.out.println(role.getName()); } return authorities; } @Override 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; } public List<Role> getRoles () { return roles; } public void setRoles (List<Role> roles) { this .roles = roles; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package cn.m5f.bean; /** * @author xhq * @date 2022/5/27 16:53 */ 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; } }
Service:
loadUserByUsername(String username):方法中的username 是用户登陆时候的用户名,我们根据用户名去找数据库中是否有这个用户,密码SpringSecurity自己会去找,不需要我们操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package cn.m5f.service; import cn.m5f.bean.User; import cn.m5f.mapper.UserMapper; 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; /** * @author xhq * @date 2022/5/27 17:13 */ @Service public class UserService 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.getUserRolesById(user.getId())); //如果存在,就根据用户名id 去查全拥有的角色 return user; } }
Mapper:
1 2 3 4 5 6 7 8 9 10 11 12 13 package cn.m5f.mapper; import cn.m5f.bean.Role; import cn.m5f.bean.User; import java.util.List; public interface UserMapper { //用户名查 密码security 自己会去匹配不需要我们管 User loadUserByUsername(String username); //根据用户名id 查所拥有的角色 List<Role> getUserRolesById(Integer id); }
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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="cn.m5f.mapper.UserMapper"> <select id="loadUserByUsername" resultType="cn.m5f.bean.User"> select * from user where username = #{username} </select> <select id="getUserRolesById" resultType="cn.m5f.bean.Role"> -- 根据用户名的uid,去找到它所拥有的rid ,rid就是role里对应的角色 select *from role where id in(select rid from user_role where uid=#{id}) </select> </mapper>
Security配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package cn.m5f.config; import cn.m5f.service.UserService; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.LockedException; 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.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; /** * @author xhq * @date 2022/1/23 20:49 */ @Configuration public class SecurityConfig 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("/user/**").hasAnyRole("admin","user")//任意一个角色 .antMatchers("/dba/**").hasRole("dba") .anyRequest().authenticated() .and() .formLogin() .permitAll() .and() .csrf().disable();//关闭cfs攻击 } }
截图:
Controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package cn.m5f.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author xhq * @date 2022/1/23 20:43 */ @RestController public class UserController { @GetMapping("/") public String hello(){ return "hello"; } @GetMapping("admin/dt") public String admin(){ return "admin"; } @GetMapping("user/dt") public String user(){ return "user"; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> <version>8.0.27</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.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
所需依赖
运行截图: