Reputation: 2075
I face a 403 - Access denied
error every time I try hitting this secured method. I can hit all other methods except this secured one. If it matters, I am using H2 DB.
This is the first time I am trying spring security
. So forgive me for any simple mistakes
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/addProduct")
public ResponseEntity<String> addProduct(@RequestBody Product product) {
if (productService.addProduct(product)) {
return new ResponseEntity<String>("newly added " + product.getName(), HttpStatus.CREATED);
}
return new ResponseEntity<String>("Could not add product " + product.getName(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
My Spring configuration class is as follows:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String authoritiesQuery = "SELECT USERNAME, ROLE FROM TBLUSERS WHERE USERNAME = ?";
private static final String usersQuery = "SELECT USERNAME, PASSWORD, 1 as enabled FROM TBLUSERS WHERE USERNAME = ?";
@Autowired
private DataSource dataSource;
@Autowired
protected void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).authoritiesByUsernameQuery(authoritiesQuery)
.usersByUsernameQuery(usersQuery).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers(HttpMethod.POST, "/addProduct").hasRole("ADMIN").antMatchers("/").permitAll().and().authorizeRequests()
.antMatchers("/console/**").permitAll();
httpSecurity.csrf().disable();
httpSecurity.headers().frameOptions().disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}
}
My H2 DB entries are:
MERGE INTO TBLUSERS VALUES ('Abhi', '$2a$10$5uSoNE.xI.0Pe4uoy1Pd/ushJPh0O32Sa6W/CybjBp9FrytEuPGvq', 'ROLE_USER');
MERGE INTO TBLUSERS VALUES ('Abhishek', '$2a$10$5uSoNE.xI.0Pe4uoy1Pd/ushJPh0O32Sa6W/CybjBp9FrytEuPGvq', 'ROLE_ADMIN');
MERGE INTO TBLUSERS VALUES ('Abhishek', '$2a$10$5uSoNE.xI.0Pe4uoy1Pd/ushJPh0O32Sa6W/CybjBp9FrytEuPGvq', 'ROLE_USER');
Upvotes: 0
Views: 78
Reputation: 16969
Your database table TBLUSERS
contains two users with username Abhishek
. Apparently the last one with authority ROLE_USER
is used. But the URL /addProduct
is only accessible for users with authority ROLE_ADMIN
. Hence, you get a 403 error message.
If you want to have users with multiple authorities, you have to change your database schema, see for example Spring Security Reference:
15.1.1 User Schema
The standard JDBC implementation of the
UserDetailsService
(JdbcDaoImpl
) requires tables to load the password, account status (enabled or disabled) and a list of authorities (roles) for the user. You will need to adjust this schema to match the database dialect you are using.create table users( username varchar_ignorecase(50) not null primary key, password varchar_ignorecase(50) not null, enabled boolean not null ); create table authorities ( username varchar_ignorecase(50) not null, authority varchar_ignorecase(50) not null, constraint fk_authorities_users foreign key(username) references users(username) ); create unique index ix_auth_username on authorities (username,authority);
Upvotes: 2