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

相關文章
相關標籤/搜索