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

Add support to modify HTTP status code using identifier in linkerd plugins #1465

Closed
SurajMenon opened this issue Jul 5, 2017 · 5 comments
Closed

Comments

@SurajMenon
Copy link

I am using linkerD to set up an authorization plugin, in Java. Currently I am using an Identifier to intercept the request & check if the user is authorized. (Using : https://github.com/linkerd/linkerd-examples/tree/master/plugins/header-classifier as an example)

If the user is not authorized, the request should not reach the backend service. I am throwing a runtime exception in such cases (do let me know if there is another way for preventing the request to reach the backend). Linkerd sends the response as 502 Bad Gateway. Linkerd should have a mechanism by which I can specify the HTTP status code I want to send back.

I tried using a responseClassifier along with the identifier, but it looks like the responseClassifier does not get invoked when the exception is thrown.

@adleong
Copy link
Member

adleong commented Jul 5, 2017

Hi @SurajMenon. This is a limitation of using the identifier plugin interface for authorization. If you prefer, you can return an UnidentifiedRequest exception which will return a 400 Bad Request. In the long term we'd like to add a new plugin interface specifically for authorization which would allow more control over the error responses: #1466

@esbie
Copy link
Contributor

esbie commented Jul 5, 2017

fwiw, we need something similar to implement istio http redirects as part of the identifier

@SurajMenon
Copy link
Author

@adleong : Thanks for the quick response. One more observation that I had was, the Accept header does not get honoured in both the cases (502 Bad Gateway & 400 Bad Request). I get a plain text response when I am expecting a json response. Let me know if this is not the expected behaviour. If it is, can this be also added as a part of #1466

@adleong
Copy link
Member

adleong commented Jul 6, 2017

That's right, we currently only return plaintext error messages. Adding support for json would be pretty easy, though. Pull requests welcome!

@serhii-samoilenko
Copy link

Maybe will be useful for someone ended up here. You can bypass this limitation by throwing io.buoyant.linkerd.protocol.http.ErrorResponder.HttpResponseException
Scala Example:

import com.twitter.finagle.buoyant.linkerd.Headers
import com.twitter.finagle.http.{Request, Status}
import com.twitter.util.Future
import io.buoyant.router.RoutingFactory
import io.buoyant.router.RoutingFactory.{RequestIdentification, UnidentifiedRequest}
import io.buoyant.linkerd.protocol.http.ErrorResponder

class AuthIdentifier extends RoutingFactory.Identifier[Request] {
  
  def apply(req: Request): Future[RequestIdentification[Request]] = {
    val auth = req.headerMap.get("Authorization")
    if (auth.isEmpty) {
      val response = Headers.Err.respond("Unauthorized", Status.fromCode(401))
      throw ErrorResponder.HttpResponseException(response)
    }
    Future.value(new UnidentifiedRequest[Request]("next"))
  }
}

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