学习Spring Boot:(十六)使用Shiro与JWT 实现认证服务

本文介绍了如何在Spring Boot应用中利用Shiro和JWT进行无状态认证。详细步骤包括自定义JWT拦截器,登录过程,以及JWTUtils的使用。通过JWT,服务器端不再需要保存会话状态,简化了服务端负担,同时也便于单元测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

代码可以参考
需要把Web应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时access_token进行资源访问。这里我们将使用 JWT 1,基于散列的消息认证码,使用一个密钥和一个消息作为输入,生成它们的消息摘要。该密钥只有服务端知道。访问时使用该消息摘要进行传播,服务端然后对该消息摘要进行验证。

认证步骤

  1. 客户端第一次使用用户名密码访问认证服务器,服务器验证用户名和密码,认证成功,使用用户密钥生成JWT并返回
  2. 之后每次请求客户端带上JWT
  3. 服务器对JWT进行验证
自定义 jwt 拦截器
/**
 * oauth2拦截器,现在改为 JWT 认证
 */
public class OAuth2Filter extends FormAuthenticationFilter {
   
   
    /**
     * 设置 request 的键,用来保存 认证的 userID,
     */
    private final static String USER_ID = "USER_ID";
    @Resource
    private JwtUtils jwtUtils;

    /**
     * logger
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(OAuth2Filter.class);


    /**
     * shiro权限拦截核心方法 返回true允许访问resource,
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
   
   
        String token = getRequestToken((HttpServletRequest) request);
        try {
   
   
            // 检查 token 有效性
            //ExpiredJwtException JWT已过期
            //SignatureException JWT可能被篡改
            Jwts.parser().setSigningKey(jwtUtils.getSecret()).parseClaimsJws(token).getBody();
        } catch (Exception e) {
   
   
            // 身份验证失败,返回 false 将进入onAccessDenied 判断是否登陆。
            onLoginFail(response);
            return false;
        }
        Long userId = getUserIdFromToken(token);
        // 存入到 request 中,在后面的业务处理中可以使用
        request.setAttribute(USER_ID, userId);
        return true;
    }

    /**
     * 当访问拒绝时是否已经处理了;
     * 如果返回true表示需要继续处理;
     * 如果返回false表示该拦截器实例已经处理完成了,将直接返回即可。
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
   
   
        if (isLoginRequest(request, response)) {
   
   
            if (isLoginSubmission(request, response)) {
   
   
                return executeLogin(request, response);
            } else {
   
   
                return true
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值