• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

基于注解实现登录票信息解析及验证


Recommended Posts

1、定义方法注解,标识该方法需要解析票信息

导入Java。郎。注释。记录在案;

导入Java。郎。注释。元素类型;

导入Java。郎。注释。继承的;

导入Java。郎。注释。保留;

导入Java。郎。注释。保留政策;

导入Java。郎。注释。目标;

/**

* @ClassName: Auth

* @描述:是否验证票

* @author: Ccl

* @date: 2022年四月29日上午11:51:54

* @Copyright:

*/

@Target({ElementType .方法})

@保留(保留政策.运行时间)

@已记录

@继承

public @interface Auth {

布尔isCheck()默认值为真实的

}

2、定义切面实现

导入Java。util。并发。时间单位;

导入org。阿帕奇。公地。郎3。字符串实用程序;

导入org。AspectJ。郎。proceedingjoinpoint

导入org。AspectJ。郎。注释。周围;

导入org。AspectJ。郎。注释。方面;

导入org。AspectJ。郎。注释。切入点;

导入org。spring框架。豆子。工厂。注释。自动连线;

导入org。spring框架。核心。注释。订单;

导入org。spring框架。刻板印象。组件;

导入com。覆铜板。秩序。API。用户。实体。用户实体;

导入com。覆铜板。秩序。API。用户。服务。用户服务;

导入com。覆铜板。秩序。auth。scuserticket

导入com。覆铜板。秩序。糖膏剂例外。authfailexception

导入com。覆铜板。秩序。糖膏剂例外。operationdeniedexception

导入com。覆铜板。秩序。雷迪斯。伊努斯。rediskey枚举;

导入com。覆铜板。秩序。雷迪斯。服务。用户。userediservice

导入com。覆铜板。秩序。util。authtokenutils

/**

* @ClassName:验证方面

* @描述:如果票解析错误将不能进入,返回重新登录代码,注意,方法的第一个参数必须为ScuserTicket,需要将解析出来的票赋值该参数

* @author: Ccl

* @date: 2022年5月一日下午3:07:52

* @Copyright:

*/

@Aspect

@订单(值=2)

@组件

公共类AuthAspect {

@自动连线

公共用户服务用户服务;

@自动连线

public userrediservice userrediservice;

//切入点

@ Pointcut(value=' @ annotation(com。覆铜板。秩序。AOP。auth。auth)')

私有空的切入点(){

}

@ Around(value=' pointcut()@ annotation(auth)')

公共对象around(ProceedingJoinPoint连接点,Auth auth){

object[]args=连接点。get args();//获取目标对象方法参数

布尔值is _ auth=auth。是check();//是否校验参数

if(is_auth) {

string jws=authtokenutils。get _ auth _ token()。//从请求中获取票

if (StringUtils.isNotBlank(jws)) { //解析ticket获取用户id String userId = AuthTokenUtils.get_decode_auth_id(jws); //判断ticket缓存是否已经失效 if(!userRedisService.has(jws)) { throw new AuthFailException("登录信息失效,请重新登录!"); } UserEntity user = userRedisService.get_entity(jws);//从缓存中获取 if(user == null) { user = userService.getById(userId);//用户信息 userRedisService.set(jws, user, RedisKeyEnum.TICKET.getExpire(),TimeUnit.SECONDS);//加入到缓存 } if(user == null){ throw new OperationDeniedException("ticket信息错误!"); } ScuserTicket scuserTicket = ScuserTicket.builder().id(userId).companyId(user.getCompanyId()).user(user).build(); if(args.length > 0) { args[0] = new ScuserTicket(); args[0] = scuserTicket; } }else { throw new AuthFailException("ticket格式错误!"); } } try { return joinPoint.proceed(args); } catch (Throwable e) { //自定义异常按照正常格式返回 throw new OperationDeniedException(e.getMessage()); } } }

3、登录接口,成功后返回ticket信息及将ticket信息放入缓存

@Override
    public Map<String, Object> login_in(UserEntityDTO param) {
        // TODO Auto-generated method stub
        if(StringUtils.isBlank(param.getUserName())) {
            throw new OperationDeniedException("用户名不能为空!");
        }else if(StringUtils.isBlank(param.getUserPassword())) {
            throw new OperationDeniedException("登录密码不能为空!");
        }
        LambdaQueryWrapper<UserEntity> lambdaQueryWrapper = new LambdaQueryWrapper<UserEntity>();
        lambdaQueryWrapper.eq(UserEntity::getUserName, param.getUserName());
        UserEntity userEntity = this.getOne(lambdaQueryWrapper);
        if(userEntity == null) {
            throw new OperationDeniedException("该用户未注册,请先注册!");
        }else {
            String oriPassword = MD5Util.MD5Encode(MD5Util.MD5Encode(param.getUserPassword()));//2次md5加密
            if(!oriPassword.equals(userEntity.getUserPassword())) {//校验密码
                throw new OperationDeniedException("登录密码错误!");
            }
        }
        //生成授权ticket
        String ticket = AuthTokenUtils.generateTicket(userEntity.getId());
        //设置ticket时效
        userRedisService.set(ticket,userEntity,RedisKeyEnum.TICKET.getExpire(),TimeUnit.SECONDS);
        //返回登录信息
        Map<String,Object> retMap = new HashMap<>();
        retMap.put("ticket", ticket);
        retMap.put("userName", userEntity.getUserName());
        return retMap;
    }

4、AuthTokenUtils方法

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
public class AuthTokenUtils {
    
    private static final String SECRET_KEY = "123455667"; // 严禁修改此变量值
    
    /**
     * @Title: generateTicket   
     * @Description: 生成ticket
     * @param: @param id
     * @param: @return      
     * @return: String      
     * @throws
     */
    public static String generateTicket(String id) {
        Map<String, Object> claims = new HashMap<>();
        String compactJws = Jwts.builder().setSubject(String.valueOf(id)).setId(UUID.randomUUID().toString().replaceAll("-", ""))
                .setIssuedAt(new Date()).addClaims(claims).signWith(SignatureAlgorithm.HS256, SECRET_KEY.getBytes(StandardCharsets.UTF_8)).compact();
        return compactJws;
    }
    
    /**
     * @Title: get_auth_token   
     * @Description: 获取ticket信息
     * @param: @return      
     * @return: String      
     * @throws
     */
    public static String get_auth_token() {
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        String headerAuthorization = request.getHeader("authorization"); // 获取认证数据
        if (StringUtils.isNotBlank(headerAuthorization) && headerAuthorization.startsWith("Bearer")) {
            return headerAuthorization.substring(7);
        }else {
            return "";
        }
    }
    
    /**
     * @Title: get_decode_auth_id   
     * @Description: 解析ticket信息  
     * @param: @param jws
     * @param: @return      
     * @return: String      
     * @throws
     */
    public static String get_decode_auth_id(String jws) {
        Claims clms = null;
        try {
            clms = Jwts.parser().setSigningKey(SECRET_KEY.getBytes(StandardCharsets.UTF_8)).parseClaimsJws(jws).getBody();
        } catch (SignatureException se) {
            try {
                clms = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(jws).getBody();
            } catch (SignatureException se2) {
                return "";
            }
        }
        return clms.getSubject();
    }
}

5、应用

@RestController
@RequestMapping("order")
@Validated
public class OrderController extends BaseController<OrderEntity,OrderService>{
    @Autowired
    private OrderService orderService;
  /**
     * 列表
     */
    @Auth
    @RequestMapping("/list")
    public ApiResponse list(ScuserTicket ticket,OrderEntityDTO param){
        
        return ApiResponse.buildSuccess(orderService.findList(param));
    }
}

6、效果

xe1qfyi2aor6187.png

 

Link to comment
Share on other sites