Spring 使用 MySQL 和 JPA 的自定义安全性提供 403 访问被拒绝
Spring Custom Security With MySQL And JPA Giving 403 Access Denied
我正在尝试通过使用 UserDetailsService 提供身份验证来访问我在邮递员上的休息 api,但每次我都会在每次请求给出 403 访问被拒绝时触发请求。 POST 和 GET 方法的行为相同。我已经阅读了论坛上记录的其他问题,但每个答案都说这是由于 CSRF,我禁用了它,但问题仍然存在。
完整代码已开启:https://github.com/afulz29/spring-security-demo.git
请帮助我,我已经为这个问题苦苦挣扎了 3 天。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer{
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/api/**").authenticated().anyRequest().hasAnyRole("ADMIN");
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
}
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
@GetMapping(path = "/users")
public User getUserById(@RequestParam("userId") Integer userId) {
return userService.getUserById(userId);
}
@PostMapping(path = "/users", consumes = MediaType.APPLICATION_JSON_VALUE)
public User addUser(@RequestBody User user) {
return userService.addUser(user);
}
}
我发现您的安全配置存在一些问题:
- BASIC AUTH 未启用,但您正尝试在 postman 中进行 Basic Auth
执行以下操作以启用基本身份验证
http
.authorizeRequests()
...
.and()
.httpBasic();
- 我猜 POST /api/users 是一个用户注册端点。您必须将此端点列入白名单,以便任何人都可以注册
http
.authorizeRequests()
.antMatchers( HttpMethod.POST,"/api/users").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().hasAnyRole("ADMIN")
.and()
.httpBasic();
测试:
创建用户
POST: localhost:8080/api/users
{
"userName" : "user1",
"password": "pass"
}
获取用户信息
GET: localhost:8080/api/users?userId=1 //use the correct ID
With Basic Auth: userName = user1, password = pass
奖励反馈:
- User.userName --> 您可能希望使该字段唯一
@Repository
您的存储库接口中不需要此注释
- 用户服务接口。我看不出有任何理由使用接口和实现。
我正在尝试通过使用 UserDetailsService 提供身份验证来访问我在邮递员上的休息 api,但每次我都会在每次请求给出 403 访问被拒绝时触发请求。 POST 和 GET 方法的行为相同。我已经阅读了论坛上记录的其他问题,但每个答案都说这是由于 CSRF,我禁用了它,但问题仍然存在。
完整代码已开启:https://github.com/afulz29/spring-security-demo.git
请帮助我,我已经为这个问题苦苦挣扎了 3 天。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer{
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/api/**").authenticated().anyRequest().hasAnyRole("ADMIN");
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
}
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
@GetMapping(path = "/users")
public User getUserById(@RequestParam("userId") Integer userId) {
return userService.getUserById(userId);
}
@PostMapping(path = "/users", consumes = MediaType.APPLICATION_JSON_VALUE)
public User addUser(@RequestBody User user) {
return userService.addUser(user);
}
}
我发现您的安全配置存在一些问题:
- BASIC AUTH 未启用,但您正尝试在 postman 中进行 Basic Auth
执行以下操作以启用基本身份验证
http
.authorizeRequests()
...
.and()
.httpBasic();
- 我猜 POST /api/users 是一个用户注册端点。您必须将此端点列入白名单,以便任何人都可以注册
http
.authorizeRequests()
.antMatchers( HttpMethod.POST,"/api/users").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().hasAnyRole("ADMIN")
.and()
.httpBasic();
测试:
创建用户
POST: localhost:8080/api/users
{
"userName" : "user1",
"password": "pass"
}
获取用户信息
GET: localhost:8080/api/users?userId=1 //use the correct ID
With Basic Auth: userName = user1, password = pass
奖励反馈:
- User.userName --> 您可能希望使该字段唯一
@Repository
您的存储库接口中不需要此注释- 用户服务接口。我看不出有任何理由使用接口和实现。