@RolesAllowed
does not seem to work when im using jdbcAuthentication()
, but it works fine if I am using inMemoryAuthentication()
. jdbcAuthentication()
works fine if I remove @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);
}
}
The following RequestMapping
does with @RolesAllowed
but it works if I remove @RolesAllowed
. I am getting the following error.
{
"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);
}
}
I have tried to inspect the authenticated user with System.out.println(SecurityContextHolder.getContext().getAuthentication().getPrincipal());
which returns
org.springframework.security.core.userdetails.User@ca3b1db5: Username: test@test.dk; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SUPERADMIN
I have tried to remove @RolesAllowed
and replaced the following line in the http.csrf().disable().authorizeRequests().antMatchers("/api/**").fullyAuthenticated().and().httpBasic()
with
http.csrf().disable().authorizeRequests().antMatchers("/api/**").hasAnyRole(String.format("%s,%s,%s", Role.SUPERADMIN, Role.ADMIN, Role.STAFF)).and().httpBasic()
This gives me http status 403
{
"timestamp": 1510629419006,
"status": 403,
"error": "Forbidden",
"message": "Access is denied",
"path": "/api/user/admin"
}
This is my two tables in my database. A user can only have a single role.
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
So I found the solution to my problem, I had to add .rolePrefix("ROLE_");
to my configureGlobalSecurity
method.
I am not sure why this is the solution. The default role prefix for AuthenticationManagerBuilder
is an empty String
according to according the documentation. So my best guess is that Spring default role prefix is "ROLE_".
If anyone knows the real explanation behind this madness please either post a comment or an answer. I would be very thanksful!
EDIT: @RolesAllowed
default prefix is ROLE_
which is why you have to add ROLE_
prefix to spring security!
@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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.