运行WSO2 AM 1.10.0的{新)已发布API时,范围验证失败

时间:2016-02-07 18:28:29

标签: api wso2 wso2-am

我在下面的答案中提供了一个工作代码,因为这套API相对较新,我在网络上看不到其他端到端示例,因此可能有用任何希望使用新API API的人的参考资料。

我正在尝试使用WSO2 AM 1.10.0的新发布API集。我根据Sanjeewa Malalgoda的一篇文章写了一个样本客户端:http://wso2.com/library/articles/2015/11/article-introducing-wso2-api-manager-new-rest-api-for-store-and-publisher-operations

以下是基于该文章的代码并修复了一些小错误/拼写错误:

  package test;

  import java.io.IOException;
  import java.io.UnsupportedEncodingException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.Base64;
  import java.util.HashMap;
  import java.util.Map;

  import org.json.JSONObject;
  import org.wso2.carbon.automation.engine.exceptions.AutomationFrameworkException;
  import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
  import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;

  public class test 
  {
    public static void main(String[] args) throws
        UnsupportedEncodingException,
        AutomationFrameworkException,
        InterruptedException,
        MalformedURLException,
        IOException
    {

        //    PHASE 1: REGISTER CLIENT
        //    ------------------------

        String dcrEndpointURL = getKeyManagerURLHttp() +
                              "client-registration/v0.9/register";

        String applicationRequestBody = " {\n" +
                    " \"callbackUrl\": \"google.sk\",\n" +
                    " \"clientName\": \"test_11\",\n" +
                    " \"tokenScope\": \"Production\",\n" +
                    " \"owner\": \"admin\",\n" +
                    " \"grantType\": \"password refresh_token\",\n" +
                    " \"saasApp\": true\n" +
                    " }";
        Map<String, String> dcrRequestHeaders = new HashMap<String, String>();

        //  This is base 64 encoded basic Auth value for user name admin and password admin.
        String basicAuthAdmin = "admin" + ":" + "admin";
        byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
        dcrRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
        System.out.println(dcrRequestHeaders.get("Authorization"));

        dcrRequestHeaders.put("Content-Type", "application/json");

        JSONObject clientRegistrationResponse = new JSONObject(HttpRequestUtil.doPost(
             new URL(dcrEndpointURL), 
             applicationRequestBody,dcrRequestHeaders));

        System.out.println(clientRegistrationResponse);

        consumerKey = new JSONObject(clientRegistrationResponse.getString("data")).get("clientId").toString();
        consumerSecret =new JSONObject(clientRegistrationResponse.getString("data")).get("clientSecret").toString();
        System.out.println(consumerKey);
        System.out.println(consumerSecret);

        Thread.sleep(2000);

        //    PHASE 2: REQUEST TOKEN
        //    ----------------------

        String requestBody = "grant_type=password&username=admin&password=admin&scope=API_CREATOR_SCOPE";

        URL tokenEndpointURL = new URL(getGatewayURLNhttp() + "token");

        Map<String, String> authenticationRequestHeaders = new HashMap<String, String>();
        String basicAuthConsumer = consumerKey + ":" + consumerSecret;
        byte [] encodedBytesConsumer = Base64.getEncoder().encode(basicAuthConsumer.getBytes("UTF-8"));
        authenticationRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesConsumer, "UTF-8"));

        JSONObject accessTokenGenerationResponse = new JSONObject(HttpRequestUtil.doPost(tokenEndpointURL, requestBody, authenticationRequestHeaders));
        System.out.println(accessTokenGenerationResponse);

        //Get access token and refresh token from token API call.
        //Now we have access token and refresh token that we can use to invoke API.
        JSONObject tokenData = new JSONObject(accessTokenGenerationResponse.getString("data"));
        String userAccessToken = tokenData.getString("access_token"); 
        String refreshToken = tokenData.getString("refresh_token");
        System.out.println("Access token: " + userAccessToken);     
        System.out.println("Refresh token: " + refreshToken);

        //    PHASE 3: CALL THE API
        //    ---------------------

        Map<String, String> requestHeaders = new HashMap<String, String>();     
        requestHeaders.put("Authorization", "Bearer " + userAccessToken);

        System.out.println(requestHeaders);

        HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis?query=admin&type=provide",requestHeaders);
        System.out.println(response.getResponseCode());
        System.out.println(response.getResponseMessage());      
    }

    static String getKeyManagerURLHttp()
    {
        return "http://127.0.0.1:9763/";
    }

    static String getGatewayURLNhttp()
    {
        return "http://127.0.0.1:8280/";
    }
  }

代码注册客户端并成功返回访问和刷新令牌。

以下是令牌请求的响应:

"data":     
    {
      "access_token": "bb5176def22ffbc4a7b12d2fd1ee9733",
      "refresh_token": "357926275971df21f9529ebb30ba36d1",
      "scope":"default",
      "token_type":"Bearer",
      "expires_in":2502
    }

但是,当我在API查询的标题中发送此标记时:

    {Authorization=Bearer bb5176def22ffbc4a7b12d2fd1ee9733}

我收到错误代码401 /未经授权。

查看服务器日志,我得到以下信息:

[2016-02-07 17:38:20,371] ERROR - WebAppAuthenticatorImpl You cannot access API as scope validation failed
[2016-02-07 17:38:20,372]  WARN - PhaseInterceptorChain Interceptor for {http://publisher.api.rest.apimgt.carbon.wso2.org/}SubscriptionsApi has thrown exception, unwinding now
org.apache.cxf.interceptor.security.AuthenticationException: Unauthenticated request
        at org.wso2.carbon.apimgt.rest.api.util.interceptors.auth.OAuthAuthenticationInterceptor.handleMessage(OAuthAuthenticationInterceptor.java:62)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:217)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:268)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
        at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke(CarbonTomcatValve.java:47)
        at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(TenantLazyLoaderValve.java:57)
        at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:47)
        at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
        at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:159)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
        at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1698)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

一些注释

  1. 我正在运行版本1.10.0,来自http://wso2.com/api-management/try-it
  2. WSO2我在此部署中发布的API都是v0.9(而不是v1,如某些示例中所示)
  3. 我尝试了API_CREATOR_SCOPE,API_PUBLISHER_SCOPE的令牌请求。两者都失败了。
  4. 在令牌请求的响应中,它表示&#34;范围:默认&#34;。不确定这是否合适。
  5. 例外情况&#34;您无法访问API,因为范围验证失败&#34;,所以我猜范围存在问题。但我不确定为什么以及如何解决。

3 个答案:

答案 0 :(得分:1)

请检查/_system/config/apimgt/applicationdata/tenant-conf.json文件中可用的角色和范围。然后请求带有那里提到的范围的令牌。然后,您将获得具有正确范围的访问令牌。请注意,具有默认范围的令牌不能用于REST API功能。

答案 1 :(得分:1)

对于基本身份验证,请将repository \ deployment \ server \ webapps \ api #am#publisher#v0.9 \ WEB-INF的beans.xml更改为:

<bean id="AuthenticationInterceptor" class="org.wso2.carbon.apimgt.rest.api.util.interceptors.auth.BasicAuthenticationInterceptor" />

然后代码大大简化了:

public class test {

public static void main(String[] args) throws
    UnsupportedEncodingException,
    AutomationFrameworkException,
    InterruptedException,
    MalformedURLException,
    IOException
{
    String dcrEndpointURL = getKeyManagerURLHttp()+"client-registration/v0.9/register";

    String basicAuthAdmin = "admin" + ":" + "admin";
    byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
    Map<String, String> requestHeaders = new HashMap<String, String>();     
    requestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));

    System.out.println(requestHeaders);

    HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis",requestHeaders);
    System.out.println(response.getResponseCode());
    System.out.println(response.getResponseMessage());      
    System.out.println(response.getData());

    HttpResponse response1 = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/subscriptions",requestHeaders);
    System.out.println(response1.getResponseCode());
    System.out.println(response1.getResponseMessage());
    System.out.println(response1.getData());

}

static String getKeyManagerURLHttp()
{
    return "http://127.0.0.1:9763/";
}

static String getGatewayURLNhttp()
{
    return "http://127.0.0.1:8280/";
}
}

答案 2 :(得分:0)

这是一个工作示例,遵循Sanjeewa的修复。

  package test;

  import java.io.IOException;
  import java.io.UnsupportedEncodingException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.Base64;
  import java.util.HashMap;
  import java.util.Map;

  import org.json.JSONObject;
  import org.wso2.carbon.automation.engine.exceptions.AutomationFrameworkException;
  import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
  import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;

  public class test 
  {
    public static void main(String[] args) throws
        UnsupportedEncodingException,
        AutomationFrameworkException,
        InterruptedException,
        MalformedURLException,
        IOException
    {

        //    PHASE 1: REGISTER CLIENT
        //    ------------------------

        String dcrEndpointURL = getKeyManagerURLHttp() +
                              "client-registration/v0.9/register";

        String applicationRequestBody = " {\n" +
                    " \"callbackUrl\": \"google.sk\",\n" +
                    " \"clientName\": \"test_11\",\n" +
                    " \"tokenScope\": \"Production\",\n" +
                    " \"owner\": \"admin\",\n" +
                    " \"grantType\": \"password refresh_token\",\n" +
                    " \"saasApp\": true\n" +
                    " }";
        Map<String, String> dcrRequestHeaders = new HashMap<String, String>();

        //  This is base 64 encoded basic Auth value for user name admin and password admin.
        String basicAuthAdmin = "admin" + ":" + "admin";
        byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
        dcrRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
        System.out.println(dcrRequestHeaders.get("Authorization"));

        dcrRequestHeaders.put("Content-Type", "application/json");

        JSONObject clientRegistrationResponse = new JSONObject(HttpRequestUtil.doPost(
             new URL(dcrEndpointURL), 
             applicationRequestBody,dcrRequestHeaders));

        System.out.println(clientRegistrationResponse);

        consumerKey = new JSONObject(clientRegistrationResponse.getString("data")).get("clientId").toString();
        consumerSecret =new JSONObject(clientRegistrationResponse.getString("data")).get("clientSecret").toString();
        System.out.println(consumerKey);
        System.out.println(consumerSecret);

        Thread.sleep(2000);

        //    PHASE 2: REQUEST TOKEN
        //    ----------------------

        String requestBody = "grant_type=password&username=admin&password=admin&scope=apim:view_api";

        URL tokenEndpointURL = new URL(getGatewayURLNhttp() + "token");

        Map<String, String> authenticationRequestHeaders = new HashMap<String, String>();
        String basicAuthConsumer = consumerKey + ":" + consumerSecret;
        byte [] encodedBytesConsumer = Base64.getEncoder().encode(basicAuthConsumer.getBytes("UTF-8"));
        authenticationRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesConsumer, "UTF-8"));

        JSONObject accessTokenGenerationResponse = new JSONObject(HttpRequestUtil.doPost(tokenEndpointURL, requestBody, authenticationRequestHeaders));
        System.out.println(accessTokenGenerationResponse);

        //Get access token and refresh token from token API call.
        //Now we have access token and refresh token that we can use to invoke API.
        JSONObject tokenData = new JSONObject(accessTokenGenerationResponse.getString("data"));
        String userAccessToken = tokenData.getString("access_token"); 
        String refreshToken = tokenData.getString("refresh_token");
        System.out.println("Access token: " + userAccessToken);     
        System.out.println("Refresh token: " + refreshToken);

        //    PHASE 3: CALL THE API
        //    ---------------------

        Map<String, String> requestHeaders = new HashMap<String, String>();     
        requestHeaders.put("Authorization", "Bearer " + userAccessToken);

        System.out.println(requestHeaders);

        HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis?query=admin&type=provide",requestHeaders);
        System.out.println(response.getResponseCode());
        System.out.println(response.getResponseMessage());      
        System.out.println(response.getData());     
    }

    static String getKeyManagerURLHttp()
    {
        return "http://127.0.0.1:9763/";
    }

    static String getGatewayURLNhttp()
    {
        return "http://127.0.0.1:8280/";
    }
  }

结果:

200
OK
{"count":1,"next":"","list":[{"name":"employees","context":"/employees","id":"09cef2c8-89f0-405e-97af-225942a52d83","description":null,"version":"1.0.0","provider":"admin","status":"PUBLISHED"}],"previous":""}