Spring Security中的身份验证问题(仅检查用户名而不是密码?)
这是我使用Spring的第一个项目,我刚刚开始使用Spring Security创建登录名。我想一些网页只能访问管理员,而不是球员。我在网上找到了一些例子,这个机制运行得很好,我有一个受登录保护的安全页面,当用户没有管理员角色时,它是被禁止的Spring Security中的身份验证问题(仅检查用户名而不是密码?),spring,spring-boot,authentication,spring-security,Spring,Spring Boot,Authentication,Spring Security,这是我使用Spring的第一个项目,我刚刚开始使用Spring Security创建登录名。我想一些网页只能访问管理员,而不是球员。我在网上找到了一些例子,这个机制运行得很好,我有一个受登录保护的安全页面,当用户没有管理员角色时,它是被禁止的 @PreAuthorize("hasAuthority('ROLE_ADMIN')") @GetMapping("/secured/all") public String securedHello() { return "S
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
@GetMapping("/secured/all")
public String securedHello() {
return "Secured Hello";
}
问题是,在测试代码时,我发现Spring只对管理员(以及用户)进行用户名验证。如果我输入了错误的密码,它仍然允许我输入。我不明白这是怎么可能的,难道Spring Security不应该自己完成所有的身份验证工作吗?我看到有人建议实现身份验证管理器或类似的东西,但我不明白为什么以及如何在代码中插入它。这件事我已经坚持了两天了,请给我提些建议,我将不胜感激。
这些是我的课程:
package model;
import java.io.IOException;
import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.fasterxml.jackson.databind.ObjectMapper;
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@EnableJpaRepositories(basePackageClasses = PlayersRepository.class)
@ComponentScan(basePackageClasses= CustomUserDetailsService.class)
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(getPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//http.csrf().disable();
http.authorizeRequests()
.antMatchers("**/secured/**").access("hasAuthority('ROLE_ADMIN')")
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return true;
}
};
}
}
package model;
import java.util.ArrayList;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private PlayersRepository usersRepository;
@Autowired
private RoleRepository rolesRepository;
public CustomUserDetailsService(PlayersRepository usersRepository, RoleRepository rolesRepository) {
this.usersRepository=usersRepository;
this.rolesRepository=rolesRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<Player> optionalUser = usersRepository.findByUsername(username);
optionalUser
.orElseThrow(() -> new UsernameNotFoundException("Username not found"));
Player user= optionalUser.get();
System.out.println(user);
return toUserDetails(new UserObject(user.getUsername(),user.getPassword(),user.getRole()));
}
private UserDetails toUserDetails(UserObject userObject) {
return User.withUsername(userObject.name)
.password(userObject.password)
.roles(userObject.role).build();
}
private static class UserObject {
private String name;
private String password;
private String role;
public UserObject(String name, String password, String role) {
this.name = name;
this.password = password;
this.role = role;
}
}
}
package model;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class CustomUserDetails extends Player implements UserDetails {
String role;
public CustomUserDetails(final Player user) {
super(user);
}
public CustomUserDetails(Optional<Player> user, String role) {
super(user);
this.role=role;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
list.add(new SimpleGrantedAuthority("ROLE_"+ role));
System.out.println(list);
return list;
}
@Override
public String getPassword() {
return super.getPassword();
}
@Override
public String getUsername() {
return super.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
包模型;
导入java.io.IOException;
导入javax.naming.AuthenticationException;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.context.annotation.ComponentScan;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.data.jpa.repository.config.EnableJpaRepositories;
导入org.springframework.http.HttpStatus;
导入org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
导入org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
导入org.springframework.security.config.annotation.web.builders.HttpSecurity;
导入org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
导入org.springframework.security.config.annotation.web.configuration.websecurityConfigureAdapter;
导入org.springframework.security.core.Authentication;
导入org.springframework.security.crypto.password.PasswordEncoder;
导入com.fasterxml.jackson.databind.ObjectMapper;
@EnableGlobalMethodSecurity(Prespenabled=true)
@启用Web安全性
@EnableJpaRepositories(basePackageClasses=PlayerRepository.class)
@ComponentScan(basePackageClasses=CustomUserDetailsService.class)
@配置
公共类安全配置扩展了WebSecurity配置适配器{
@自动连线
私有customuserdetails服务userdetails服务;
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
auth.userDetailsService(userDetailsService)
.passwordEncoder(getPasswordEncoder());
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
//http.csrf().disable();
http.authorizeRequests()
.antMatchers(“**/secured/**”).access(“hasAuthority('ROLE_ADMIN'))
.anyRequest().permitAll()
.及()
.formLogin().permitAll();
}
私有密码编码器getPasswordEncoder(){
返回新的PasswordEncoder(){
@凌驾
公共字符串编码(CharSequence CharSequence){
返回charSequence.toString();
}
@凌驾
公共布尔匹配(CharSequence CharSequence,字符串s){
返回true;
}
};
}
}
包装模型;
导入java.util.ArrayList;
导入java.util.Optional;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.security.core.userdetails.User;
导入org.springframework.security.core.userdetails.userdetails;
导入org.springframework.security.core.userdetails.userdetails服务;
导入org.springframework.security.core.userdetails.UsernameNotFoundException;
导入org.springframework.stereotype.Service;
@服务
公共类CustomUserDetailsService实现UserDetailsService{
@自动连线
私人玩家存储库用户存储库;
@自动连线
私人角色存储角色存储;
public CustomUserDetails服务(播放器存储库用户存储库、角色存储库角色存储库){
this.usersRepository=usersRepository;
this.rolesRepository=rolesRepository;
}
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
可选optionalUser=usersRepository.findByUsername(用户名);
可选用户
.orelsetrow(()->new UsernameNotFoundException(“找不到用户名”);
Player user=optionalUser.get();
System.out.println(用户);
返回toUserDetails(新的UserObject(user.getUsername(),user.getPassword(),user.getRole());
}
私有用户详细信息用户详细信息(用户对象用户对象){
返回User.withUsername(userObject.name)
.password(userObject.password)
.roles(userObject.role).build();
}
私有静态类用户对象{
私有字符串名称;
私有字符串密码;
私有字符串角色;
公共用户对象(字符串名称、字符串密码、字符串角色){
this.name=名称;
this.password=密码;
this.role=角色;
}
}
}
包装模型;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.SimpleGrantedAuthority;
导入org.springframework.security.core.userdetails.userdetails;
导入java.util.ArrayList;
导入java.util.Collection;
导入java.util.List;
导入java.util.Optional;
导入java.util.stream.collector;
公共类CustomUserDetails扩展播放器实现UserDetails{
字符串角色;
公共CustomUserDetails(最终玩家用户){
超级用户;
}
公共CustomUserDetails(可选用户、字符串角色){
超级用户;
这个角色=角色;
}
@凌驾
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return true;
}
};
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return charSequence.toString.equals(s);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}