2 springsecurity-jwt整合
专注于分享Java领域干货文章http://www.javaman.cn/sb2/jwt
2.1整合springsecurity
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.2认证授权流程
1、用户提交用户名、密码被SecurityFilterChain中的 UsernamePasswordAuthenticationFilter 过滤器获取到,封装为请求Authentication,通常情况下是UsernamePasswordAuthenticationToken这个实现类。
3、认证成功后,AuthenticationManager 身份管理器返回一个被填充满了信息的(包括上面提到的权限信息,身份信息,细节信息,但密码通常会被移除) Authentication 实例。
授权管理
2.3编写自己的UserDetails和UserDetailService
2.3.1UserDetails
package com.ds.book.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Collection;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
/**
* <p>
*
* </p>
*
* @author java大师
* @since 2023-03-17
*/
@Data
@EqualsAndHashCode(callSuper = false
@Accessors(chain = true
@TableName("t_user"
public class User implements Serializable, UserDetails {
private static final long serialVersionUID = 1L;
private Integer id;
/**
* 登录名
*/
private String name;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 是否有效:1-有效;0-无效
*/
private String status;
@Override
public Collection<? extends GrantedAuthority> getAuthorities( {
return roles
.stream(
.map(role -> new SimpleGrantedAuthority(role.getRoleCode(
.collect(Collectors.toList(;
}
@Override
public boolean isAccountNonExpired( {
return true;
}
@Override
public boolean isAccountNonLocked( {
return true;
}
@Override
public boolean isCredentialsNonExpired( {
return true;
}
@Override
public boolean isEnabled( {
return true;
}
}
2.3.2userDetailService
登录成功后,将UserDetails的roles设置到用户中
package com.ds.book.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ds.book.entity.User;
import com.ds.book.mapper.UserMapper;
import com.ds.book.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* <p>
* 服务实现类
* </p>
*
* @author java大师
* @since 2023-03-17
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService, UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username throws UsernameNotFoundException {
User loginUser = userMapper.selectOne(new QueryWrapper<User>(.eq("username", username;
if (loginUser == null{
throw new UsernameNotFoundException("用户名或密码错误";
}
loginUser.setRoles(userMapper.getRolesByUserId(loginUser.getId(;
return loginUser;
}
}
2.3.2加载userDetailService
将我们自己的UserDetailService注入springsecurity
package com.ds.book.config;
import com.ds.book.filter.JwtTokenFilter;
import com.ds.book.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserServiceImpl userService;
@Bean
public PasswordEncoder passwordEncoder({
return new BCryptPasswordEncoder(;
}
//注入我们自己的UserDetailService
@Override
protected void configure(AuthenticationManagerBuilder auth throws Exception {
auth.userDetailsService(userService.passwordEncoder(passwordEncoder(;
}
}
问题:前后端分离项目,通常不会使用springsecurity自带的登录界面,登录界面由前端完成,后台只需要提供响应的服务即可,且目前主流不会采用session去存取用户,后端会返回响应的token,前端访问的时候,会在headers里面带入token。
2.4JwtToken
2.4.1 JWT描述
Jwt token由Header、Payload、Signature三部分组成,这三部分之间以小数点”.”连接,JWT token长这样:
token解析后长这样:
header部分,有令牌的类型(JWT和签名算法名称(HS256:
{
"alg": "HS256",
"typ": "JWT"
}
Payload部分,有效负载,这部分可以放任何你想放的数据:
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
HMACSHA256(
base64UrlEncode(payload,