grpc之java使用拦截器实现权限验证
  Adknp2DJyaqB 2023年11月13日 25 0

grpc之java使用拦截器实现权限验证

在前面java实现的简单调用基础上增加拦截器实现请求权限验证。

  1. 新建intercept目录新增服务段和客户端拦截器

ServerIntercept.java

package com.wms.inercept;

import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;

public class ServerIntercept implements ServerInterceptor {
    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
        System.out.println("每次请求都要经过我");
        Metadata.Key<String> accessToken  =
                Metadata.Key.of("accessToken", Metadata.ASCII_STRING_MARSHALLER);
        System.out.println(metadata.get(accessToken));
        return serverCallHandler.startCall(serverCall, metadata);
    }
}

ClientIntercept.java

package com.wms.inercept;

import io.grpc.*;

public class ClientIntercept implements ClientInterceptor {
    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
                                                               CallOptions callOptions, Channel next) {
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {

            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                /* put custom header */
                Metadata.Key<String> accessToken  =
                        Metadata.Key.of("accessToken", Metadata.ASCII_STRING_MARSHALLER);
                headers.put(accessToken, "customRequestValue");
                super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    @Override
                    public void onHeaders(Metadata headers) {
                        /**
                         * if you don't need receive header from server,
                         * you can use {@link io.grpc.stub.MetadataUtils#attachHeaders}
                         * directly to send header
                         */
                        System.out.println("header received from server:" + headers);
                        super.onHeaders(headers);
                    }
                }, headers);
            }
        };
    }
}

image 然后启动服务端和客户端,输出如图 image image 2. pom文件中新增2各依赖

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.16.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.40</version>
        </dependency>

一个是解密解密库,一个是处理json. 3. 新建User和token验证返回类 image User.java

package com.wms.model;

public class User {
    private String userName;
    private String passWord;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
}

TokenResponse.java

package com.wms.model;

public class TokenResponse {
    private boolean success;
    private String message;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

  1. 在拦截器目录添加token检查方法
package com.wms.inercept;

import com.alibaba.fastjson2.JSON;
import com.wms.model.Carrier;
import com.wms.model.TokenResponse;
import com.wms.model.User;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

import java.util.Arrays;

public class Token {
    public TokenResponse check(String accessToken){
//        String token = Hex.encodeHexString(Base64.encodeBase64String("{\"userName\":\"wms\",\"passWord\":\"123456\"}".getBytes()).getBytes());
        TokenResponse tokenResponse = new TokenResponse();
        if(accessToken.isEmpty()){
            tokenResponse.setSuccess(false);
            tokenResponse.setMessage("请添加授权token");
            return tokenResponse;
        }
        String jsonStr = "";
        User user = new User();
        try {
            jsonStr = new String(Base64.decodeBase64(Hex.decodeHex(accessToken)));
            user = JSON.parseObject(jsonStr, User.class);
        } catch (Exception e) {
            tokenResponse.setSuccess(false);
            tokenResponse.setMessage(e.getMessage());
            return tokenResponse;
        }

        if(user.getUserName().equals("wms") && user.getPassWord().equals("123456")){
            tokenResponse.setSuccess(true);
            tokenResponse.setMessage("验证通过");
        }
        return tokenResponse;
    }
}

  1. 客户端和服务端拦截器修改如下 ClientIntercept.java 请求前添加token
headers.put(accessToken, "65794a3163325679546d46745a534936496e647463794973496e426863334e5862334a6b496a6f694d54497a4e445532496e303d");

ServerIntercept.java 接收验证token

Token token = new Token();
        TokenResponse b = token.check(metadata.get(accessToken));
        if(!b.isSuccess()){
            serverCall.close(Status.UNAUTHENTICATED,metadata);
        }
  1. 返回结果 image image
  2. 用php请求,和前面请求golang一样,只是地址换一下
$clientJava = new Carrier\CarrierClient('192.168.2.127:50052', [
    'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
$carrierRequest = new Carrier\CarrierRequest();
$carrierRequest->setName("e邮宝");
$meaData = array(
    'accessToken' => array("65794a3163325679546d46745a534936496e647463794973496e426863334e5862334a6b496a6f694d54497a4e445532496e303d")
);
list($replyj, $statusj) = $clientJava->GetCarrier($carrierRequest,$meaData)->wait();
if($statusj->code === 0){
    print_r($replyj->getName());
    print_r($replyj->getId());
    print_r($statusj->code);
    print_r(json_encode($replyj));
    print_r(json_encode($statusj));
}else{
    print_r($statusj->code);
    print_r($statusj->details);
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  3I1N9ysrcSyk   2023年12月08日   26   0   0 javahapi数据交换
  DF5J4hb0hcmT   2023年12月07日   48   0   0 javaArthas
Adknp2DJyaqB