1:引入SpringSecurity jar包
代码中还用到了 插件lombok, 没有引入的话 还需要引入 lombok
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2: 在resources文件夹下的static包内放入你的登录html文件
没有static文件夹的,自己创建个.
注意: form表单中的 action 必须要和步骤 4 中的loginProcessingUrl (" ")一致
表单中的 用户名 name值 和密码name值 必须为 username 和password
<form action="/loginPost" method="post">
账户<input type="text" name="username">
密码<input type="text" name="password">
<button type="submit">登录</button>
</form>
3 创建User实体类
该实体类需要实现UserDetails 接口
package com.example.demo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.validation.constraints.NotEmpty;
import java.util.Collection;
import java.util.Date;
/**
* 普通用户实体类
*/
@AllArgsConstructor
@Data
public class User implements UserDetails {
private Integer id;
private String username;
private String password;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
4:创建Security配置类 WebSecurityConfig
该类继承 WebSecurityConfigurerAdapter , 并重写 configure方法, 该类主要是对访问的资源进行拦截 放行.
package com.example.demo.security;
import com.example.demo.token.TokenUtil;
import lombok.AllArgsConstructor;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@AllArgsConstructor
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService; //这个类需要进行密码验证
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.formLogin()
.loginPage("/login.html") //loginPage为自定义的登录页面,与你在static下的登录html文件名一致
.loginProcessingUrl("/loginPost") //loginProcessingUrl 为登录的路径,与你form表单填写的路径一致.
.defaultSuccessUrl("/index.html").failureUrl("/login?error=true") ; //设置登录成功后的跳转页面,error=true控制页面错误信息的展示
}
//将密码进行加密验证, 目前Security密码必须加密
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
}
5:创建 UserDetailsService 实现类
package com.example.demo.security;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
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.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
@Service("userDetailsService")
public class LoginSecurityImple implements UserDetailsService {
@Autowired
private UserService userService; //需要查找数据库中用户名是否存在
//UserService 是自己写的类, 爆红的话,建议自己写一个(这是基础知识就不写了)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//username 为前端传递过来的用户名
//根据用户名在数据库中查找是否存在 并返回一个用户实体类
User user =userService.selectUserByName(username);
//用户名存在,将查找到的用户密码进行加密 ,不加密会报错
user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()) );
//将查询到的用户返回给 WebSecurityConfig类,然后由Security自己对比密码是否一致
return user;
}
}