java Spring Security authenticate(未知源)

ulydmbyx  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(85)

我试图从Teddy Smith的YouTube教程中创建一个身份验证系统,现在我已经创建了一个注册系统,一个PasswordEncoder,一切都很好。但我无法从数据库中验证帐户,数据库中有多个用户,我无法验证,直到我理解我现在拥有的代码,但我无法解决这个错误,它从字面上停止了我的 Spring 安全培训,这是几乎完成,你能帮助我吗?
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();
}

}

现在最重要的是控制台

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]

这些授权后的线路堵塞了整个控制台,谢谢,希望大家能帮我。

aoyhnmkz

aoyhnmkz1#

我通过对用户输入的密码进行加密并对SecurityFilterChain进行调整来修复我的问题
是:

Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, passwordEncoder.encode(password)));

变成了:

Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));

SecurityFilterChain是:

@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 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();
}

增加和变更:

.defaultSuccessUrl("/home", true)
.failureUrl("/login-error")

相关问题