Spring Security用户权限测试

在本周给出题系统加了Travis的自动测试,前一天还能经过,但次日上课回来却报错了,缘由是加了权限校验,是经过Spring Security实现的,不过初始化用户的时候也初始化了权限了呀。打上断点debug能够发现,该有的初始化状态都有
image.pnghtml

可是测试仍是报了403,为何呢?spring

解决办法

测试时用户是经过@WithMockUser实现的,其余测试类经过继承ControllerTest得到基础配置数据库

image.png

和潘哥一番查找,发现spring已经替咱们准备好了解决办法,只需在@WithMockUser添加相应的属性便可session

image.png

添加相应的角色:ide

@WithMockUser(username = "admin", password = "admin", roles = "COLLEGE")

单元测试顺利经过。单元测试

关于@WithMockUserSpring Security测试的更详细内容能够查看官方文档测试

为什么会这样

user里面已经有了相应的角色,为什么还须要在注解中配置角色呢?this

知其然还需知其因此然才行,因此尝试着去寻找为什么这样,先本身在网上搜了搜,没整太明白,问了问张喜硕学长,学长给我解释了一下。如下内容须要Spring Security的基础知识。spa

在本项目中,登陆流程以下:debug

  1. 前台传一个用户到后台
  2. 经过继承自UserDetailsServiceYunzhiAuthService生成了一个org.springframework.security.core.userdetails.User

    @Component
    public class YunzhiAuthService implements UserDetailsService {
    
        private static final Logger logger = LoggerFactory.getLogger(YunzhiAuthService.class);
    
        private final UserRepository userRepository;
    
        public YunzhiAuthService(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        @Transactional
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            logger.debug("根据用户名查询用户");
            User user = userRepository.findByUsername(username);
    
            if (user == null) {
                logger.error("用户名不存在");
                throw new UsernameNotFoundException("用户名不存在");
            }
    
            logger.debug("获取用户受权菜单");
            Set<Menu> menus = new HashSet<>();
            for (Role role : user.getRoles()) {
                menus.addAll(role.getMenus());
            }
    
            logger.debug("初始化受权列表");
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    
            logger.debug("根据菜单进行 API 受权");
            for (Menu menu : menus) {
                authorities.add(new SimpleGrantedAuthority(menu.getRoleName()));
            }
    
            logger.debug("构造用户");
            return new org.springframework.security.core.userdetails.User(username, user.getPassword(), authorities);
        }
    }
  3. 和数据库中的user比较密码
  4. 正确则登陆成功,并存入session

而权限是在UserDetailsServiceloadUserByUsername中生成的。

当使用@WithMockUser时,实际上并无进行登陆操做,天然没法从数据库中的用户中提取出相应的权限,而在注解中配置的权限会直接放入 session中。

image.png

相关文章
相关标签/搜索