权限校验的控制---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实现权限认证
在这个场景下,“基于acess_token和refresh_token实现token续签”是一个关键的过程,它涉及到用户登录、权限管理以及令牌的有效性维护。下面将详细阐述这个主题。 首先,我们需要理解`access_token`和`refresh_...
本知识点将介绍如何在Spring Boot与Vue前后端分离架构中集成WebSocket,并实现带有身份认证的消息推送功能。这是实现即时通讯、实时数据更新等应用场景的常用技术方案。 ### 1. WebSocket简介 WebSocket是一种在...
APP使用token和refreshToken实现接口身份认证,保持登录状态
Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档.rar Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档.rar Java开发案例-springboot-34-整合Sa-Token实现权限认证-源代码+文档....
标题中的“onenet平台Token计算工具”指的是一个用于与中移物联网OneNet平台交互的工具,该工具的主要功能是生成和管理Token。OneNet是中国移动旗下提供物联网服务的一个云平台,它提供了数据存储、处理、分析以及...
node-jsonwebtoken, node.js http的JsonWebToken实现 jsonwebtoken 的一个实现。这是针对 draft-ietf-oauth-json-web-token-08 开发的。 它利用了节点 jws 。安装$ npm install jsonwebtoken迁移
标题中的“OneNet一键token工具”指的是中国移动物联网平台OneNet提供的一种便捷获取API访问权限的工具。在物联网(IoT)开发中,API token是安全访问服务的关键元素,它允许设备或应用程序通过验证来调用OneNet平台的...
Spring Cloud Feign统一设置验证token实现方法解析 Spring Cloud Feign是一个基于Netflix的Feign组件,提供了一个简洁的方式来构建RESTful风格的微服务接口。Feign组件提供了一个统一的接口调用方式,使得微服务...
【OneNet MQTT Token计算工具详解】 OneNet MQTT Token计算工具是一款专为物联网(IoT)开发者设计的应用,用于生成在使用OneNet MQTT协议时所需的Token。OneNet是中国移动物联网开放平台提供的一种通信协议,它基于...
OneNET-token计算工具 用于生成连接OneNET平台时的token值。便于大家下载使用
在物联网(IoT)领域,安全性和数据保护是至关重要的因素。OneNET平台作为一个领先的物联网云服务...在实际应用中,开发者应根据具体需求和安全策略,合理设置token的有效期、更新策略等,以实现最佳的物联网安全实践。
内容概要: 1、首次登录的时候会获取到两个token(AccessToken,...阅读建议:此资源以简单的demo演示了RefreshToken使用的全过程,介绍了基本的思路,所以在学习的过程要结合这些内容一起来实践,并调试对应的代码。
基于 express 封装的用户鉴权功能,基本原理: 1、用 jsonwebtoken 生成 token 2、用 express-jwt 验证 token 是否过期或失效 3、用 jsonwebtoken 解析出 token 中的用户信息,比如用户 id
文章链接中的"Token生成规则以及工具"可能涉及如何使用特定编程语言(如Java或Python)实现Token的生成和验证,以及如何配置和使用相关的库或框架。例如,对于JWT,可能使用了如`jjwt`(Java JWT)这样的库来创建和...
**正文** 在IT行业中,尤其是Web开发领域,安全性和用户认证是至关重要的议题。本教程将探讨一个基于JFinal框架的token...在实际项目中,还可以考虑结合JWT(JSON Web Token)等现代认证方案,以进一步增强安全性。
在SuperMap iClient for JavaScript中,安全认证是访问...了解以上知识点后,你就可以在SuperMap iClient for JavaScript中有效地实现基于Token的安全认证,确保你的Web应用程序能够安全地访问SuperMap iServer服务。
在IT行业中,Token认证签名加密是一种常见的安全机制,主要用于确保数据传输的安全性和验证请求的合法性。这个主题涉及了几个核心概念,包括Token、加密和签名,这些都是构建安全网络服务的关键要素。 1. **Token**...
在智能家居领域,米家...了解这些知识点后,用户可以更有效地利用米家设备 token 工具,实现对智能家居设备的个性化控制和自动化管理。同时,这也为开发者提供了一个便捷的入口,能够探索更多基于米家平台的创新应用。
最近在搞springboot的模块化开发,集成了shiro+jwt实现restful接口的token认证。 需新增测试表: CREATE TABLE `t_user` ( `user_id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT, `user_name` varchar(32...