Quantcast
Channel: Active questions tagged rest - Stack Overflow
Viewing all articles
Browse latest Browse all 3643

403 Forbidden Error During Login in Spring Boot Application

$
0
0

Have a good day.

I am facing an issue when verifying the user osamazaza200 with the correct password (test123) during login in my Spring Boot application. Despite providing the proper credentials, the authentication process fails, and a 403 error is returned.

Steps to Reproduce

Create a user with the following credentials:

Username: osamazaza200

Password: test123 (hashed and stored in the database)

Attempt to sign in using the /signin endpoint with the credentials.

Observe the response, which results in a 403 Forbidden error.

Relevant Code:Fristly: Security Config Class:

@Configuration@EnableMethodSecuritypublic class SecurityConfig {    private UserDetailsService userDetailsService;    public SecurityConfig(UserDetailsService userDetailsService){        this.userDetailsService = userDetailsService;    }    @Bean    public static PasswordEncoder passwordEncoder(){        return new BCryptPasswordEncoder();    }    @Bean    public AuthenticationManager authenticationManager(    AuthenticationConfiguration configuration)    throws Exception {        return configuration.getAuthenticationManager();    }    @Bean    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {    http.authorizeHttpRequests((authorize) ->                        //authorize.anyRequest().authenticated()                         authorize.requestMatchers(HttpMethod.GET, "/api/**").permitAll()                                .requestMatchers("/api/auth/**").permitAll()                                .anyRequest().authenticated()                );        return http.build();    }}

Secondly: AuthController

package com.muhammedessa.securityapicrud.controllers;@RestController@RequestMapping("/api/auth")public class AuthController {    @Autowired    private AuthenticationManager authenticationManager;    @Autowired    private UserRepository userRepository;    @Autowired    private RoleRepository roleRepository;    @Autowired    private PasswordEncoder passwordEncoder;    @PostMapping("/signin")    public ResponseEntity<String> authenticateUser(@RequestBody LoginDto loginDto){        Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(                loginDto.getUsernameOrEmail(), loginDto.getPassword()));        SecurityContextHolder.getContext().setAuthentication(authentication);        return new ResponseEntity<>("User signed-in successfully!.", HttpStatus.OK);    }    @PostMapping("/signup")    public ResponseEntity<?> registerUser(@RequestBody SignUpDto signUpDto){        // add check for username exists in a DB        if(userRepository.existsByUsername(signUpDto.getUsername())){            return new ResponseEntity<>("Username is already taken!", HttpStatus.BAD_REQUEST);        }        // add check for email exists in DB        if(userRepository.existsByEmail(signUpDto.getEmail())){            return new ResponseEntity<>("Email is already taken!", HttpStatus.BAD_REQUEST);        }        // create user object        User user = new User();        user.setName(signUpDto.getName());        user.setUsername(signUpDto.getUsername());        user.setEmail(signUpDto.getEmail());        user.setPassword(passwordEncoder.encode(signUpDto.getPassword()));        Role roles = roleRepository.findByName("ROLE_ADMIN").get();        user.setRoles(Collections.singleton(roles));        userRepository.save(user);        return new ResponseEntity<>("User registered successfully", HttpStatus.OK);    }}

Thirdly: Login DTO

package com.muhammedessa.securityapicrud.dto;import lombok.Data;@Datapublic class LoginDto {    private String usernameOrEmail;    private String password;}

Fourthly: Sign UP DTO

package com.muhammedessa.securityapicrud.dto;import lombok.Data;@Datapublic class SignUpDto {    private String name;    private String username;    private String email;    private String password;}

Fifthly: Role Class

package com.muhammedessa.securityapicrud.entity;import jakarta.persistence.Column;import jakarta.persistence.Entity;import jakarta.persistence.GeneratedValue;import jakarta.persistence.GenerationType;import jakarta.persistence.Id;import jakarta.persistence.Table;import lombok.Getter;import lombok.Setter;@Setter@Getter@Entity@Table(name = "roles")public class Role {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private long id;    @Column(length = 60)    private String name;}

Sixthly: User Role Class

package com.muhammedessa.securityapicrud.entity;import java.util.Set;import jakarta.persistence.*; import lombok.Data;@Data@Entity@Table(name = "users", uniqueConstraints = {        @UniqueConstraint(columnNames = {"username"}),        @UniqueConstraint(columnNames = {"email"})})public class User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private long id;    private String name;    private String username;    private String email;    private String password;    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)    @JoinTable(name = "user_roles",        joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),        inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))    private Set<Role> roles;}

Seventhly: Role Repository Class

package com.muhammedessa.securityapicrud.repository;import java.util.Optional;import org.springframework.data.jpa.repository.JpaRepository;import com.muhammedessa.securityapicrud.entity.Role;public interface RoleRepository extends JpaRepository<Role, Long> {    Optional<Role> findByName(String name);}

Eighty: User Repository Class

package com.muhammedessa.securityapicrud.repository;import java.util.Optional;import org.springframework.data.jpa.repository.JpaRepository;import com.muhammedessa.securityapicrud.entity.User;public interface UserRepository extends JpaRepository<User, Long> {    Optional<User> findByEmail(String email);    Optional<User> findByUsernameOrEmail(String username, String email);    Optional<User> findByUsername(String username);    Boolean existsByUsername(String username);    Boolean existsByEmail(String email);}

Ninthly: CustomUserDetailsService

package com.muhammedessa.securityapicrud.services;import java.util.Set;import java.util.stream.Collectors;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.stereotype.Service;import com.muhammedessa.securityapicrud.entity.User;import com.muhammedessa.securityapicrud.repository.UserRepository;@Servicepublic class CustomUserDetailsService implements UserDetailsService {    private UserRepository userRepository;    public CustomUserDetailsService(UserRepository userRepository) {        this.userRepository = userRepository;    }    @Override    public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {          User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail)                 .orElseThrow(() ->                         new UsernameNotFoundException("User not found with username or email: "+ usernameOrEmail));        Set<GrantedAuthority> authorities = user                .getRoles()                .stream()                .map((role) -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toSet());        return new org.springframework.security.core.userdetails.User(user.getEmail(),                user.getPassword(),                authorities);    }}

Application Properties

spring.application.name=APIDemo# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)spring.datasource.url=jdbc:mysql://127.0.0.1:3306/usersdb?useSSL=falsespring.datasource.username=rootspring.datasource.password= # Hibernate# The SQL dialect makes Hibernate generate better SQL for the chosen databasespring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect# Hibernate ddl auto (create, create-drop, validate, update)spring.jpa.hibernate.ddl-auto = updatelogging.level.org.hibernate.SQL=DEBUGlogging.level.org.hibernate.type=TRACE

When running [POST] request API http://localhost:8080/api/auth/signup

Body

{"name": "Loyasl Essa","username": "testrer","email": "test123@gmail.com","password": "12345678"}

getting 403 error


Viewing all articles
Browse latest Browse all 3643

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>