[ 
https://issues.apache.org/jira/browse/CXF-9149?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmitry Batmanov  updated CXF-9149:
----------------------------------
    Description: 
when using kerberos authentication on a proxy server:
{code:java}
    <d1p1:conduit 
xmlns:d1p1="http://cxf.apache.org/transports/http/configuration"; 
name="*.http-conduit">
        <d1p1:proxyAuthorization 
xmlns:sec="http://cxf.apache.org/configuration/security"; >
           <sec:UserName>[email protected]</sec:UserName>
            <sec:Password>my_pass</sec:Password>
            <sec:AuthorizationType>Negotiate</sec:AuthorizationType>
            <sec:Authorization>CXFClient</sec:Authorization>
        </d1p1:proxyAuthorization>
        <d1p1:client AllowChunking="false" ProxyServer="squid.example.com" 
ProxyServerPort="3128" />
    </d1p1:conduit> {code}
I get the following exception:
{code:java}
java.lang.RuntimeException: No valid credentials provided (Mechanism level: No 
valid credentials provided (Mechanism level: Server not found in Kerberos 
database (7) - LOOKING_UP_SERVER))
    at 
org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier.getAuthorization(AbstractSpnegoAuthSupplier.java:83)
 ~[!/:3.3.10]
    at 
org.apache.cxf.transport.http.auth.SpnegoAuthSupplier.getAuthorization(SpnegoAuthSupplier.java:37)
 ~[!/:3.3.10]
    at 
org.apache.cxf.transport.http.HTTPConduit.setHeadersByAuthorizationPolicy(HTTPConduit.java:814)
 ~[!/:3.3.10]
    at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:564) 
~[!/:3.3.10] {code}
on the kerberos server i see the following logs:
{code:java}
Jul 04 12:07:55 krb.example.com krb5kdc34: TGS_REQ (2 etypes 
{aes256-cts-hmac-sha1-96(18), aes128-cts-hmac-sha1-96(17)}) 172.17.0.1: 
LOOKING_UP_SERVER: authtime 0, etypes {rep=UNSUPPORTED:(0)} 
[email protected] for HTTP/[email protected], Server not 
found in Kerberos database {code}
it feels like it's trying to authenticate to an external 
service(my-external-service.com), not a proxy server
I tried to do approximately the same thing programmatically(last version cxf), 
but I get exactly the same behavior
{code:java}
import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.auth.SpnegoAuthSupplier;
import jakarta.ws.rs.core.Response;

public class RestClient {
    public static void main(String[] args) {
        System.setProperty("java.security.auth.login.config", "jaas.conf");
        System.setProperty("java.security.krb5.conf", "krb5.conf");
        System.setProperty("sun.security.krb5.debug", "true"); 
        WebClient client = WebClient.create("http://ext-service.com/";);

        HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();


        conduit.getClient().setProxyServer("squid.example.com");
        conduit.getClient().setProxyServerPort(3128);

        ProxyAuthorizationPolicy policy = new ProxyAuthorizationPolicy();
        policy.setAuthorizationType("Negotiate"); 
        policy.setAuthorization("CXFClient");

        policy.setUserName("[email protected]");
        policy.setPassword("123456");
        conduit.setProxyAuthorization(policy);

        SpnegoAuthSupplier authSupplier = new SpnegoAuthSupplier();
        conduit.setProxyAuthSupplier(authSupplier);

        Response postResponse = client.path("/")
                .type("application/json")
                .get();
        System.out.println(postResponse.getStatus());
    }
} {code}
I tried to debug the code and I realized that 
[HTTP/[email protected]|mailto:HTTP/[email protected]]
 - is formed in 
getCompleteServicePrincipalName(org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier)
 from uri to destination
my current solution is to write my own HttpAuthSupplier:
{code:java}
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
import org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier;
import org.apache.cxf.transport.http.auth.HttpAuthSupplier;
import java.net.URI;
import java.net.URISyntaxException;


public class ProxySpnegoAuthSupplier extends AbstractSpnegoAuthSupplier
        implements HttpAuthSupplier {

    @Override
    public boolean requiresRequestCaching() {
        return false;
    }

    @Override
    public String getAuthorization(AuthorizationPolicy  authPolicy,
                                   URI currentURI,
                                   Message message,
                                   String fullHeader) {
        try {
            return super.getAuthorization(authPolicy,  new URI("http://"+ 
((URLConnectionHTTPConduit) 
message.get("org.apache.cxf.transport.Conduit")).getClient().getProxyServer()), 
message);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
} {code}
now my java code works:
{code:java}
ProxySpnegoAuthSupplier authSupplier = new ProxySpnegoAuthSupplier();
conduit.setProxyAuthSupplier(authSupplier); {code}
but blueprint doesn't work, block ProxyAuthSupplieris missing in xml

and(Please note that I had to comment out block AuthorizationType)
{code:java}
<d1p1:conduit xmlns:d1p1="http://cxf.apache.org/transports/http/configuration"; 
name="*.http-conduit">
    <d1p1:authSupplier class="tim.integration.cxf.ProxySpnegoAuthSupplier"/>
    <d1p1:proxyAuthorization 
xmlns:sec="http://cxf.apache.org/configuration/security";>
        <sec:UserName>[email protected]</sec:UserName>
        <sec:Password>pass</sec:Password>
        <!-- <sec:AuthorizationType>Negotiate</sec:AuthorizationType >-->
        
<sec:Authorization>com.sun.security.jgss.krb5.initiate</sec:Authorization>
    </d1p1:proxyAuthorization>
    <d1p1:client AllowChunking="false" ProxyServer="squid.example.com" 
ProxyServerPort="3128"/>

</d1p1:conduit> {code}
I am not very familiar with cxf and I ask to clarify if there is a way to 
enable different authentication methods specifically on a proxy

  was:
when using kerberos authentication on a proxy server:
{code:java}
    <d1p1:conduit 
xmlns:d1p1="http://cxf.apache.org/transports/http/configuration"; 
name="*.http-conduit">
        <d1p1:proxyAuthorization 
xmlns:sec="http://cxf.apache.org/configuration/security"; >
           <sec:UserName>[email protected]</sec:UserName>
            <sec:Password>my_pass</sec:Password>
            <sec:AuthorizationType>Negotiate</sec:AuthorizationType>
            <sec:Authorization>CXFClient</sec:Authorization>
        </d1p1:proxyAuthorization>
        <d1p1:client AllowChunking="false" ProxyServer="squid.example.com" 
ProxyServerPort="3128" />
    </d1p1:conduit> {code}
I get the following exception:
{code:java}
java.lang.RuntimeException: No valid credentials provided (Mechanism level: No 
valid credentials provided (Mechanism level: Server not found in Kerberos 
database (7) - LOOKING_UP_SERVER))
    at 
org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier.getAuthorization(AbstractSpnegoAuthSupplier.java:83)
 ~[!/:3.3.10]
    at 
org.apache.cxf.transport.http.auth.SpnegoAuthSupplier.getAuthorization(SpnegoAuthSupplier.java:37)
 ~[!/:3.3.10]
    at 
org.apache.cxf.transport.http.HTTPConduit.setHeadersByAuthorizationPolicy(HTTPConduit.java:814)
 ~[!/:3.3.10]
    at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:564) 
~[!/:3.3.10] {code}
on the kerberos server i see the following logs:
{code:java}
Jul 04 12:07:55 krb.example.com krb5kdc34: TGS_REQ (2 etypes 
{aes256-cts-hmac-sha1-96(18), aes128-cts-hmac-sha1-96(17)}) 172.17.0.1: 
LOOKING_UP_SERVER: authtime 0, etypes {rep=UNSUPPORTED:(0)} 
[email protected] for HTTP/[email protected], Server not 
found in Kerberos database {code}
it feels like it's trying to authenticate to an external 
service(my-external-service.com), not a proxy server
I tried to do approximately the same thing programmatically(last version cxf), 
but I get exactly the same behavior
{code:java}
import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.auth.SpnegoAuthSupplier;
import jakarta.ws.rs.core.Response;

public class RestClient {
    public static void main(String[] args) {
        System.setProperty("java.security.auth.login.config", "jaas.conf");
        System.setProperty("java.security.krb5.conf", "krb5.conf");
        System.setProperty("sun.security.krb5.debug", "true"); 
        WebClient client = WebClient.create("http://ext-service.com/";);

        HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();


        conduit.getClient().setProxyServer("squid.example.com");
        conduit.getClient().setProxyServerPort(3128);

        ProxyAuthorizationPolicy policy = new ProxyAuthorizationPolicy();
        policy.setAuthorizationType("Negotiate"); 
        policy.setAuthorization("CXFClient");

        policy.setUserName("[email protected]");
        policy.setPassword("123456");
        conduit.setProxyAuthorization(policy);

        SpnegoAuthSupplier authSupplier = new SpnegoAuthSupplier();
        conduit.setProxyAuthSupplier(authSupplier);

        Response postResponse = client.path("/")
                .type("application/json")
                .get();
        System.out.println(postResponse.getStatus());
    }
} {code}
I tried to debug the code and I realized that 
[HTTP/[email protected]|mailto:HTTP/[email protected]]
 - is formed in 
getCompleteServicePrincipalName(org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier)
 from uri to destination
my current solution is to write my own HttpAuthSupplier:

{code:java}
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
import org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier;
import org.apache.cxf.transport.http.auth.HttpAuthSupplier;
import java.net.URI;
import java.net.URISyntaxException;


public class ProxySpnegoAuthSupplier extends AbstractSpnegoAuthSupplier
        implements HttpAuthSupplier {

    @Override
    public boolean requiresRequestCaching() {
        return false;
    }

    @Override
    public String getAuthorization(AuthorizationPolicy  authPolicy,
                                   URI currentURI,
                                   Message message,
                                   String fullHeader) {
        try {
            return super.getAuthorization(authPolicy,  new URI("http://"+ 
((URLConnectionHTTPConduit) 
message.get("org.apache.cxf.transport.Conduit")).getClient().getProxyServer()), 
message);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
} {code}
and(Please note that I had to comment out block AuthorizationType)
{code:java}
<d1p1:conduit xmlns:d1p1="http://cxf.apache.org/transports/http/configuration"; 
name="*.http-conduit">
    <d1p1:authSupplier class="tim.integration.cxf.ProxySpnegoAuthSupplier"/>
    <d1p1:proxyAuthorization 
xmlns:sec="http://cxf.apache.org/configuration/security";>
        <sec:UserName>[email protected]</sec:UserName>
        <sec:Password>pass</sec:Password>
        <!-- <sec:AuthorizationType>Negotiate</sec:AuthorizationType >-->
        
<sec:Authorization>com.sun.security.jgss.krb5.initiate</sec:Authorization>
    </d1p1:proxyAuthorization>
    <d1p1:client AllowChunking="false" ProxyServer="squid.example.com" 
ProxyServerPort="3128"/>

</d1p1:conduit> {code}
I am not very familiar with cxf and I ask to clarify if there is a way to 
enable different authentication methods specifically on a proxy


> Kerberos authentication error on proxy server 
> ----------------------------------------------
>
>                 Key: CXF-9149
>                 URL: https://issues.apache.org/jira/browse/CXF-9149
>             Project: CXF
>          Issue Type: Bug
>          Components: Transports
>         Environment: cxf 3.3.10 (karaf 4.2.16, java 1.8)
> cxf 4.1.2(java 22)
>            Reporter: Dmitry Batmanov 
>            Priority: Major
>
> when using kerberos authentication on a proxy server:
> {code:java}
>     <d1p1:conduit 
> xmlns:d1p1="http://cxf.apache.org/transports/http/configuration"; 
> name="*.http-conduit">
>         <d1p1:proxyAuthorization 
> xmlns:sec="http://cxf.apache.org/configuration/security"; >
>            <sec:UserName>[email protected]</sec:UserName>
>             <sec:Password>my_pass</sec:Password>
>             <sec:AuthorizationType>Negotiate</sec:AuthorizationType>
>             <sec:Authorization>CXFClient</sec:Authorization>
>         </d1p1:proxyAuthorization>
>         <d1p1:client AllowChunking="false" ProxyServer="squid.example.com" 
> ProxyServerPort="3128" />
>     </d1p1:conduit> {code}
> I get the following exception:
> {code:java}
> java.lang.RuntimeException: No valid credentials provided (Mechanism level: 
> No valid credentials provided (Mechanism level: Server not found in Kerberos 
> database (7) - LOOKING_UP_SERVER))
>     at 
> org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier.getAuthorization(AbstractSpnegoAuthSupplier.java:83)
>  ~[!/:3.3.10]
>     at 
> org.apache.cxf.transport.http.auth.SpnegoAuthSupplier.getAuthorization(SpnegoAuthSupplier.java:37)
>  ~[!/:3.3.10]
>     at 
> org.apache.cxf.transport.http.HTTPConduit.setHeadersByAuthorizationPolicy(HTTPConduit.java:814)
>  ~[!/:3.3.10]
>     at 
> org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:564) 
> ~[!/:3.3.10] {code}
> on the kerberos server i see the following logs:
> {code:java}
> Jul 04 12:07:55 krb.example.com krb5kdc34: TGS_REQ (2 etypes 
> {aes256-cts-hmac-sha1-96(18), aes128-cts-hmac-sha1-96(17)}) 172.17.0.1: 
> LOOKING_UP_SERVER: authtime 0, etypes {rep=UNSUPPORTED:(0)} 
> [email protected] for HTTP/[email protected], Server not 
> found in Kerberos database {code}
> it feels like it's trying to authenticate to an external 
> service(my-external-service.com), not a proxy server
> I tried to do approximately the same thing programmatically(last version 
> cxf), but I get exactly the same behavior
> {code:java}
> import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
> import org.apache.cxf.jaxrs.client.WebClient;
> import org.apache.cxf.transport.http.HTTPConduit;
> import org.apache.cxf.transport.http.auth.SpnegoAuthSupplier;
> import jakarta.ws.rs.core.Response;
> public class RestClient {
>     public static void main(String[] args) {
>         System.setProperty("java.security.auth.login.config", "jaas.conf");
>         System.setProperty("java.security.krb5.conf", "krb5.conf");
>         System.setProperty("sun.security.krb5.debug", "true"); 
>         WebClient client = WebClient.create("http://ext-service.com/";);
>         HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
>         conduit.getClient().setProxyServer("squid.example.com");
>         conduit.getClient().setProxyServerPort(3128);
>         ProxyAuthorizationPolicy policy = new ProxyAuthorizationPolicy();
>         policy.setAuthorizationType("Negotiate"); 
>         policy.setAuthorization("CXFClient");
>         policy.setUserName("[email protected]");
>         policy.setPassword("123456");
>         conduit.setProxyAuthorization(policy);
>         SpnegoAuthSupplier authSupplier = new SpnegoAuthSupplier();
>         conduit.setProxyAuthSupplier(authSupplier);
>         Response postResponse = client.path("/")
>                 .type("application/json")
>                 .get();
>         System.out.println(postResponse.getStatus());
>     }
> } {code}
> I tried to debug the code and I realized that 
> [HTTP/[email protected]|mailto:HTTP/[email protected]]
>  - is formed in 
> getCompleteServicePrincipalName(org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier)
>  from uri to destination
> my current solution is to write my own HttpAuthSupplier:
> {code:java}
> import org.apache.cxf.configuration.security.AuthorizationPolicy;
> import org.apache.cxf.message.Message;
> import org.apache.cxf.transport.http.URLConnectionHTTPConduit;
> import org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier;
> import org.apache.cxf.transport.http.auth.HttpAuthSupplier;
> import java.net.URI;
> import java.net.URISyntaxException;
> public class ProxySpnegoAuthSupplier extends AbstractSpnegoAuthSupplier
>         implements HttpAuthSupplier {
>     @Override
>     public boolean requiresRequestCaching() {
>         return false;
>     }
>     @Override
>     public String getAuthorization(AuthorizationPolicy  authPolicy,
>                                    URI currentURI,
>                                    Message message,
>                                    String fullHeader) {
>         try {
>             return super.getAuthorization(authPolicy,  new URI("http://"+ 
> ((URLConnectionHTTPConduit) 
> message.get("org.apache.cxf.transport.Conduit")).getClient().getProxyServer()),
>  message);
>         } catch (URISyntaxException e) {
>             throw new RuntimeException(e);
>         }
>     }
> } {code}
> now my java code works:
> {code:java}
> ProxySpnegoAuthSupplier authSupplier = new ProxySpnegoAuthSupplier();
> conduit.setProxyAuthSupplier(authSupplier); {code}
> but blueprint doesn't work, block ProxyAuthSupplieris missing in xml
> and(Please note that I had to comment out block AuthorizationType)
> {code:java}
> <d1p1:conduit 
> xmlns:d1p1="http://cxf.apache.org/transports/http/configuration"; 
> name="*.http-conduit">
>     <d1p1:authSupplier class="tim.integration.cxf.ProxySpnegoAuthSupplier"/>
>     <d1p1:proxyAuthorization 
> xmlns:sec="http://cxf.apache.org/configuration/security";>
>         <sec:UserName>[email protected]</sec:UserName>
>         <sec:Password>pass</sec:Password>
>         <!-- <sec:AuthorizationType>Negotiate</sec:AuthorizationType >-->
>         
> <sec:Authorization>com.sun.security.jgss.krb5.initiate</sec:Authorization>
>     </d1p1:proxyAuthorization>
>     <d1p1:client AllowChunking="false" ProxyServer="squid.example.com" 
> ProxyServerPort="3128"/>
> </d1p1:conduit> {code}
> I am not very familiar with cxf and I ask to clarify if there is a way to 
> enable different authentication methods specifically on a proxy



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to