SpringBoot学习笔记【三】整合 Security + JWT + 异常处理 您所在的位置:网站首页 过滤器异常处理 SpringBoot学习笔记【三】整合 Security + JWT + 异常处理

SpringBoot学习笔记【三】整合 Security + JWT + 异常处理

2024-07-15 14:26| 来源: 网络整理| 查看: 265

目录

一、添加依赖

二、配置

(一)JWT

(二)Security

(三)异常处理

三、总结

一、添加依赖

Spring Security是后台开发中经常使用的身份认证和访问权限控制框架,集成起来十分简单,对Restful接口的支持也比较完备,至于更多的介绍,可以参考 Spring Security 参考手册,在pom.xml中添加依赖如下:

org.springframework.boot spring-boot-starter-security

JWT(Json Web Token)定义了一种简洁的,自包含的信息传递规范,在目前前后端分离的架构环境下使用十分频繁,但JWT也存在一定的局限性,在具体的业务场景下通常无法直接代替通常意义上的session,带着学习的目的,我们可以尝试一下简单的使用,详细介绍可以参考 JWT介绍,在pom.xml中添加依赖如下:

io.jsonwebtoken jjwt 0.9.0 二、配置 (一)JWT

JWT的配置相对来讲是比较简单的,主要包括两个部分:1. 定义Token生成和解析的方法;2. 定义Token验证过滤器,话不多说,直接贴代码:

1. 定义Token的生成和解析

/** * Author GreedyStar * Date 2018/7/18 */ public class JwtUtil { /** * 解析Token * * @param jsonWebToken Token String * @param base64Security Base64Security Key * @return */ public static Claims parseToken(String jsonWebToken, String base64Security) { try { Claims claims = Jwts.parser().setSigningKey(base64Security).parseClaimsJws(jsonWebToken).getBody(); return claims; } catch (Exception ex) { return null; } } /** * 生成Token * * @param username 用户名 * @param property 自定义的jwt公共属性(包括超时时长、签发者、base64Security key) * @return */ public static String createToken(String username, JwtProperty property) { Calendar calendar = Calendar.getInstance(); JwtBuilder builder = Jwts.builder() .setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256") .claim("username", username) .setIssuer(property.getIssuer()) .signWith(SignatureAlgorithm.HS256, property.getBase64Security()) .setExpiration(new Date(calendar.getTimeInMillis() + property.getExpiry())).setNotBefore(calendar.getTime()); return builder.compact(); } }

2. 定义Token验证过滤器

/** * Token验证过滤器 *

* Author GreedyStar * Date 2018/7/20 */ public class JwtAuthenticationFilter extends OncePerRequestFilter{ private JwtProperty jwtProperty; public JwtAuthenticationFilter(JwtProperty jwtProperty) { this.jwtProperty = jwtProperty; } @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { httpServletResponse.setContentType("application/json"); String authorization = httpServletRequest.getHeader("Authorization"); // 放行GET请求 if (httpServletRequest.getMethod().equals(String.valueOf(RequestMethod.GET))) { filterChain.doFilter(httpServletRequest, httpServletResponse); return; } if (StringUtils.isEmpty(authorization)) { // 未提供Token httpServletResponse.getWriter().write(JSON.toJSONString(new Response.Builder().setStatus(403).setMessage("Token not provided").build())); return; } if (!authorization.startsWith("bearer ")) { // Token格式错误 httpServletResponse.getWriter().write(JSON.toJSONString(new Response.Builder().setStatus(403).setMessage("Token format error").build())); return; } authorization = authorization.replace("bearer ", ""); Claims claims = JwtUtil.parseToken(authorization, jwtProperty.getBase64Security()); if (null == claims) { // Token不可解码 httpServletResponse.getWriter().write(JSON.toJSONString(new Response.Builder().setStatus(403).setMessage("Can't parse token").build())); return; } if (claims.getExpiration().getTime() >= new Date().getTime()) { // Token超时 httpServletResponse.getWriter().write(JSON.toJSONString(new Response.Builder().setStatus(403).setMessage("Token expired").build())); return; } // 再进行一些必要的验证 if (StringUtils.isEmpty(claims.get("username"))) { httpServletResponse.getWriter().write(JSON.toJSONString(new Response.Builder().setStatus(403).setMessage("Invalid token").build())); return; } filterChain.doFilter(httpServletRequest, httpServletResponse); } }

OK,JWT的简单配置就完成了,这里只是对JWT的简单使用,在通常的开发中还需要更复杂的处理逻辑,比如通常的访问Token,刷新Token等,这里就不详细说了。

(二)Security

1. 修改数据库

首先,修改一下数据库表结构,修改之后共有用户表、角色表、用户角色关系表,ER图如下:

角色表里共有两条数据,这两个角色是我们后续进行访问权限控制的基础,如下所示:

2. 修改User类,实现UserDetails接口

UserDetails是Security提供的一个接口,其中定义了一系列用于判断User状态和权限的方法,User实体如下所示:

public class User extends BaseEntity implements UserDetails { private static final long serialVersionUID = 1L; private String username; private String password; private List roles; // 从数据库查询出的Role public void setUsername(String username) { this.username = username; } @Override public String getUsername() { return this.username; } public void setPassword(String password) { this.password = password; } @Override @JsonIgnore public String getPassword() { return this.password; } public List getRoles() { return roles; } public void setRoles(List roles) { this.roles = roles; } @Override @JsonIgnore public Collection


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有