【问题标题】:Restlet client use authentication keyRestlet 客户端使用身份验证密钥
【发布时间】:2015-06-01 14:38:38
【问题描述】:

使用restlet JEE 2.3.2。

我有一个客户端 id 和密码来与服务器 restful API 交互。提交该信息可以让我取回必须用于后续请求的授权密钥。在 curl 中,我可以使用该键进行查询并获取数据:

curl -XGET "Authorization c79cec57-a52f-4e04-f3ca-55ea2a202114" "https://some/restful/endpoint"

如何设置我的客户端资源以提交该授权密钥?在线文档似乎没有涵盖这种情况。

【问题讨论】:

    标签: java restlet


    【解决方案1】:

    如果方案不重要,您可以使用“自定义”方案,(因为它在 HTTP 规范中是强制性的)。为了避免“restlet 引擎不支持方案”的警告,只需注册一个,如下:

    您可以使用“自定义”方案来实现您所需要的,如下所示。

        // Declare a custom Authenticator helper, if it is not standard
        Engine.getInstance().getRegisteredAuthenticators().add(new AuthenticatorHelper(ChallengeScheme.CUSTOM, true, false) {});
    
        // set up the reusable challenge response
        ChallengeResponse cred = new ChallengeResponse(ChallengeScheme.CUSTOM);
        cred.setRawValue("12344");
    
        ClientResource cr = new ClientResource("http://localhost:8183/");
        cr.setChallengeResponse(cred);
        cr.get();
    

    如果你想要一个空的方案,你可以这样做:

        ChallengeResponse cred = new ChallengeResponse(new ChallengeScheme("",""));
        cred.setRawValue("12345");
    

    【讨论】:

      【解决方案2】:

      在这种情况下,我认为您可以按照所述使用质询响应,因为此类功能使用格式 Authorization: Scheme ChallengeResponseContent 构建 Authorization 标头:

      ClientResource resource = new ClientResource(resouceURL);
      String token = "myToken";
      ChallengeResponse cr = new ChallengeResponse(
                   ChallengeScheme.HTTP_OAUTH_BEARER);
      cr.setRawValue(token);
      resource.setChallengeResponse(cr);
      (...)
      

      事实上,Restlet 需要一个质询方案,该方案将在标头 Authorization 的值内的令牌(或其他内容)之前添加。参见AuthenticatorUtils#formatRequest类的摘录:

      public static String formatRequest(ChallengeRequest challenge,
              Response response, Series<Header> httpHeaders) {
          String result = null;
      
          if (challenge == null) {
              Context.getCurrentLogger().warning(
                      "No challenge response to format.");
          } else if (challenge.getScheme() == null) {
              Context.getCurrentLogger().warning(
                      "A challenge response must have a scheme defined.");
          } else if (challenge.getScheme().getTechnicalName() == null) {
              Context.getCurrentLogger().warning(
                      "A challenge scheme must have a technical name defined.");
          } else {
              ChallengeWriter cw = new ChallengeWriter();
              cw.append(challenge.getScheme().getTechnicalName()).appendSpace();
              int cwInitialLength = cw.getBuffer().length();
      
              if (challenge.getRawValue() != null) {
                  cw.append(challenge.getRawValue());
              } else {
          (...)
      

      在你的情况下,我认为你需要自己构建标题Authorization,如下所述:

      ClientResource resource = new ClientResource(resouceURL);
      String token = "myToken";
      resource.getRequest().getHeaders().add("Authorization", token);
      resource.get();
      

      您还可以根据需要实现自定义客户端资源,以便自动应用令牌:

      public class ProtectedClientResource extends ClientResource {
          private String token;
      
          public ProtectedClientResource(String uri) {
              super(uri);
          }
      
          @Override
          public Response handleOutbound(Request request) {
              if (token!=null) {
                  request.getHeaders().add("Authorization", token);
              }
              return super.handleOutbound(request);
          }
      
          public String getToken() {
              return token;
          }
      
          public void setToken(String token) {
              this.token = token;
          }
      }
      

      希望对你有帮助 蒂埃里

      【讨论】:

      • 我已经通过 resource.getRequest().getHeaders().add("Authorization", token); 添加了标题,但出现以下错误:2015 年 6 月 1 日上午 10:49:27 org.restlet.engine.header.HeaderUtils addExtensionHeaders 警告:添加标准标题“授权”是不允许的。请使用 Restlet API 中的等效属性。
      • 我也尝试过ChallengeResponse cr = new ChallengeResponse( ChallengeScheme.HTTP_OAUTH_BEARER); cr.setRawValue(token); resource.setChallengeResponse(cr);,但收到以下错误:警告:Restlet 引擎不支持挑战方案 HTTP_Bearer。
      • 是的,但是使用 OAuth 承载,您将拥有类似的内容:Authorization: Bearer mytoken... 即使您有消息(您不必将 oauth 扩展名放在类路径中),标头已添加到请求中...
      • 我使用的是 maven,除了 org.restlet 和各种表示扩展之外,我没有添加任何其他内容。 HTTP_Bearer not supported by restlet engine 在我调用 resource.get() 时发生,在此之前我看到服务器正在响应 401“请求需要用户身份验证”,所以它看起来不喜欢这种格式,可能是“承载”字符串在身份验证中...我只需要令牌字符串
      • 嗨,米乔。我做了一些测试,似乎限制是在 2.3.2 版本中添加的。它仅适用于 2.3.1 版。我将我的测试项目上传到 github。请参阅此网址:github.com/templth/restlet-stackoverflow/tree/master/restlet/…
      猜你喜欢
      • 2017-10-24
      • 1970-01-01
      • 2023-03-19
      • 2018-09-16
      • 2016-03-13
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      相关资源
      最近更新 更多