`
y806839048
  • 浏览: 1092753 次
  • 性别: 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;

    }

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics