英文:
Spring Security authenticate(Unknown source)
问题
You seem to be experiencing an issue related to your Spring Security configuration, specifically with authentication. The error messages in your console indicate that the problem occurs during the authentication process. Unfortunately, I can't analyze the entire code or provide a specific solution based on the information given here.
To troubleshoot this issue, you should check the following:
-
Ensure that your user data is correctly stored in the database, and the UserEntity class mapping is accurate.
-
Verify that you have the necessary dependencies and configurations in your project related to Spring Security.
-
Check your CustomUserDetailsService class and its loadUserByUsername method to make sure it correctly loads user details from the database.
-
Ensure your RoleEntity class and RoleRepository are set up correctly.
-
Check your SecurityConfig class for any misconfigurations related to URL permissions and user roles.
-
Look into the specific error messages in your console logs for more details about what went wrong.
If you need further assistance, consider providing more specific error messages or details about the issue you're facing. You might also seek help on developer forums or communities, where experts can analyze your code more thoroughly.
英文:
I'm trying to create an authentication system from Teddy Smith's YouTube tutorials, now I've created a registration system, a PasswordEncoder and everything is fine. but I can't authenticate the account from the database, there are multiple users in the database and I can't authenticate until I understand the code I have right now, but I can't solve this error, it literally stopped my Spring Security training which is almost finished, can you help me with this?
UserEntity.class:
package springsecuritylearn.entity;
import java.util.ArrayList;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
@Entity
@Table(name = "users")
public class UserEntity {
@Id
@SequenceGenerator(name = "user_sequence", sequenceName = "user_sequence", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_sequence")
private long id;
private String username;
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 List<RoleEntity> roles = new ArrayList<>();
public UserEntity() {}
public UserEntity(String username, String password, List<RoleEntity> roles) {
this.username = username;
this.password = password;
this.roles = roles;
}
public long getId() {
return id;
}
public void setId(long 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 List<RoleEntity> getRoles() {
return roles;
}
public void setRoles(List<RoleEntity> roles) {
this.roles = roles;
}
}
RoleEntity.class:
package springsecuritylearn.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
@Entity
@Table(name = "roles")
public class RoleEntity {
@Id
@SequenceGenerator(name = "role_sequence", sequenceName = "role_sequence", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "role_sequence")
private long id;
private String name;
public RoleEntity() {}
public RoleEntity(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
AuthController.class:
package springsecuritylearn.controller;
import java.util.Collections;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import springsecuritylearn.entity.RoleEntity;
import springsecuritylearn.entity.UserEntity;
import springsecuritylearn.repository.RoleRepository;
import springsecuritylearn.repository.UserRepository;
@Controller
@RequestMapping("/")
public class AuthController {
private AuthenticationManager authenticationManager;
private PasswordEncoder passwordEncoder;
private UserRepository userRepository;
private RoleRepository roleRepository;
@Autowired
public AuthController(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder,
UserRepository userRepository, RoleRepository roleRepository) {
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String userAuthenticate(
UserEntity userEntity,
@RequestParam String username,
@RequestParam String password,
Map<String, Object> model) {
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/home";
}
@GetMapping("/register")
public String register() {
return "register";
}
@PostMapping("/register")
private String addNewUser(
@RequestParam String username,
@RequestParam String password,
Map<String, Object> model) {
if (userRepository.existsByUsername(username)) {
return "register";
}
RoleEntity roles = roleRepository.findByName("USER").orElse(null);
UserEntity user = new UserEntity(username, passwordEncoder.encode(password), Collections.singletonList(roles));
userRepository.save(user);
return "redirect:/login";
}
}
WebController.class:
package springsecuritylearn.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(path = "/")
public class WebController {
@GetMapping(path = "/home")
public String home() {
return "home";
}
@GetMapping(path = "/user")
public String user() {
return "user";
}
@GetMapping(path = "/admin")
public String admin() {
return "admin";
}
}
UserRepository.interface:
package springsecuritylearn.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import springsecuritylearn.entity.UserEntity;
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByUsername(String username);
Boolean existsByUsername(String username);
}
RoleRepository.interface:
package springsecuritylearn.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import springsecuritylearn.entity.RoleEntity;
@Repository
public interface RoleRepository extends JpaRepository<RoleEntity, Long> {
Optional<RoleEntity> findByName(String name);
}
CustomUserDetailsService.class:
package springsecuritylearn.security;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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 springsecuritylearn.entity.RoleEntity;
import springsecuritylearn.entity.UserEntity;
import springsecuritylearn.repository.UserRepository;
@Service
public class CustomUserDetailsService implements UserDetailsService {
private UserRepository userRepository;
@Autowired
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserEntity user = userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("Username not found"));
return new User(user.getUsername(), user.getPassword(), mapRolesToAuthorities(user.getRoles()));
}
private Collection<GrantedAuthority> mapRolesToAuthorities(List<RoleEntity> roles) {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
}
}
SecurityConfig.class:
package springsecuritylearn.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity
@Configuration
public class SecurityConfig {
private CustomUserDetailsService userDetailsService;
@Autowired
public SecurityConfig(CustomUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/", "/register").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/home")
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic()
.disable();
return http.build();
}
@Bean
public UserDetailsService users() {
UserDetails user1 = User.builder()
.username("august")
.password("{noop}august")
.roles("ADMIN")
.build();
UserDetails user2 = User.builder()
.username("maksim")
.password("{noop}maksim")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user1, user2);
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
And now the most important thing, console:
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.7.jar:6.0.7]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:211) ~[spring-aop-6.0.7.jar:6.0.7]
at jdk.proxy7/jdk.proxy7.$Proxy133.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
These lines after authorization clogged the entire console, thank you, i hope you can help me.
答案1
得分: 0
I fixed my problem by encrypting the password that the user enters and making adjustments to SecurityFilterChain.
Was:
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, passwordEncoder.encode(password)));
Became:
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
SecurityFilterChain was:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/","/register").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/home")
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic()
.disable();
return http.build();
}
Became:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/", "/register").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/home", true)
.failureUrl("/login-error")
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic()
.disable();
return http.build();
}
Added and changed:
.defaultSuccessUrl("/home", true)
.failureUrl("/login-error")
英文:
I fixed my problem by encrypting the password that the user enters and making adjustments to SecurityFilterChain
was:
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, passwordEncoder.encode(password)));
became:
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
SecurityFilterChain was:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/", "/register").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/home")
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic()
.disable();
return http.build();
}
became:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/", "/register").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/home", true)
.failureUrl("/login-error")
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.httpBasic()
.disable();
return http.build();
}
Added and changed:
.defaultSuccessUrl("/home", true)
.failureUrl("/login-error")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论