Spring Boot Security 整合 JWT 实现 无状态的分布式API接口

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
permission_id bigint(11) NOT NULL

);

CREATE TABLE permission (

id bigint(11) NOT NULL AUTO_INCREMENT,

url varchar(255) NOT NULL,

name varchar(255) NOT NULL,

description varchar(255) NULL,

pid bigint(11) NOT NULL,

PRIMARY KEY (id)

);

INSERT INTO user (id, username, password) VALUES (1,‘user’,‘e10adc3949ba59abbe56e057f20f883e’);

INSERT INTO user (id, username , password) VALUES (2,‘admin’,‘e10adc3949ba59abbe56e057f20f883e’);

INSERT INTO role (id, name) VALUES (1,‘USER’);

INSERT INTO role (id, name) VALUES (2,‘ADMIN’);

INSERT INTO permission (id, url, name, pid) VALUES (1,‘/user/hi’,‘’,0);

INSERT INTO permission (id, url, name, pid) VALUES (2,‘/admin/hi’,‘’,0);

INSERT INTO user_role (user_id, role_id) VALUES (1, 1);

INSERT INTO user_role (user_id, role_id) VALUES (2, 1);

INSERT INTO user_role (user_id, role_id) VALUES (2, 2);

INSERT INTO role_permission (role_id, permission_id) VALUES (1, 1);

INSERT INTO role_permission (role_id, permission_id) VALUES (2, 1);

INSERT INTO role_permission (role_id, permission_id) VALUES (2, 2);

项目结构


resources

|___application.yml

java

|___com

| |____gf

| | |____SpringbootJwtApplication.java

| | |____config

| | | |____.DS_Store

| | | |____SecurityConfig.java

| | | |____MyFilterSecurityInterceptor.java

| | | |____MyInvocationSecurityMetadataSourceService.java

| | | |____MyAccessDecisionManager.java

| | |____entity

| | | |____User.java

| | | |____RolePermisson.java

| | | |____Role.java

| | |____mapper

| | | |____PermissionMapper.java

| | | |____UserMapper.java

| | | |____RoleMapper.java

| | |____utils

| | | |____JwtTokenUtil.java

| | |____controller

| | | |____AuthController.java

| | |____filter

| | | |____JwtTokenFilter.java

| | |____service

| | | |____impl

| | | | |____AuthServiceImpl.java

| | | | |____UserDetailsServiceImpl.java

| | | |____AuthService.java

关键代码


pom.xml

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-security

io.jsonwebtoken

jjwt

0.9.0

mysql

mysql-connector-java

runtime

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.0.0

application.yml

spring:

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/spring-security-jwt?useUnicode=true&characterEncoding=utf-8&useSSL=false

username: root

password: root

SecurityConfig

@Configuration

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

private UserDetailsService userDetailsService;

@Autowired

public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

//校验用户

auth.userDetailsService( userDetailsService ).passwordEncoder( new PasswordEncoder() {

//对密码进行加密

@Override

public String encode(CharSequence charSequence) {

System.out.println(charSequence.toString());

return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());

}

//对密码进行判断匹配

@Override

public boolean matches(CharSequence charSequence, String s) {

String encode = DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());

boolean res = s.equals( encode );

return res;

}

} );

}

@Override

protected void configure(HttpSecurity http) throws Exception {

http.csrf().disable()

//因为使用JWT,所以不需要HttpSession

.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS).and()

.authorizeRequests()

//OPTIONS请求全部放行

.antMatchers( HttpMethod.OPTIONS, “/**”).permitAll()

//登录接口放行

.antMatchers(“/auth/login”).permitAll()

//其他接口全部接受验证

.anyRequest().authenticated();

//使用自定义的 Token过滤器 验证请求的Token是否合法

http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

http.headers().cacheControl();

}

@Bean

public JwtTokenFilter authenticationTokenFilterBean() throws Exception {

return new JwtTokenFilter();

}

@Bean

@Override

public AuthenticationManager authenticationManagerBean() throws Exception {

return super.authenticationManagerBean();

}

}

JwtTokenUtil

欢迎工作一到五年的Java工程师朋友们加入Java架构开发:828697593 本群提供免费的学习指导 架构资料 以及免费的解答

/**

  • JWT 工具类

*/

@Component

public class JwtTokenUtil implements Serializable {

private static final String CLAIM_KEY_USERNAME = “sub”;

/**

  • 5天(毫秒)

*/

private static final long EXPIRATION_TIME = 432000000;

/**

  • JWT密码

*/

private static final String SECRET = “secret”;

/**

  • 签发JWT

*/

public String generateToken(UserDetails userDetails) {

Map<String, Object> claims = new HashMap<>(16);

claims.put( CLAIM_KEY_USERNAME, userDetails.getUsername() );

return Jwts.builder()

.setClaims( claims )

.setExpiration( new Date( Instant.now().toEpochMilli() + EXPIRATION_TIME ) )

.signWith( SignatureAlgorithm.HS512, SECRET )

.compact();

}

/**

  • 验证JWT

*/

public Boolean validateToken(String token, UserDetails userDetails) {

User user = (User) userDetails;

String username = getUsernameFromToken( token );

return (username.equals( user.getUsername() ) && !isTokenExpired( token ));

}

/**

  • 获取token是否过期

*/

public Boolean isTokenExpired(String token) {

Date expiration = getExpirationDateFromToken( token );

return expiration.before( new Date() );

}

/**

  • 根据token获取username

*/

public String getUsernameFromToken(String token) {

String username = getClaimsFromToken( token ).getSubject();

return username;

}

/**

  • 获取token的过期时间

*/

public Date getExpirationDateFromToken(String token) {

Date expiration = getClaimsFromToken( token ).getExpiration();

return expiration;

}

/**

  • 解析JWT

*/

private Claims getClaimsFromToken(String token) {

Claims claims = Jwts.parser()

.setSigningKey( SECRET )

.parseClaimsJws( token )

.getBody();

return claims;

}

}

JwtTokenFilter

@Component

public class JwtTokenFilter extends OncePerRequestFilter {

@Autowired

private UserDetailsService userDetailsService;

@Autowired

private JwtTokenUtil jwtTokenUtil;

/**

  • 存放Token的Header Key

*/

public static final String HEADER_STRING = “Authorization”;

@Override

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

总结

其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。

这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来

目录:

部分内容截图:


《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
erride

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {

总结

其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。

这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来

目录:

[外链图片转存中…(img-GsExJUn4-1714746702865)]

部分内容截图:

[外链图片转存中…(img-0cq5suWo-1714746702865)]

[外链图片转存中…(img-vEto4ArF-1714746702866)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 23
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值