`
y806839048
  • 浏览: 1126462 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

JsonWebToken工具结合切面token实现认证

阅读更多

 

 

权限校验的控制---1,直接用权限框架

                 2,用路径特征---不同的controller用不同的路径前缀---可根据这种特征用不同的权限认证

 

 

用JsonWebToken工具hash需要的字段之后生成一段字符串,之后这段字符串可以反向获取之前的明文----这个可以作为token--可以翻译出信息的token

 

用一个切面结合token实现认证:----尤其外部分享链接可以采用这种方式

 

1,认证

2,验证是否有效

 

有效期:每次请求之后无论成功失败都刷新,每次刷新都是重新生成claim除了用户名,密码,还是有事件戳,所以每次生成的不一样

 

 

   if (!tokenUtils.validateToken(token, user)) {

            log.info("{} : token validation fails", request.getServletPath());

            response.setStatus(HttpCodeEnum.FORBIDDEN.getCode());

            response.getWriter().print("Invalid token ");

            return false;

        }

 

/**

     * 根据 用户名、密码 验证 token

     *

     * @param token

     * @param username

     * @param password

     * @return

     */

    public Boolean validateToken(String token, String username, String password) {

        String tokenUsername = getUsername(token);

        String tokenPassword = getPassword(token);

        return (username.equals(tokenUsername) && password.equals(tokenPassword) && !(isExpired(token)));

    }

 

 

 

认证:

 @Override

    public User shareLogin(String token, UserLogin userLogin) throws NotFoundException, ServerException, UnAuthorizedExecption {

        //AES解密

        String decrypt = AESUtils.decrypt(token, null);

        //获取分享信息

        String tokenUserName = tokenUtils.getUsername(decrypt);

        String tokenPassword = tokenUtils.getPassword(decrypt);

 

        String[] tokenInfos = tokenUserName.split(Constants.SPLIT_CHAR_STRING);

        String[] tokenCrypts = tokenPassword.split(Constants.SPLIT_CHAR_STRING);

 

        if (tokenInfos.length < 2) {

            throw new ServerException("Invalid share token");

        }

 

        User loginUser = userMapper.selectByUsername(userLogin.getUsername());

        if (null == loginUser) {

            throw new NotFoundException("user is not found");

        }

 

        //校验密码

        if (!BCrypt.checkpw(userLogin.getPassword(), loginUser.getPassword())) {

            throw new ServerException("password is wrong");

        }

 

        Long shareUserId = Long.parseLong(tokenInfos[1]);

        if (shareUserId.longValue() < 1L) {

            throw new ServerException("Invalid share token");

        }

 

        User shareUser = userMapper.getById(shareUserId);

        if (null == shareUser) {

            throw new ServerException("Invalid share token");

        }

 

        if (tokenInfos.length == 3) {

            if (tokenCrypts.length < 2) {

                throw new ServerException("Invalid share token");

            }

            try {

                String sharedUserName = tokenInfos[2];

                Long sharedUserId = Long.parseLong(tokenCrypts[1]);

                if (!(loginUser.getUsername().equals(sharedUserName) && loginUser.getId().equals(sharedUserId)) && !loginUser.getId().equals(shareUserId)) {

                    throw new ForbiddenExecption("The resource requires authentication, which was not supplied with the request");

                }

            } catch (NumberFormatException e) {

                throw new ForbiddenExecption("The resource requires authentication, which was not supplied with the request");

            }

        }

 

        //是否激活

        if (!loginUser.getActive()) {

            throw new ServerException("this user is not active");

        }

 

        return loginUser;

    }

 

 

验证是否失效:

 

/**

     * 修改dashboard下的widget关联信息

     *

     * @param bindingResult

     * @param user

     * @param request

     * @return

     */

    @ApiOperation(value = "update dashboard widget relation")

    @PutMapping(value = "/{portalId}/dashboards/widgets", consumes = MediaType.APPLICATION_JSON_VALUE)

    public ResponseEntity updateMemDashboardWidget(@PathVariable("portalId") Long portalId,

                                                   @Valid @RequestBody MemDashboardWidgetDto[] memDashboardWidgets,

                                                   @ApiIgnore BindingResult bindingResult,

                                                   @ApiIgnore @CurrentUser User user,

                                                   HttpServletRequest request) {

        if (bindingResult.hasErrors()) {

            ResultMap resultMap = new ResultMap(tokenUtils).failAndRefreshToken(request).message(bindingResult.getFieldErrors().get(0).getDefaultMessage());

            return ResponseEntity.status(resultMap.getCode()).body(resultMap);

        }

 

        for (MemDashboardWidget memDashboardWidget : memDashboardWidgets) {

            if (invalidId(memDashboardWidget.getId())) {

                ResultMap resultMap = new ResultMap(tokenUtils).failAndRefreshToken(request).message("Invalid id");

                return ResponseEntity.status(resultMap.getCode()).body(resultMap);

            }

 

            if (invalidId(memDashboardWidget.getDashboardId())) {

                ResultMap resultMap = new ResultMap(tokenUtils).failAndRefreshToken(request).message("Invalid dashboard id");

                return ResponseEntity.status(resultMap.getCode()).body(resultMap);

            }

 

            if (invalidId(memDashboardWidget.getWidgetId())) {

                ResultMap resultMap = new ResultMap(tokenUtils).failAndRefreshToken(request).message("Invalid widget id");

                return ResponseEntity.status(resultMap.getCode()).body(resultMap);

            }

 

            if (memDashboardWidget.getPolling() && memDashboardWidget.getFrequency() < 1) {

                ResultMap resultMap = new ResultMap(tokenUtils).failAndRefreshToken(request).message("Invalid frequency");

                return ResponseEntity.status(resultMap.getCode()).body(resultMap);

            }

        }

 

        dashboardService.updateMemDashboardWidgets(portalId, user, memDashboardWidgets);

        return ResponseEntity.ok(new ResultMap(tokenUtils).successAndRefreshToken(request));

    }

 

 

 

 

 

生成token的时候如果需要使用过期时间,刷新也就是重新设置过期时间然后重新生成

可以不用过期时间,生成永久的token 

 

一般用于生成token的明文的对象是map类型

 

 /**

     * 根据 TokenDetail 实体生成Token

     *

     * @param tokenDetail

     * @return

     */

    public String generateToken(TokenDetail tokenDetail) {

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

        claims.put(Consts.TOKEN_USER_NAME, StringUtils.isEmpty(tokenDetail.getUsername()) ? EMPTY : tokenDetail.getUsername());

        claims.put(Consts.TOKEN_USER_PASSWORD, StringUtils.isEmpty(tokenDetail.getPassword()) ? EMPTY : tokenDetail.getPassword());

        claims.put(Consts.TOKEN_CREATE_TIME, System.currentTimeMillis());

        return generate(claims);

    }

 

 

 /**

     * 根据 clams生成token

     *

     * @param claims

     * @return

     */

    private String generate(Map<String, Object> claims) {

        Long expiration = Long.parseLong(claims.get(Consts.TOKEN_CREATE_TIME) + EMPTY) + TIMEOUT;

        try {

            return Jwts.builder()

                    .setClaims(claims)

                    .setSubject(claims.get(Consts.TOKEN_USER_NAME).toString())

                    .setExpiration(new Date(expiration))

                    .signWith(null != SignatureAlgorithm.valueOf(ALGORITHM) ?

                            SignatureAlgorithm.valueOf(ALGORITHM) :

                            SignatureAlgorithm.HS512, SECRET.getBytes("UTF-8"))

                    .compact();

        } catch (UnsupportedEncodingException ex) {

            log.warn(ex.getMessage());

            return Jwts.builder()

                    .setClaims(claims)

                    .setSubject(claims.get(Consts.TOKEN_USER_NAME).toString())

                    .setExpiration(new Date(expiration))

                    .signWith(null != SignatureAlgorithm.valueOf(ALGORITHM) ?

                            SignatureAlgorithm.valueOf(ALGORITHM) :

                            SignatureAlgorithm.HS512, SECRET)

                    .compact();

        }

    }

 

 

 

 

解析token,生成claims对象,后续用这个对象获取相应的属性(明文)

 

 

/**

     * 获取token claims

     *

     * @param token

     * @return

     */

    private Claims getClaims(String token) {

        Claims claims;

        try {

            claims = Jwts.parser()

                    .setSigningKey(SECRET.getBytes("UTF-8"))

                    .parseClaimsJws(token.startsWith(Consts.TOKEN_PREFIX) ?

                            token.substring(token.indexOf(Consts.TOKEN_PREFIX) + Consts.TOKEN_PREFIX.length()).trim() :

                            token.trim())

                    .getBody();

        } catch (Exception e) {

            log.warn(e.getMessage());

            claims = Jwts.parser()

                    .setSigningKey(SECRET)

                    .parseClaimsJws(token.startsWith(Consts.TOKEN_PREFIX) ?

                            token.substring(token.indexOf(Consts.TOKEN_PREFIX) + Consts.TOKEN_PREFIX.length()).trim() :

                            token.trim())

                    .getBody();

        }

        return claims;

    }

 

 

 

 

 /**

     * 解析 token 用户名

     *

     * @param token

     * @return

     */

    public String getUsername(String token) {

        String username;

        try {

            final Claims claims = getClaims(token);

            username = claims.get(Consts.TOKEN_USER_NAME).toString();

        } catch (Exception e) {

            username = null;

        }

        return username;

    }

 

 

 

 

 

分享到:
评论

相关推荐

    SpringBoot(51) 整合Sa-Token实现权限认证

    SpringBoot(51) 整合Sa-Token实现权限认证

    基于acess_token和refresh_token实现token续签

    在这个场景下,“基于acess_token和refresh_token实现token续签”是一个关键的过程,它涉及到用户登录、权限管理以及令牌的有效性维护。下面将详细阐述这个主题。 首先,我们需要理解`access_token`和`refresh_...

    spring boot+vue+websocket带token身份认证推送消息实现

    本知识点将介绍如何在Spring Boot与Vue前后端分离架构中集成WebSocket,并实现带有身份认证的消息推送功能。这是实现即时通讯、实时数据更新等应用场景的常用技术方案。 ### 1. WebSocket简介 WebSocket是一种在...

    APP使用token和refreshToken实现接口身份认证,保持登录状态.vsdx

    APP使用token和refreshToken实现接口身份认证,保持登录状态

    Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档.rar

    Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档.rar Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档.rar Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档....

    onenet平台Token计算工具

    标题中的“onenet平台Token计算工具”指的是一个用于与中移物联网OneNet平台交互的工具,该工具的主要功能是生成和管理Token。OneNet是中国移动旗下提供物联网服务的一个云平台,它提供了数据存储、处理、分析以及...

    node-jsonwebtoken, node.js http的JsonWebToken实现.zip

    node-jsonwebtoken, node.js http的JsonWebToken实现 jsonwebtoken 的一个实现。这是针对 draft-ietf-oauth-json-web-token-08 开发的。 它利用了节点 jws 。安装$ npm install jsonwebtoken迁移

    OneNet一键token工具

    标题中的“OneNet一键token工具”指的是中国移动物联网平台OneNet提供的一种便捷获取API访问权限的工具。在物联网(IoT)开发中,API token是安全访问服务的关键元素,它允许设备或应用程序通过验证来调用OneNet平台的...

    Spring Cloud Feign统一设置验证token实现方法解析

    Spring Cloud Feign统一设置验证token实现方法解析 Spring Cloud Feign是一个基于Netflix的Feign组件,提供了一个简洁的方式来构建RESTful风格的微服务接口。Feign组件提供了一个统一的接口调用方式,使得微服务...

    onenet MQTT Token计算工具

    【OneNet MQTT Token计算工具详解】 OneNet MQTT Token计算工具是一款专为物联网(IoT)开发者设计的应用,用于生成在使用OneNet MQTT协议时所需的Token。OneNet是中国移动物联网开放平台提供的一种通信协议,它基于...

    OneNET-token计算工具

    OneNET-token计算工具 用于生成连接OneNET平台时的token值。便于大家下载使用

    OneNET平台鉴权token计算工具_物联网_鉴权

    在物联网(IoT)领域,安全性和数据保护是至关重要的因素。OneNET平台作为一个领先的物联网云服务...在实际应用中,开发者应根据具体需求和安全策略,合理设置token的有效期、更新策略等,以实现最佳的物联网安全实践。

    vue中前端利用refreshToken结合axios拦截器实现token的无感刷新

    内容概要: 1、首次登录的时候会获取到两个token(AccessToken,...阅读建议:此资源以简单的demo演示了RefreshToken使用的全过程,介绍了基本的思路,所以在学习的过程要结合这些内容一起来实践,并调试对应的代码。

    node.js之express的token验证

    基于 express 封装的用户鉴权功能,基本原理: 1、用 jsonwebtoken 生成 token 2、用 express-jwt 验证 token 是否过期或失效 3、用 jsonwebtoken 解析出 token 中的用户信息,比如用户 id

    Token生成规则以及工具相关代码

    文章链接中的"Token生成规则以及工具"可能涉及如何使用特定编程语言(如Java或Python)实现Token的生成和验证,以及如何配置和使用相关的库或框架。例如,对于JWT,可能使用了如`jjwt`(Java JWT)这样的库来创建和...

    JFinal+token基础demo

    **正文** 在IT行业中,尤其是Web开发领域,安全性和用户认证是至关重要的议题。本教程将探讨一个基于JFinal框架的token...在实际项目中,还可以考虑结合JWT(JSON Web Token)等现代认证方案,以进一步增强安全性。

    SuperMap iclient for javascript使用token安全认证

    在SuperMap iClient for JavaScript中,安全认证是访问...了解以上知识点后,你就可以在SuperMap iClient for JavaScript中有效地实现基于Token的安全认证,确保你的Web应用程序能够安全地访问SuperMap iServer服务。

    Token认证签名加密

    在IT行业中,Token认证签名加密是一种常见的安全机制,主要用于确保数据传输的安全性和验证请求的合法性。这个主题涉及了几个核心概念,包括Token、加密和签名,这些都是构建安全网络服务的关键要素。 1. **Token**...

    获取米家设备 token 工具

    在智能家居领域,米家...了解这些知识点后,用户可以更有效地利用米家设备 token 工具,实现对智能家居设备的个性化控制和自动化管理。同时,这也为开发者提供了一个便捷的入口,能够探索更多基于米家平台的创新应用。

    springboot的模块化开发,集成shiro+jwt实现restful接口的token认证

    最近在搞springboot的模块化开发,集成了shiro+jwt实现restful接口的token认证。 需新增测试表: CREATE TABLE `t_user` ( `user_id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT, `user_name` varchar(32...

Global site tag (gtag.js) - Google Analytics