新增SysRoleMapper接口
在mapper包中新增SysRoleMapper接口,增加查询用户角色方法
@Repository public interface SysRoleMapper { List<SysRole> selectRoleByUser(Integer userId); } 复制代码
实现SysRoleMapper接口
在resources目录下的mappers文件夹中新增xml配置文件,实现Mapper接口中的查询方法
<?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.citi.mapper.SysRoleMapper"> <resultMap id="roleMapper" type="com.citi.entity.SysRole"> <id column="id" property="id" /> <result column="rolename" property="name" /> <result column="rolememo" property="demo" /> </resultMap> <select id="selectRoleByUser" parameterType="integer" resultMap="roleMapper"> SELECT r.id, r.rolename, rolememo FROM sys_user_role ur, sys_role r WHERE ur.roleid = r.id AND ur.userid = #{userId} </select> </mapper> 复制代码
创建自定义的UserDetailsService实现类
重写方法中查询数据库获取用户信息,获取角色数据,构建UserDetails实现类对象
@Service public class JdbcUserDetailsService implements UserDetailsService { @Resource private SysUserMapper userMapper; @Resource private SysRoleMapper roleMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 1.根据username获取SysUser SysUser user = userMapper.selectSysUser(username); // 2.根据userId获取用户角色 if (user != null){ List<SysRole> sysRoles = roleMapper.selectRoleByUser(user.getId()); String roleName = ""; List<GrantedAuthority> authorities = new ArrayList<>(); for (SysRole sysRole : sysRoles) { roleName = sysRole.getName(); SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_" + roleName); authorities.add(grantedAuthority); } return user; } return user; } } 复制代码
新建CustSecurityConfig配置列
在config包下新建CustSecurityConfig,自定义WebSecurityConfigurerAdapter,自定义安全配置
@Configuration @EnableWebSecurity public class CustSecurityConfig extends WebSecurityConfigurerAdapter { @Resource private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); } } 复制代码
新增UserController
新增controller包,新增UserController及index.html页面
@RestController public class UserController { @GetMapping(value = "/access/user", produces = "text/html;charset=utf-8") public String user(){ return "USER"; } @GetMapping(value = "/access/read", produces = "text/html;charset=utf-8") public String read(){ return "READ"; } @GetMapping(value = "/access/admin", produces = "text/html;charset=utf-8") public String admin(){ return "ADMIN"; } } 复制代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> </head> <body> <p>验证访问</p> <a href="/access/user">USER</a> <a href="/access/read">READ</a> <a href="/access/admin">ADMIN</a> </body> </html> 复制代码
启动MainApplication
启动MainApplication,打开localhost:8080,自动跳转至localhost:8080/login
输入用户名密码Thor/12345,Peter/12345,Stark/12345,可以成功跳转至index页面
给index页面去除权限控制,在CustSecurityConfig类中新增重载的configure方法,出了index页面可以直接访问,其他页面都需要权限验证
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/index.html").permitAll() .anyRequest().authenticated() .and() .formLogin(); } 复制代码
重启启动应用,清楚浏览器缓存,在浏览器中输入localhost:8080,页面直接显示,不需要在进行登录操作,随意点击index页面的一个连接跳出认证页面
16.给URL配置角色访问权限,修改configure(HttpSecurity http)方法
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/index.html").permitAll() // 给url配置角色访问权限 .antMatchers("/access/user").hasRole("USER") .antMatchers("/access/read").hasRole("READ") .antMatchers("/access/admin").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin(); } 复制代码
以上代码给USER角色配置了/access/user的访问权限,给READ角色配置了/access/read的访问权限 ,给ADMIN角色配置了/access/admin的访问权限
17.验证权限,重新启动应用,打开首页如下,为保证正确性,首先清楚浏览器缓存,三个用户Peter,Thor,Stark分别属于3个角色ADMIN,USER,READ,Thor账户还拥有ADMIN的权限
首先验证USER角色,点击USER链接,输入Thor/123456,正常访问
其他页面,访问异常
由于Thor账户还有ADMIN角色,所以ADMIN页面也是可以正常访问的
清楚浏览器缓存,使用READ角色的Stark账号访问,read页面可以正常访问
试试其他页面,访问user页面和admin页面均报错
当然也可以给一个角色配置多个页面访问权限
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/index.html").permitAll() // 给url配置角色访问权限 .antMatchers("/access/user","/access/read").hasRole("USER") .antMatchers("/access/read").hasRole("READ") .antMatchers("/access/admin","/access/read","/access/user").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin(); } 复制代码
antMatchers()参数为String...antPatterns,不限制url的个数。
目前为止,已经实现在自定义数据库表的情况下实现用户认证和权限的鉴别,并且通过了测试。