Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error code 14 on 401 unauthorized #569

Closed
dasois opened this issue May 27, 2019 · 4 comments
Closed

Error code 14 on 401 unauthorized #569

dasois opened this issue May 27, 2019 · 4 comments

Comments

@dasois
Copy link

dasois commented May 27, 2019

The grpc-web client transforms a 401 into status code 14 .

The definition suggests, that it should be error code 16 in this case.

I have the requirement to handle 401 errors differently than if the backend would be unavailable per se.

@stanley-cheung
Copy link
Collaborator

Sorry for the late reply. But where did you see that 401 got turned into code 14?

Here: https://github.com/grpc/grpc-web/blob/master/javascript/net/grpc/web/statuscode.js#L156 we mapped 401 to 16.

@harmangakhal
Copy link
Contributor

harmangakhal commented Aug 16, 2019

I have a similar problem; I've set up a web application using
grpc-web/envoy and have an external authorization
HTTP filter than performs JWT authentication of the client requests before allowing them through to the grpc server. When it returns,
a 401 response on JWT authentication failure, I think the response is not propagated because https://github.com/grpc/grpc-web/blob/master/javascript/net/grpc/web/grpcwebclientreadablestream.js#L198-L207 does not handle http_error.
It just default's to UNAVAILABLE so I get a
Object { code: 14, message: "Http response at 400 or 500 level" } response but
the HTTP POST response status code header returns a 401.
Seems like it's getting caught in,

if (self.onErrorCallback_) {
self.onErrorCallback_({
code: grpcStatusCode,
message: ErrorCode.getDebugMessage(lastErrorCode)
});
}
return;

because the error message comes from,
https://github.com/google/closure-library/blob/4f1e354899494227cdf6ddeac9fa1f5b931b39fb/closure/goog/net/errorcode.js#L115-L116.

@stanley-cheung Is this intended behavior? Must my authentication server be a grpc server?

@asv
Copy link
Contributor

asv commented Aug 19, 2019

Have a similar problem as @haberman. @stanley-cheung could you help us? This is a serious production blocker for my team :(

@asv
Copy link
Contributor

asv commented Aug 19, 2019

@haberman I found a fast & dirty workaround.
From my ext_authz handler:

func (s *server) Check(ctx context.Context, req *envoyauthz.CheckRequest) (*envoyauthz.CheckResponse, error) {
	headers := req.GetAttributes().GetRequest().GetHttp().GetHeaders()
	sessionCookie, err := parseCookie(headers["cookie"], sessionCookieName)
	if err != nil {
		return responseDenied("can't parse session cookie")
	}
    //... further it doesn’t matter
}

func responseDenied(reason string) (*envoyauthz.CheckResponse, error) {
	return &envoyauthz.CheckResponse{
		Status: &rpc.Status{
			Code:    int32(rpc.UNAUTHENTICATED),
			Message: "Denied: " + reason,
		},
                // Workaround for issue https://github.com/grpc/grpc-web/issues/569
		HttpResponse: &envoyauthz.CheckResponse_DeniedResponse{
			DeniedResponse: &envoyauthz.DeniedHttpResponse{
				Status: &envoytype.HttpStatus{
					Code: envoytype.StatusCode_OK,
				},
				Headers: []*envoycore.HeaderValueOption{
					{
						Append: &types.BoolValue{
							Value: false,
						},
						Header: &envoycore.HeaderValue{
							Key:   "grpc-status",
							Value: strconv.Itoa(int(codes.Unauthenticated)),
						},
					},
					{
						Append: &types.BoolValue{
							Value: false,
						},
						Header: &envoycore.HeaderValue{
							Key:   "grpc-message",
							Value: reason,
						},
					},
				},
			},
		},
	}, nil
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants