問題描述
日志打出來的ROLE是USER,代碼里調用的是@PreAuthorize("hasRole('USER')"),為什么權限卻是不對?
后臺打印日志:
username is jack, USER
LoginFilter:{
"accountNonExpired":true,
"accountNonLocked":true,
"authorities":[{
"authority":"USER"
}],
"credentialsNonExpired":true,
"enabled":true,
"username":"jack"
}
調用代碼:
@RestController
@RequestMapping(Array("/httpapi"))
class HttpApiController @Autowired()(
val HttpSuiteDao: HttpSuiteDao,
val HttpApiDao: HttpApiDao,
val HttpReportDao: HttpReportDao) {
@PreAuthorize("hasRole('USER')")
@RequestMapping(value = {
Array("", "/")
}, method = Array(RequestMethod.GET))
def list(model: Model) = {
model.addAttribute("httpapis", HttpApiDao.findAll())
new ModelAndView("/httpapi/list")
}
....
}
數據庫存的是USER:
package com.springboot.in.action.service
import javax.annotation.PostConstruct
import com.springboot.in.action.dao.{RoleDao, UserDao, UserRoleDao}
import com.springboot.in.action.entity.{Role, User, UserRole}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
/**
* Created by jack on 2017/4/29.
* 初始化測試數據
*/
//@Service // 需要初始化數據時,打開注釋即可。
class DataInit @Autowired()(val userDao: UserDao,
val userRoleDao: UserRoleDao,
val roleDao: RoleDao) {
@PostConstruct def dataInit(): Unit = {
val admin = new User
val jack = new User
admin.username = "admin"
admin.password = "admin"
jack.username = "jack"
jack.password = "123456"
userDao.save(admin)
userDao.save(jack)
val adminRole = new Role
val userRole = new Role
adminRole.role = "ADMIN"
userRole.role = "USER"
roleDao.save(adminRole)
roleDao.save(userRole)
val userRoleAdminRecord1 = new UserRole
userRoleAdminRecord1.userId = admin.id
userRoleAdminRecord1.roleId = adminRole.id
userRoleDao.save(userRoleAdminRecord1)
val userRoleAdminRecord2 = new UserRole
userRoleAdminRecord2.userId = admin.id
userRoleAdminRecord2.roleId = userRole.id
userRoleDao.save(userRoleAdminRecord2)
val userRoleJackRecord = new UserRole
userRoleJackRecord.userId = jack.id
userRoleJackRecord.roleId = userRole.id
userRoleDao.save(userRoleJackRecord)
}
}
原因分析:
Spring Security默認前綴ROLE_問題。這個應該是框架的一個小缺陷??偢杏X這樣的一個潛規則在這里有點不大優雅。
解決方案
數據庫里面存的role角色要加上默認前綴:ROLE_
adminRole.role = "ROLE_ADMIN"
userRole.role = "ROLE_USER"
這樣改完之后,代碼調用的地方保持不變,數據庫里面角色必須統一有ROLE_前綴。而我們看到的后臺打印的日志內容也是數據庫的信息:
username is jack, ROLE_USER
LoginFilter:{
"accountNonExpired":true,
"accountNonLocked":true,
"authorities":[{
"authority":"ROLE_USER"
}],
"credentialsNonExpired":true,
"enabled":true,
"username":"jack"
}
這個小坑,估計很多初次學習使用Security框架的人都會踩到。所以,記個問題,以供參考。