广告
返回顶部
首页 > 资讯 > 数据库 >shiro、jwt、redis整合
  • 434
分享到

shiro、jwt、redis整合

shirojwtredis整合 2019-07-08 16:07:43 434人浏览 无得
摘要

shiro、Jwt、Redis、SpringBoot整合 shiro、jwt、redis整合 一、步骤 1.导入坐标 org.crazycake shiro-redis-s

shiro、jwt、redis整合

shiroJwtRedisSpringBoot整合

shiro、jwt、redis整合

一、步骤

1.导入坐标



    org.crazycake
    shiro-redis-spring-boot-starter
    3.2.1

 
 
     io.JSONWEBtoken
     jjwt
     0.9.1

2.编写ShiroConfig

目的:实现session共享

session共享

HTTP协议(1.1)是无状态的,所以服务器在需要识别用户访问的时候,就要做相应的记录用于跟踪用户操作,这个实现机制就是Session。当一个用户第一次访问服务器的时候,服务器就会为用户创建一个Session,每个Session都有一个唯一的SessionId(应用级别)用于标识用户。

因此要使用shiro继承redis

使用redis管理session能够方便的实现session集群,并且在服务重启(或服务器重启)时不会丢失session。

package com.gyb.config;

import com.gyb.shiro.AccountRealm;
import com.gyb.shiro.JwtFilter;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Autowired
    JwtFilter jwtFilter;

    @Bean
    public SessionManager sessionManager(RedisSessionDAO redisSessionDAO) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();

        sessionManager.setSessionDAO(redisSessionDAO);
        return sessionManager;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(AccountRealm accountRealm,
                                                   SessionManager sessionManager,
                                                   RedisCacheManager redisCacheManager) {

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm);

        securityManager.setSessionManager(sessionManager);

        securityManager.setCacheManager(redisCacheManager);
        return securityManager;
    }

    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

        Map filterMap = new LinkedHashMap<>();

        //将所有的过滤交给自定义的jwt来做
        filterMap.put("
@Configuration
public class CorsConfig implements WebmvcConfigurer {

    @Override
    public void addCorsMappings(CorsReGIStry registry) {
        registry.addMapping("
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        JwtToken jwtToken = (JwtToken) token;

        String userId = jwtUtils.getClaimByToken((String) jwtToken.getPrincipal()).getSubject();

        User user = userService.getById(Long.valueOf(userId));
        if (user == null) {
            throw new UnknownAccountException("账户不存在");
        }

        if (user.getStatus() == -1) {
            throw new LockedAccountException("账户已被定");
        }

        AccountProfile profile = new AccountProfile();
        BeanUtil.copyProperties(user, profile);

        return new SimpleAuthenticationInfo(profile, jwtToken.getCredentials(), getName());
    }
}

4.3 创建JwtFifter类

package com.gyb.shiro;

import cn.hutool.json.JSONUtil;
import com.gyb.common.lang.Result;
import com.gyb.util.JwtUtils;
import io.jsonwebtoken.Claims;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.Http.httpservletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtFilter extends AuthenticatingFilter {

    @Autowired
    JwtUtils jwtUtils;

    @Override
    protected AuthenticationToken createToken(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String jwt = request.getHeader("Authorization");
        if(!StringUtils.hasLength(jwt) ) {
            return null;
        }

        return new JwtToken(jwt);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String jwt = request.getHeader("Authorization");
        if(!StringUtils.hasLength(jwt)) {
            return true;
        } else {

            // 校验jwt
            Claims claim = jwtUtils.getClaimByToken(jwt);
            if(claim == null || jwtUtils.isTokenExpired(claim.getExpiration())) {
                throw new ExpiredCredentialsException("token已失效,请重新登录");
            }

            // 执行登录
            return executeLogin(servletRequest, servletResponse);
        }
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {

        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        Throwable throwable = e.getCause() == null ? e : e.getCause();
        Result result = Result.fail(throwable.getMessage());
        String json = JSONUtil.toJsonStr(result);

        try {
            httpServletResponse.getWriter().print(json);
        } catch (IOException ioException) {

        }
        return false;
    }

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {

        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
        httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
        // 跨域时会首先发送一个OPTIONS请求,这里我们给OPTIONS请求直接返回正常状态
        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
            httpServletResponse.setStatus(org.springframework.http.HttpStatus.OK.value());
            return false;
        }
        return super.preHandle(request, response);
    }
}

4.4 创建JwtToken类

package com.gyb.shiro;

import org.apache.shiro.authc.AuthenticationToken;

public class JwtToken implements AuthenticationToken {

    private String token;

    public JwtToken(String jwt) {
        this.token = jwt;
    }

    @Override
    public Object getPrincipal() {
        return token;
    }

    @Override
    public Object getCredentials() {
        return token;
    }
}

5.创建util包

JwtUtil: 1.在用户调用登录接口时,生成jwt

​ 2.获取token的Claims对象的方法,Claims大家可以理解为jwt明文的报文体结构,在验证的时候可以通过获取其到当前请求的用 户payload信息。

​ 3.判定token是否过期

ShiroUtil: 只有一行代码,我是为了简便= =,(也可以不写此类)

​ 用于获取当前用户的Principal

5.1 JwtUtil

package com.gyb.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlGorithm;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;


@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "gyb.jwt")
public class JwtUtils {

    private String secret;
    private long expire;
    private String header;

    
    public String generateToken(long userId) {
        Date nowDate = new Date();
        //过期时间
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);

        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(userId+"")
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    public Claims getClaimByToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
        }catch (Exception e){
            log.debug("validate is token error ", e);
            return null;
        }
    }

    
    public boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }
}

5.2 ShiroUtil

package com.gyb.util;import com.gyb.shiro.AccountProfile;import org.apache.shiro.SecurityUtils;public class ShiroUtil {    public static AccountProfile getProfile() {        return (AccountProfile) SecurityUtils.getSubject().getPrincipal();    }}
您可能感兴趣的文档:

--结束END--

本文标题: shiro、jwt、redis整合

本文链接: https://www.lsjlt.com/news/8786.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • shiro、jwt、redis整合
    shiro、jwt、redis、SpringBoot整合 shiro、jwt、redis整合 一、步骤 1.导入坐标 org.crazycake shiro-redis-s...
    99+
    2019-07-08
    shiro jwt redis整合
  • SpringBoot集成整合JWT与Shiro流程详解
    目录前言实战演练代码结构SQL脚本pom依赖UserJwtUtilUserMapperUserServiceUserServiceImplJwtTokenMyRealmJWTFilt...
    99+
    2022-12-08
    SpringBoot Shiro SpringBoot JWT SpringBoot集成JWT与Shiro
  • springboot整合Shiro
    目录什么是ShiroShiro的三大核心概念Shiro功能介绍Springboot整合Shiro导入依赖javaConfigRealmControllerShiro整合thymele...
    99+
    2022-11-12
  • SpringBoot整合Shiro和Redis的示例代码
    目录1.准备工作2.编写index,login,register三个JSP3.实现User、Role、Permission三个POJO4.实现Controller、Service、D...
    99+
    2022-11-13
  • 【SpringBoot整合JWT】
    目录 一、什么是JWT 二、JWT能做什么  三、为什么是JWT  1、基于传统的Session认证 2、基于JWT认证 四、JWT的结构是什么  五、JWT的第一个程序 六、封装JWT工具类  七、整合SpringBoot使用 一、什...
    99+
    2023-09-01
    spring boot 后端 java
  • SpringBoot与Shiro整合
    一,Shiro 体系结构 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的...
    99+
    2023-10-02
    spring boot java spring mysql 系统安全
  • SpringBoot+SpringSecurity+JWT整合
    SpringSecurity+JWT整合 1.简介 SpringSecurity是spring的一个安全管理框架,相比另一个安全框架shiro,它提供了更丰富的功能,社区资源也比shiro丰富。 web应用主要用于认证和授权 认证:...
    99+
    2023-09-06
    java spring boot Powered by 金山文档
  • springboot使用shiro-整合redis作为缓存的操作
    说在前面 本来的整合过程是顺着博客的顺序来的,越往下,集成的越多,由于之前是使用ehcache缓存,现在改为redis,限制登录人数 以及 限制登录次数等 都需要改动,本篇为了简单,...
    99+
    2022-11-12
  • JWT如何整合Springboot
    这篇文章将为大家详细讲解有关JWT如何整合Springboot,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.基于JWT认证1.1 认证流程首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。...
    99+
    2023-06-21
  • ssm整合shiro使用详解
    目录整合shiro:1.在pom.xml中引入依赖2.新建并配置缓存ehcache.xml3.在spring配置文件applicationContext.xml配置shiro4.自定...
    99+
    2022-11-12
  • 详解Javaspringboot整合Shiro框架
    目录Shiro介绍Springboot整合ShiroShiro整合Thymeleaf总结Shiro介绍 Shiro是一款安全框架,主要的三个类Subject、SecurityMana...
    99+
    2022-11-12
  • SpringBoot整合JWT Token的完整步骤
    目录背景一  JWT 消息构成1.1 组成1.2 header1.3 playload1.4 signature二 Spring Boot 和 JWT集成实例2.1 项目依...
    99+
    2022-11-12
  • springboot整合shiro之thymeleaf使用shiro标签的方法
    thymeleaf介绍 简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下三个极...
    99+
    2022-11-12
  • shiro整合swagger的注意事项
    swagger是一个很好的rest api管理工具,最近又整合了基于shiro的权限控制,出问题了,http://localhost:8080/swagger-ui.html访问不...
    99+
    2022-11-12
  • Springboot整合knife4j与shiro的操作
    一、介绍knife4j 增强版本的Swagger 前端UI,取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍,更名也是希望把她做成一个为Swagger接口文档服务的...
    99+
    2022-11-12
  • springboot整合shiro的过程详解
    目录什么是 ShiroShiro 架构Shiro 架构图Shiro 工作原理Shiro 详细架构图springboot 整合 shirospringboot 整合 shiro 思路项...
    99+
    2022-11-12
  • SpringBoot整合Shiro的方法详解
    目录1.Shito简介1.1 什么是shiro1.2 有哪些功能2.QuickStart3.SpringBoot中集成1.导入shiro相关依赖2.自定义UserRealm3.定义s...
    99+
    2022-11-13
  • SpringBoot整合Shiro的代码详解
    shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/  它提供了很方便的权限认证和登录的功能.  而springboot作为一个开源框架,必然提供了和shiro整合的功能!接下来就用...
    99+
    2023-05-31
    spring boot shiro
  • SpringBoot详解整合JWT教程
    目录1、概述2、优势所在3、结构组成3.1、标头(Header)3.2、有效负载(Payload)3.3、签名(Signature)4、Spring boot整合JWT 导入依赖1、...
    99+
    2022-11-13
  • shiro 与 SpringMVC的整合完美示例
    想要整合Shiro和springmvc,在网上找了很多例子,感觉都有一点复杂。所以就自己写了一个最简单整合项目,记录在这里以备后面查看。 这个例子包含如下三个部分: 1.简单的页面 ...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作