Giter Site home page Giter Site logo

Comments (17)

shumonsharif avatar shumonsharif commented on June 2, 2024 2

@dufoli What you're proposing sounds appropriate, I like the idea of leveraging the producer or supplier annotations if available.

I'm not sure if it makes sense to use a custom configuration converter to configure the input parameter map?
https://quarkus.io/guides/config-reference#custom-configuration-converters

Will need to give this some deeper thought, and will keep you posted if I have anything to add!

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024 1

analyse:

  • interceptors can been added with application.properties:
    example:
quarkus.cxf.endpoint."/foo".in-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
quarkus.cxf.endpoint."/foo".out-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor

but interceptors need a map as inputs parameters
cf: https://cxf.apache.org/docs/ws-security.html

I do not know what is the best to configure that ?
any feedback from community to find the best solution: @bnazare @shumonsharif @antonwiens
I am thinking to add interceptors as beans and if I found producer annotation or supplier annotation, used them instead of generate instance directly...
wdyt ?

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024 1

ok so solution, can you test :
config:

quarkus.cxf.endpoint."/foo".in-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
quarkus.cxf.endpoint."/foo".out-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor

create a class with this method

@Produce 
public WSS4JInInterceptor getWSS4JInInterceptor() {
    Map<String,Object> inProps = new HashMap<String,Object>();
    inProps.put(WSHandlerConstants.HANDLER_ACTIONS, "UsernameToken"); 
    inProps.put(WSS4JConstants.PASSWORD_TYPE_ATTR, "PasswordDigest"); 
    inProps.put("signaturePropFile", "..."); 
    inProps.put(ConfigurationConstants.PW_CALLBACK_CLASS, cb); 
    return new WSS4JInInterceptor(inProps);
}
@Produce 
public WSS4JOutInterceptor getWSS4JOutInterceptor() {
    Map<String,Object> outProps = new HashMap<String,Object>();
    //same process here
    //outProps.put(); 
    return new WSS4JOutInterceptor(outProps);
}

from quarkus-cxf.

shumonsharif avatar shumonsharif commented on June 2, 2024 1

I may not have framed my question properly ... :) I was referring to the below ...

quarkus.cxf.endpoint."/foo".in-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
quarkus.cxf.endpoint."/foo".out-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor

What I was trying to confirm is that the server only needs to accept and validate the credentials using WSS4JInInterceptor - the client on the other hand needs to only send the proper credentials using WSS4JOutInterceptor. So server needs in-interceptor, and client needs out-interceptor. In any case, will test and keep you posted.

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024 1

I think you are right on your last comment

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024 1

to add in #147

from quarkus-cxf.

antonwiens avatar antonwiens commented on June 2, 2024

The Interceptor may also need objects for initialization. You can set the "merlin" instance for the wss4j In/Out Interceptor for example. So simple String values will not suffice. Another example is setting the Password Callback for the Out Interceptor. This also requires passing an class object. So maybe you could add the ability to configure a Callback for each interceptor which provides a configuration map.

for example:
quarkus.cxf.endpoint."/foo".out-interceptors."org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor".config-callback=org.example.MyConfigMapCallback
But this looks a bit long.

from quarkus-cxf.

bnazare avatar bnazare commented on June 2, 2024

I would propose that, when complex configuration is required, users should create their own feature and use it in the endpoint configuration instead of using just interceptors. Within the new feature, the user would then be able to execute any code necessary to discover and produce adequate configuration objects.

Creating a new extension is as simple as extending org.apache.cxf.feature.AbstractFeature and overriding initializeProvider(). Here's an example.

from quarkus-cxf.

bnazare avatar bnazare commented on June 2, 2024

Adding to my previous point, CXF features also have access to the Clients or Endpoints being created which allows for them to perform slightly different configurations depending on the specifics of each service.

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024

for feature ok, for use case of security, WSS4JOutInterceptor we have not equivalent to0 initializeProvider() but we can set up the props inside the ctor....

from quarkus-cxf.

antonwiens avatar antonwiens commented on June 2, 2024

ok so solution, can you test :
config:

quarkus.cxf.endpoint."/foo".in-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
quarkus.cxf.endpoint."/foo".out-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor

create a class with this method

@Produce 
public WSS4JInInterceptor getWSS4JInInterceptor() {
    Map<String,Object> inProps = new HashMap<String,Object>();
    inProps.put(WSHandlerConstants.HANDLER_ACTIONS, "UsernameToken"); 
    inProps.put(WSS4JConstants.PASSWORD_TYPE_ATTR, "PasswordDigest"); 
    inProps.put("signaturePropFile", "..."); 
    inProps.put(ConfigurationConstants.PW_CALLBACK_CLASS, cb); 
    return new WSS4JInInterceptor(inProps);
}
@Produce 
public WSS4JOutInterceptor getWSS4JOutInterceptor() {
    Map<String,Object> outProps = new HashMap<String,Object>();
    //same process here
    //outProps.put(); 
    return new WSS4JOutInterceptor(outProps);
}

Thanks, i will try it out!

from quarkus-cxf.

shumonsharif avatar shumonsharif commented on June 2, 2024

I will also test this out today, will keep you posted @dufoli ... I'm assuming the in-interceptor should only be set for the web service, while the out-interceptor should only be for the client, is that correct?

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024

Nope.
For server:
In interceptor is for incoming request
Out interceptor is for outgoing response
For clients :
It start with out interceptor when sending request
Then when response is received, in interceptor is invoked.

from quarkus-cxf.

shumonsharif avatar shumonsharif commented on June 2, 2024

@dufoli and all, I can confirm that the @Produces annotations are working beautifully. I think we're in good shape with this approach, and folks can refer to the WSS4J guide for their more complex needs.

Here's what I implemented for the server:

quarkus.cxf.endpoint."/test".in-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.wss4j.common.ConfigurationConstants;
import org.jboss.logging.Logger;

import javax.enterprise.inject.Produces;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
import java.util.HashMap;
import java.util.Map;

@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
public class TestEndpoint implements Test {

    private static final Logger logger = Logger.getLogger(TestEndpoint.class);

    @Override
    public String test(String val) {
        logger.info("Hit test endpoint");
        return val;
    }

    @Produces
    public WSS4JInInterceptor getWSS4JInInterceptor() {
        Map<String,Object> inProps = new HashMap<String,Object>();
        inProps.put(ConfigurationConstants.ACTION, "UsernameToken");
        inProps.put(ConfigurationConstants.PASSWORD_TYPE, "PasswordDigest");
        inProps.put(ConfigurationConstants.PW_CALLBACK_CLASS, UsernameTokenPasswordServerCallback.class.getName());
        return new WSS4JInInterceptor(inProps);
    }

}
import org.apache.wss4j.common.ext.WSPasswordCallback;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class UsernameTokenPasswordServerCallback implements CallbackHandler {

    private Map<String, String> passwords = new HashMap();

    public UsernameTokenPasswordServerCallback() {
        passwords.put("joe", "wss4j");
        passwords.put("test", "password");
    }

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            WSPasswordCallback pc = (WSPasswordCallback) callback;
            String pass = passwords.get(pc.getIdentifier());
            if (pass != null) {
                pc.setPassword(pass);
                return;
            }
        }
    }
}

Here's what needed to be done for the client.

quarkus.cxf.endpoint."/client".out-interceptors=org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.wss4j.common.ConfigurationConstants;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.handler.WSHandlerConstants;

import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import java.util.HashMap;
import java.util.Map;

@Path("/")
public class ClientResource {

    @Inject
    Test testClient;

    @GET
    public String hello() {
        return testClient.test("hello");
    }

    @Produces
    public WSS4JOutInterceptor getWSS4JOutInterceptor() {
        Map<String,Object> outProps = new HashMap<String,Object>();
        outProps.put(ConfigurationConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        outProps.put(ConfigurationConstants.PASSWORD_TYPE, WSConstants.PASSWORD_DIGEST);
        outProps.put(ConfigurationConstants.PW_CALLBACK_CLASS, UsernameTokenPasswordClientCallback.class.getName());
        outProps.put(ConfigurationConstants.USER, "joe");
        return new WSS4JOutInterceptor(outProps);
    }
}
import org.apache.wss4j.common.ext.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.IOException;

public class UsernameTokenPasswordClientCallback implements CallbackHandler {

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            WSPasswordCallback wpc = (WSPasswordCallback) callback;
            if (wpc.getIdentifier().equals("joe")) {
                wpc.setPassword("wss4j");
                return;
            }
        }
    }
}

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024

great. I think we will need to add unit test for that.

from quarkus-cxf.

shumonsharif avatar shumonsharif commented on June 2, 2024

Hey @dufoli my suggestion would be that we just document this for now, because we're using interceptor features that the extension already provides to integrate with WSS4J ... there were no extension code changes required to support CXF security, it all just works out of the box. What do you think?

from quarkus-cxf.

dufoli avatar dufoli commented on June 2, 2024

Now that documentation is out, we can close it

from quarkus-cxf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.