Ich wünsche Ihnen einen schönen Tag.
Ich habe ein Problem beim Überprüfen des Benutzers osamazaza200 mit dem richtigen Passwort (test123) während der Anmeldung in meiner Spring Boot-Anwendung. Trotz Angabe der richtigen Anmeldeinformationen schlägt der Authentifizierungsprozess fehl und es wird ein 403-Fehler zurückgegeben.
Schritte zum Reproduzieren
Erstellen Sie einen Benutzer mit den folgenden Anmeldeinformationen :
Benutzername: osamazaza200
Passwort: test123 (gehasht und in der Datenbank gespeichert)
Versuch anmelden Verwenden des /signin-Endpunkts mit den Anmeldeinformationen.
Beobachten Sie die Antwort, die zu einem 403 Forbidden-Fehler führt.
Relevanter Code:
Fristly: Sicherheitskonfigurationsklasse:
@Configuration
@EnableMethodSecurity
public 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();
}
}
Zweitens: 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 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);
}
}
Drittens: DTO anmelden
package com.muhammedessa.securityapicrud.dto;
import lombok.Data;
@Data
public class LoginDto {
private String usernameOrEmail;
private String password;
}
Viertens: Melden Sie sich bei DTO an
package com.muhammedessa.securityapicrud.dto;
import lombok.Data;
@Data
public class SignUpDto {
private String name;
private String username;
private String email;
private String password;
}
Fünftens: Rollenklasse
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;
}
Sechstens: Benutzerrollenklasse
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 roles;
}
Siebtens: Rollen-Repository-Klasse
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 {
Optional findByName(String name);
}
Eighty: Benutzer-Repository-Klasse
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 {
Optional findByEmail(String email);
Optional findByUsernameOrEmail(String username, String email);
Optional findByUsername(String username);
Boolean existsByUsername(String username);
Boolean existsByEmail(String email);
}
Neuntens: 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;
@Service
public 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 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);
}
}
Anwendungseigenschaften
spring.application.name=APIDemo
# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/usersdb?useSSL=false
spring.datasource.username=root
spring.datasource.password=
# Hibernate
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
Beim Ausführen der [POST]-Anfrage-API http://localhost:8080/api/auth/signup
Body
{
"Name": "Loyasl Essa",
"Benutzername": "testrer",
"E-Mail": "test123@gmail.com",
"Passwort": „12345678“
}
erhalte 403-Fehler
403 Verbotener Fehler beim Anmelden in der Spring Boot-Anwendung ⇐ Java
-
- Similar Topics
- Replies
- Views
- Last post