简体   繁体   中英

Spring Boot error 403 when sending request

My system consists of 3 parts. Spring Boot app, Angular app and Android app. When my Android app sends request to reset password (if don't remember it) then Spring Boot app receives this request with this method:

@PostMapping("/forgot_password")
public String processForgotPassword(@RequestBody String email, HttpServletRequest request) {
    try {
        String token = RandomString.make(30);
        userService.updateResetPasswordToken(token, email);
        String resetPasswordLink = "https://jakuwegiel.web.app/projects/endless-blow/reset-password?token=" + token;
        sendEmail(email, resetPasswordLink);

    } catch (Exception ex) {
        System.out.println(ex.getMessage());
    }
    return "Email has been sent";
}

where updateResetPasswordToken() is:

public void updateResetPasswordToken(String token, String email) throws SQLException {
    UserDetails userDetails = usersDao.getUserDetailsByEmail(connFromUserService, email);
    if (userDetails != null) {
        User user = usersDao.getUserByName(connFromUserService, userDetails.getName());
        usersDao.setResetPasswordToken(connFromUserService, user, token);
    }
}

where getUserDetailsByEmail() is:

public UserDetails getUserDetailsByEmail(Connection connection, String email) {
    UserDetails userDetails = new UserDetails();
    PreparedStatement ps;
    try {
        ps = connection.prepareStatement("SELECT * from users_details where email = '"+email+"'");
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            userDetails = new UserDetails(rs.getString(2), rs.getString(3));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return userDetails;
}

and getUserByName() is:

public User getUserByName(Connection connection, String name) throws SQLException {
    User user = new User();
    PreparedStatement ps;
    try {
        ps = connection.prepareStatement("SELECT * from users where username = '"+name+"'");
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            user = new User(rs.getString(2), rs.getString(3));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return user;
}

and setResetPasswordToken() is:

public void setResetPasswordToken(Connection connection, User user, String token) {
    PreparedStatement ps;
    try {
        ps = connection.prepareStatement("UPDATE users set reset_password_token = '" + token + "' where username = '" + user.getUsername() + "'");
        ps.executeUpdate();
    } catch (SQLException e) {
        System.out.println(e.getMessage());
    }
}

Then user receives reset link on email. He opens link which opens Angular app and I input on two EditText fields passsword twice and send with button send which performs this code:

  public postResetPassword(token: string, password: string): Observable<any> {
    const body = {
      'token': token,
      'password': password
    };
    const headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
    return this.http.post<any>('https://endlessblow-1.herokuapp.com/reset_password', body,{headers: headers});
  }

What's strange this Angular's code generates OPTIONS request not POST why? Spring Boot app receives this request with method:

@RequestMapping(value = "/reset_password", consumes="application/json", method = {RequestMethod.OPTIONS, RequestMethod.POST, RequestMethod.GET})
public String processResetPassword(@RequestBody TokenAndPassword tokenAndPassword) {
    try {
        User user = userService.getByResetPasswordToken(tokenAndPassword.getToken());
        if (user == null) {
            return "message1";
        } else {
            userService.updatePassword(user, tokenAndPassword.getPassword());
            System.out.println("You have successfully changed your password.");
        }
    }
    catch (Exception ex) {
        System.out.println(ex.getMessage());
        return "Error. Did you use your token already? Or does this link come from email?";
    }

    return "You have successfully changed your password.";
}

But finally every time /reset_password comes then ERROR 403 shows up.

I also added such class:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
public void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .authorizeRequests().anyRequest().permitAll();
}
}

but it gives nothing.

What's wrong with this code?

Thank you very very very much for help!

The issue is most likely with the preflight request that the angular app is sending. You could disable cors by adding this to your security configuration:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedMethods("*");
}

or you can configure it to your use case by following the example from the spring documentation https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors-global-java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM