1、实现UserDetails接口
User.java
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class User implements UserDetails {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}
2、实现UserDetailsService接口
UserDetailsServiceImpl.java
package org.example.security;
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("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = null;
# 先演示三个固定的账号,后面再演示数据源方式
if (username.equals("user1")) {
user = new User(username, "111111");
}
if (username.equals("user2")) {
user = new User(username, "222222");
}
if (username.equals("user3")) {
user = new User(username, "333333");
}
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
return user;
}
}
3、实现AuthenticationProvider接口
UserAuthenticationProvider
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
/**
* 自定义认证处理
*/
@Component("authenticationProvider")
public class UserAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (!password.equals(userDetails.getPassword())) {
throw new BadCredentialsException("密码不正确,请重新登录!");
}
return new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities());
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}
4、重写UserWebSecurityConfigurerAdapter方法
提供自定义验证
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class UserWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
//自定义认证逻辑处理
@Autowired
private UserAuthenticationProvider authenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//禁用csrf
.csrf()
.disable()
//用户登录
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")//自定义登录请求路径
//请求过滤
.and()
.authorizeRequests()
.antMatchers("/login.html", "/login").anonymous()//登录页与登录请求,只允许匿名访问
.anyRequest().authenticated();//除此之外,其他请求均需要登录后才可以访问
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
}
5、启动项目
这时发现,控制台中没有再提供默认密码了。标识我们自定义认证配置成功了。
6、访问登录页并测试
分别用账号user1、user2、user3测试,均登录成功。
用其他账号测试,登录失败