我创建了一个简单的 REST Web 服务,它{"code":4,"type":"ok","message":"hello there!"}
从curl -k -u admin:admin -X GET "https://server.running.service:8447/demo/v1/test"
我想让所有用户通过 Apache Knox 访问 Web 服务,以便他们可以通过身份验证。但是,当我使用时,curl -k -u admin:admin -X GET "https://server.running.knox:8443/gateway/platform//hello/v1/test"
我回来了:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 500 Server Error</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /gateway/platform/hello/v1/test. Reason:
<pre> Server Error</pre></p><hr /><i><small>Powered by Jetty://</small></i><br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</body>
</html>
查看 Knox gateway.log 文件,我可以看到这个错误:
INFO hadoop.gateway (KnoxLdapRealm.java:getUserDn(556)) - Computed userDn: uid=admin,ou=people,dc=hadoop,dc=apache,dc=org using dnTemplate for principal: admin
2017-03-20 14:15:53,289 INFO hadoop.gateway (AclsAuthorizationFilter.java:doFilter(85)) - Access Granted: true
2017-03-20 14:15:53,296 WARN hadoop.gateway (DefaultDispatch.java:executeOutboundRequest(138)) - Connection exception dispatching request: https://server.running.knox:8443/gateway/platform/hello/v1/test?user.name=admin javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.apache.hadoop.gateway.dispatch.DefaultDispatch.executeOutboundRequest(DefaultDispatch.java:127)
at org.apache.hadoop.gateway.dispatch.DefaultDispatch.executeRequest(DefaultDispatch.java:114)
at org.apache.hadoop.gateway.dispatch.DefaultDispatch.doGet(DefaultDispatch.java:294)
at org.apache.hadoop.gateway.dispatch.GatewayDispatchFilter$GetAdapter.doMethod(GatewayDispatchFilter.java:145)
at org.apache.hadoop.gateway.dispatch.GatewayDispatchFilter.doFilter(GatewayDispatchFilter.java:117)
at org.apache.hadoop.gateway.filter.AbstractGatewayFilter.doFilter(AbstractGatewayFilter.java:61)
at org.apache.hadoop.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:315)
at org.apache.hadoop.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:215)
at org.apache.hadoop.gateway.filter.AclsAuthorizationFilter.doFilter(AclsAuthorizationFilter.java:89)
at org.apache.hadoop.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:315)
at org.apache.hadoop.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:215)
我不确定将服务添加到 Knox 时是否犯了错误。我用以下内容创建了一个 rewrite.xml:
<rules>
<rule dir="IN" name="HELLOSERVICE/hello/inbound/root" pattern="*://*:*
/**/hello/">
<rewrite template="{$serviceUrl[HELLOSERVICE]}/"/>
</rule>
<rule dir="IN" name="HELLOSERVICE/hello/inbound/path" pattern="*://*:*/**/hello/{**}">
<rewrite template="{$serviceUrl[HELLOSERVICE]}/{**}"/>
</rule>
<rule dir="IN" name="HELLOSERVICE/hello/inbound/query" pattern="*://*:*/**/hello/{**}?{**}">
<rewrite template="{$serviceUrl[HELLOSERVICE]}/{**}?{**}"/>
</rule>
<rule dir="OUT" name="HELLOSERVICE/hello/outbound/demo/v1">
<match pattern="*://*:*/demo/v1/{**}"/>
<rewrite template="{$frontend[url]}/hello/v1/{**}"/>
</rule>
</rules>
和一个 service.xml 具有以下内容:
<service role="HELLOSERVICE" name="hello" version="0.0.1">
<routes>
<route path="/hello/"/>
<route path="/hello/**"/>
<route path="/hello/**?**"/>
</routes>
</service>
platform.xml 文件具有:
<topology>
<gateway>
<provider>
<role>authentication</role>
<name>ShiroProvider</name>
<enabled>true</enabled>
<param>
<name>sessionTimeout</name>
<value>30</value>
</param>
<param>
<name>main.ldapRealm</name>
<value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
</param>
<param>
<name>main.ldapRealm.userDnTemplate</name>
<value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>
<param>
<name>main.ldapRealm.contextFactory.url</name>
<value>ldap://server.running.knox:33389</value>
</param>
<param>
<name>main.ldapRealm.contextFactory.authenticationMechanism</name>
<value>simple</value>
</param>
<param>
<name>urls./**</name>
<value>authcBasic</value>
</param>
</provider>
<provider>
<role>identity-assertion</role>
<name>Default</name>
<enabled>true</enabled>
</provider>
<provider>
<role>authorization</role>
<name>AclsAuthz</name>
<enabled>true</enabled>
</provider>
<provider>
<role>webappsec</role>
<name>WebAppSec</name>
<enabled>true</enabled>
<param><name>csrf.enabled</name><value>false</value></param> <!-- CSRF Disabled -->
<param><name>csrf.customHeader</name><value>X-XSRF-Header</value></param>
<param><name>csrf.methodsToIgnore</name><value>GET,OPTIONS,HEAD</value></param>
<param><name>cors.enabled</name><value>true</value></param>
<param><name>cors.allowOrigin</name><value>*</value></param>
<param><name>cors.allowSubdomains</name><value>false</value></param>
<param><name>cors.supportedMethods</name><value>GET,POST,HEAD,OPTIONS,PUT,DELETE</value></param>
</provider>
</gateway>
<service>
<role>HELLOSERVICE</role>
<url>http://server.running.service:8088/demo</url>
</service>
</topology>
我在设置 Knox 时犯了错误吗?为了能够通过 Knox 向我的服务发送命令,我还需要做一些其他配置吗?