英文:
Spring Security 403 Error While Trying To Add a New User
问题
我一直在尝试为我的Spring Boot安全应用程序添加一个create方法,但是当我使用POST映射时,我会得到那个错误。另外,我的ID在数据库中是自增的。我不确定,但错误可能是由于这个原因。我不知道如何在请求体中编写自增的值。
请求体如下:
{
"id": 3,
"userName": "Adminn",
"password": "pss",
"active": true,
"role": "ROLE_ADMIN"
}
我的Home Resource类如下:
package io.javabrains.springsecurity.jpa;
@RestController
public class HomeResource {
@Autowired
private UserRepository userRepo;
@GetMapping("/")
public String home() {
return "<h1>Welcome</h1>";
}
@GetMapping("/user")
public String user() {
return "Welcome User";
}
@GetMapping("/admin")
public String admin() {
return "<h1>Welcome Admin</h1>";
}
@GetMapping("/users/{id}")
public Optional<User> retrieveUser(@PathVariable int id) {
return userRepo.findById(id);
}
@PostMapping("/createUser")
public void createUser(@RequestBody User myuser) {
User savedUser = userRepo.save(myuser);
}
}
我的Spring应用程序类如下:
@SpringBootApplication
@EnableJpaRepositories(basePackageClasses = UserRepository.class)
public class SpringsecurityApplication implements CommandLineRunner {
@Autowired
UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(SpringsecurityApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Application Running.");
User adminUser = new User();
adminUser.setUserName("Admin");
adminUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
adminUser.setRole("ROLE_ADMIN");
adminUser.setActive(true);
userRepository.save(adminUser);
User newUser = new User();
newUser.setUserName("User");
newUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
newUser.setRole("ROLE_USER");
newUser.setActive(true);
userRepository.save(newUser);
}
}
用户类如下:
package io.javabrains.springsecurity.jpa.models;
@Entity
@Table(name = "app_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String userName;
private String password;
private boolean active;
private String role;
// Getters and setters...
}
安全配置类如下:
package io.javabrains.springsecurity.jpa;
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasAnyRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN", "USER")
.antMatchers("/", "/createUser").permitAll()
.and().formLogin();
}
}
英文:
I have been trying to add a create method to my spring boot security app but, when I use post mapping I get that error. Also, my id is auto-incremented in db. I am not sure but maybe the error is because of it. I don't know how to write an auto-incremented value in the request body.
{"timestamp":"2020-08-
23T00:43:31.062+00:00","status":403,"error":"Forbidden","message":"","path":"/createUser"}
The body that i am trying to post:
{
"id": 3,
"userName": "Adminn",
"password": "pss",
"active": true,
"role": "ROLE_ADMIN"
}
Request Body for Post Mapping
[1]: https://i.stack.imgur.com/uqoD0.png
My home resource class
package io.javabrains.springsecurity.jpa;
@RestController
public class HomeResource {
@Autowired
private UserRepository userRepo;
@GetMapping("/")
public String home() {
return ("<h1>Welcome</h1>");
}
@GetMapping("/user")
public String user() {
return ("Welcome User");
}
@GetMapping("/admin")
public String admin() {
return ("<h1>Welcome Admin</h1>");
}
@GetMapping("/users/{id}")
public Optional<User> retriveUser(@PathVariable int id)
{
return userRepo.findById(id);
}
@PostMapping("/createUser")
public void createUser(@RequestBody User myuser) {
User savedUser=userRepo.save(myuser);
}
/*@GetMapping("/createUser") // it is working
public String addUser() {
User newuser= new User();
newuser.setUserName("new");
newuser.setPassword(new BCryptPasswordEncoder().encode("pass"));
newuser.setRole("ROLE_ADMIN");
newuser.setActive(true);
userRepo.save(newuser);
return "user booked";
}*/
}
My Spring App Class
@SpringBootApplication
@EnableJpaRepositories(basePackageClasses = UserRepository.class)
public class SpringsecurityApplication implements CommandLineRunner{
@Autowired
UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(SpringsecurityApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("Application Running.");
User adminUser= new User();
adminUser.setUserName("Admin");
adminUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
adminUser.setRole("ROLE_ADMIN");
adminUser.setActive(true);
userRepository.save(adminUser);
User newUser= new User();
newUser.setUserName("User");
newUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
newUser.setRole("ROLE_USER");
newUser.setActive(true);
userRepository.save(newUser);
}
}
User Class
package io.javabrains.springsecurity.jpa.models;
@Entity
@Table(name="app_user")
public class User {
@Id
@GeneratedValue(strategy =GenerationType.AUTO)
private int id;
private String userName;
private String password;
private boolean active;
private String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Security Config Class
package io.javabrains.springsecurity.jpa;
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder ()
{
return new BCryptPasswordEncoder();
}
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasAnyRole("ADMIN")
.antMatchers("/user").hasAnyRole("ADMIN","USER")
.antMatchers("/","/createUser").permitAll()
.and().formLogin();
}
}
答案1
得分: 0
如果您按照以下方式修改您的代码:
.antMatchers(HttpMethod.POST, "/createUser").permitAll()
英文:
What if you modify your code this way:
.antMatchers(HttpMethod.POST, "/createUser").permitAll()
答案2
得分: 0
因为默认情况下启用了针对状态更改型HTTP动词(例如POST)的CSRF保护。您可以选择禁用它,或在您的网页中包含CSRF令牌,然后在您的HTTP请求中也包含该令牌。
英文:
Because CSRF protection for state-changing HTTP verbs, such as POST, is enabled by default. You can either disable it or include CSRF token in your web page, and subsequently in your HTTP request.
答案3
得分: -1
首先,将JSON请求映射到实体类是一个不好的做法。首先,您应该使用DTO类。
这样做,然后看看会发生什么。
英文:
First of all is a bad practice try to map the JSON request to an entity class. First you should use a DTO class.
Do that first and see what happend
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论