基于springcloud接口鉴权

本文详细介绍了基于SpringCloud的接口鉴权流程,包括调用方如何获取token,服务端如何验证token并进行鉴权。流程涉及Redis存储、代码中配置的code和secret、HTTP请求的数据统一处理、Feign调用的鉴权服务等。鉴权过程中,通过SHA1和SHA256加密确保安全性,同时利用Redis存储和管理token的有效性和权限信息。
摘要由CSDN通过智能技术生成

梳理一下流程
1.调用方需要获取到token(由code和secret和随机数加密生成)
2.调用接口前先通过服务端的要求传入相应的数据生成token,调用接口时把token传入
3.由服务端接收到token进行验证
4.验证成功后对url进行鉴权

接口信息以及权限信息回放在数据库中(mysql以及redis)

资源信息表
接口信息表
调用方身份表;java后端、app端、H5…要进行区分
调用方身份表
中间表;每种身份所对应的资源
中间表

HTTP请求返回的数据统一放入ResponseModel类中.省略了get set方法

public class ResponseModel<T> {
   

    /**
     * 通配符
     **/
    private static final String WILDCARD_ALL = "*";
    /**
     * 响应状态码
     **/
    private volatile String code = HttpCode.BAD_REQUEST.getCode();
    /**
     * 响应状态码对应的提示信息
     **/
    private volatile String message = HttpCode.BAD_REQUEST.getMessage();
    /**
     * 响应内容
     **/
    private volatile T content = null;

    public ResponseModel() {
   
    }
 }

把code和secret放入配置文件中;要与数据库中的一致

	@Value("${microservices.code}")
    private String microservicesCode;
    @Value("${microservices.secret}")
    private String microservicesSecret;

在调用接口、执行http请求之前先获取token,把code和secret传入
这边先不管接口的鉴权流程,先看token的获取流程然后再说鉴权流程

 /**
     *  http请求公共方法
     * @param url
     * @param params
     * @param method get and post
     * @return
     */
    protected ResponseModel HttpCommon(String url ,Map params,String method){
   
        ResponseModel  responseModel=null;
        //获取token
        String uToken = partnerService.getToken(microservicesCode, microservicesSecret);
        //调用微服务接口传入token进行鉴权并返回结果;params为查询条件map
        if("post".equalsIgnoreCase(method)){
   
              responseModel = PartnerUtils.doPostToXianXiu(url, uToken, params);
        }else if("get".equalsIgnoreCase(method)){
   
              responseModel = PartnerUtils.doGetToXianXiu(url, uToken, params);
        }
        return responseModel;
    }

在生成token之前会先去redis查询一遍,如果有就直接返回token,key的值可以自己去定义
(调用端和服务端操作的redis不是同一个库,这里我操作的是第一个库,服务端操作的是第三个库)
如果redis没有走生成token的流程,先生成一个随机字符串nonceStr,然后把nonceStr以及传进来的code以及secret参数进行SHA1加密得到一个签名uSign
调用getAccessToken方法进行token生成以及校验token

@Service("partnerServiceImpl")
public class PartnerServiceImpl implements PartnerService {
   

    @Resource
    private RedisService redisService;
	
	@Override
	public String getToken(String code, String secretKey) {
   
		
		if(StringUtils.isEmpty(code) || StringUtils.isEmpty(secretKey)) {
   
			
			return null;
		}
		
		String sessionKey = code+"-TOKEN";
		
		String uToken = redisService.get(sessionKey);
		
		if(StringUtils.isEmpty(uToken)) {
   
			
			try {
   
				
				String nonceStr=UUID.randomUUID().toString();
				//进行SHA1加密
				String uSign = SecuritySHA1Utils.shaEncode(code+nonceStr+secretKey);
				ResponseModel responseModel = PartnerUtils.getAccessToken(code, uSign, nonceStr);
				
				if(responseModel==null || StringUtils.isEmpty(String.valueOf(responseModel.getContent()))) {
   
					
					log.info("新平台鉴权失败==================");
					log.info("sign:"+uSign);
					log.info("rand:"+nonceStr);
					
					return null;
					
				}else {
   
								
								
					uToken = (String)responseModel.getContent();
					
					log.info("新平台鉴权成功==================");
					log.info("utoken:"+uToken);
								
					redisService.set(sessionKey, uToken, 900);

					return uToken;
				}
				
			} catch (Exception e) {
   
				
				e.printStackTrace();
				return null;
			}
			
		}else {
   
			
			return uToken;
		}
	}
	
	
}
	//zuul网关的端口
	public static String HOST = "http://localhost:8110";
	//生成token的接口
	public static final String TOKEN_PATH = "/partner/auth/safty/get-partner-token";

	public static ResponseModel getAccessToken(String code, String signature, String nonceStr) {
   
		
		String backData = "";
		
		String param="code="+code+"&signature="+signature+"&nonceStr="+nonceStr+"";
		
		try {
   
			backData = HttpUtils.sendGet(HOST+TOKEN_PATH, param);
		}catch (Exception e) {
   
			e.printStackTrace();
		}
		log.info("============》获取accessToken"+JSON.toJSONString(backData));
		// String accessToken = (String)
		// JSONObject.fromObject(backData).get("access_token");
		ResponseModel responseModel = JSON.parseObject(backData, new TypeReference<ResponseModel>() {
   });
		return responseModel;
	}

网关配置

一般会把所有的请求前缀进行配置;如果出现非法请求则会被拒;强烈要求接口以前缀进行分组这样比较直观
请求合法会执行doAccess方法,把RequestContext对象,prefix请求前缀,url传入。进行鉴权

@SuppressWarnings("serial")
    private static final Set<String> URL_PREFIX = new HashSet<String>() {
   {
   
        add("auth");
        add("demo");
        add("user");
        add("job");
        add("partner");
        add("activity");
        add("payment");
        add("product");
        add("hatch");
    }};
    
    @Override
    public Object run() {
   
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值