前言
這幾天一直在學習和慢慢摸索SpringBoot和SpringSecurity整合的知識要點,今天搭好了鑑權這一塊後啓動項目,準備用postman測一下幾個接口,沒想到遇到一個天坑(也許是自己才疏學淺了😄😄)。
首先在配置裏過濾掉不需要認證的URL:
.antMatchers("/login","/home","/getCode").permitAll() //過濾不需要認證的路徑
.antMatchers("/auth/**").permitAll() //過濾不需要認證的路徑
.anyRequest().authenticated() //對任何一個請求,都需要認證
放開了/auth/
下的接口,controller裏的方法,先來個根據用戶名獲取角色的吧:
/**
* 獲取用戶及對應的角色信息
*
* @Author ZHANGCHAO
* @Date 2020/3/4 11:03
* @param
* @retrun
**/
@GetMapping("/getUserRoles")
public ResponseMessage getUserAndRolesByUserCode(@RequestParam("userName") String userName){
SysUser user = (SysUser) userService.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUserName,userName)).getData();
if (isEmpty(user)){
return new ResponseMessage(false,"用戶不存在!",null);
}
List<SysUserRole> userRoles = (List<SysUserRole>) userRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId,user.getId())).getData();
List<SysRole> roleList = new ArrayList<>();
if (isNotEmpty(userRoles)){
userRoles.forEach(sysUserRole -> {
roleList.add((SysRole) roleService.getById(sysUserRole.getRoleId()).getData());
});
}
user.setRoles(roleList);
return new ResponseMessage(true,user);
}
postman測試:
很好,完美!返回了用戶名是zhangchao的所有角色!😄爽歪歪,繼續再加個用戶吧:
/**
* 新增用戶
*
* @Author ZHANGCHAO
* @Date 2020/3/3 10:58
* @param
* @param user
* @retrun com.junya.util.result.ResponseMessage
**/
@PostMapping("/addUser")
public ResponseMessage saveUser(@RequestBody SysUser user){
System.out.println(user);
user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
return userService.save(user);
}
postman調用,竟然返回登錄頁面的HTML:
懷疑是不是找不到接口?!換成GET方式調用試試:
Request method 'GET' not supported
說明方法沒問題,可以調用到。
經過查詢資料可知,Spring Security默認開啓CSRF防護:
CSRF是指跨站請求僞造(Cross-site request forgery),是web常見的攻擊之一。
從Spring Security 4.0開始,默認情況下會啓用CSRF保護,以防止CSRF攻擊應用程序,Spring Security CSRF會針對PATCH,POST,PUT和DELETE方法進行防護。
我這邊是spring boot項目,在啓用了@EnableWebSecurity註解後,CSRF保護就自動生效了。
所以在默認配置下,即便已經登錄了,頁面中發起PATCH,POST,PUT和DELETE請求依然會被拒絕,並返回403,需要在請求接口的時候加入CSRF Token纔行。
原來如此,那就在項目的配置中先禁用掉吧:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() //需要授權的請求
.antMatchers("/login","/home","/getCode").permitAll() //過濾不需要認證的路徑
.antMatchers("/auth/**").permitAll() //過濾不需要認證的路徑
.anyRequest().authenticated() //對任何一個請求,都需要認證
.and() //完成上一個配置,進行下一步配置
//.httpBasic();
.formLogin() //配置表單登錄
.loginPage("/login") //設置登錄頁面
.successHandler(successHandler) /* 設置成功處理器 */
.failureHandler(failureHandler) /* 設置失敗處理器*/
.and()
.logout() //登出
.logoutSuccessUrl("/home"); //設置退出頁面
// 添加驗證碼過濾器
http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
// 禁用CSRF防護
http.csrf().disable();
}
很簡單,加上http.csrf().disable()
即可。
重啓項目,postman測試下:
OK,很好,已經添加到數據庫中了!😆😆😆