@RolesAllowed
时, jdbcAuthentication()
似乎不起作用,但如果我使用inMemoryAuthentication()
则效果正常。如果我删除jdbcAuthentication()
,则@RolesAllowed
可以正常工作。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery("select u.email, u.password, u.enabled from bagtag.user u where email=?")
.authoritiesByUsernameQuery("select u.email, r.name from bagtag.user u join bagtag.role r on (r.id = u.role_id) where u.email=?")
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/api/**").fullyAuthenticated().and().httpBasic()
.realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
以下RequestMapping
对@RolesAllowed
有效,但如果我删除@RolesAllowed
则有效。我收到以下错误。
{
"timestamp": 1510628906600,
"status": 403,
"error": "Forbidden",
"exception": "org.springframework.security.access.AccessDeniedException",
"message": "Access is denied",
"path": "/api/user/admin"
}
@RestController
@RequestMapping(value = "/api/user", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
@Autowired
UserService us;
@RolesAllowed(Role.SUPERADMIN)
@RequestMapping(value = "/admin", method = RequestMethod.POST)
public ResponseEntity<User> createAdmin(@RequestBody UserWrapper uw) {
return new ResponseEntity<User>(uw.getUser(), HttpStatus.OK);
}
}
我尝试过检查经过身份验证的用户
System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());
返回
org.springframework.security.core.userdetails.User@ca3b1db5: Username: test@test.dk; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SUPERADMIN
我试图删除@RolesAllowed
并替换了以下行
http.csrf().disable().authorizeRequests().antMatchers("/api/**").fullyAuthenticated().and().httpBasic()
与
http.csrf().disable().authorizeRequests().antMatchers("/api/**").hasAnyRole(String.format("%s,%s,%s", Role.SUPERADMIN, Role.ADMIN, Role.STAFF)).and().httpBasic()
这给了我http status 403
{
"timestamp": 1510629419006,
"status": 403,
"error": "Forbidden",
"message": "Access is denied",
"path": "/api/user/admin"
}
这是我数据库中的两个表。用户只能拥有一个角色。
CREATE TABLE `role` (
`role_id` int(11) NOT NULL AUTO_INCREMENT,
`role` varchar(255) DEFAULT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) DEFAULT NULL,
`role_id` int(11) NOT NULL,
`enabled` bit(1) NOT NULL DEFAULT b'0',
`last_login` timestamp NULL DEFAULT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8
答案 0 :(得分:0)
所以我找到了问题的解决方案,我必须将.rolePrefix("ROLE_");
添加到我的configureGlobalSecurity
方法中。
我不确定为什么这是解决方案。根据文档,AuthenticationManagerBuilder
的默认角色前缀为空String
。所以我最好的猜测是Spring默认角色前缀是“ROLE _”。
如果有人知道这种疯狂背后的真实解释,请发表评论或回答。我会非常感谢!
编辑:
@RolesAllowed
默认前缀为ROLE_
,这就是为什么你必须为spring security添加ROLE_
前缀!
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder)
//.rolePrefix fixed the problem
.rolePrefix("ROLE_");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/api/**")
.hasAnyRole(String.format("%s,%s,%s", Role.SUPERADMIN, Role.ADMIN, Role.STAFF)).and().httpBasic()
.realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint()).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}