Custom CXF Conduit - apache

I want to custom a CXF Conduit in my application, but i don't know how to implement it and add it in client code.
I want to implement it as custom destination that i have done as follows:
Step1: i create a MyDestinationFactory class
class MyDestinationFactory extends AbstractTransportFactory implements DestinationFactory {
....
}
Step 2: i add this Destination in the server code:
JaxWsServerFactoryBean serverFactory;
MyDestinationFactory destFac = new MyDestinationFactory();
serverFactory.setDestinationFactory(destFac);
It works with the custom destination.
=> How to customize a CXF Conduit ? I read here http://cxf.apache.org/docs/custom-transport.html but i don't use it.

Bus bus = BusFactory.getThreadDefaultBus();
MyTransportFactory customTransport = new MyTransportFactory();
ConduitInitiatorManager extension = bus.getExtension(ConduitInitiatorManager.class);
extension.registerConduitInitiator(MyTransportFactory.TRANSPORT_ID, customTransport);

Related

Generate Link To Spring Data Rest Controller

I created a REST API with Spring Data Rest that forks fine. It must be possible to clone Projects via the API, so I added a custom #RestController to implement that via POST /projects/{id}/clone.
#RestController
#RequestMapping(value = "/projects", produces = "application/hal+json")
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
public class ProjectCloneController {
private final ProjectRepo projectRepo;
#PostMapping("/{id}/clone")
public EntityModel<Project> clone(#PathVariable String id) {
Optional<Project> origOpt = projectRepo.findById(id);
Project original = origOpt.get();
Project clone = createClone(original);
EntityModel<Project> result = EntityModel.of(clone);
result.add(linkTo(ProjectRepo.class).slash(clone.getId()).withSelfRel());
return result;
}
I am stuck at the point where I need to add a Link to the EntityModel that points to an endpoint provided by Spring Data Rest. It will need to support a different base path, and act correctly to X headers as well.
Unfortunately, the line above (linkTo and slash) just generates http://localhost:8080/636f4aaac9143f1da03bac0e which misses the name of the resource.
Check org.springframework.data.rest.webmvc.support.RepositoryEntityLinks.linkFor

Dependency Injection Access While Configuring Service Registrations in asp.net Core (3+)

I have cases, where I want to configure services based on objects which are registered in the dependency injection container.
For example I have the following registration for WS Federation:
authenticationBuilder.AddWsFederation((options) =>{
options.MetadataAddress = "...";
options.Wtrealm = "...";
options.[...]=...
});
My goal in the above case is to use a configuration object, which is available via the DI container to configure the WsFederation-middleware.
It looks to me that IPostConfigureOptions<> is the way to go, but until now, I have not found a way to accomplish this.
How can this be done, or is it not possible?
See https://andrewlock.net/simplifying-dependency-injection-for-iconfigureoptions-with-the-configureoptions-helper/ for the I(Post)ConfigureOptions<T> way, but I find that way too cumbersome.
I generally use this pattern:
// Get my custom config section
var fooSettingsSection = configuration.GetSection("Foo");
// Parse it to my custom section's settings class
var fooSettings = fooSettingsSection.Get<FooSettings>()
?? throw new ArgumentException("Foo not configured");
// Register it for services who ask for an IOptions<FooSettings>
services.Configure<FooSettings>(fooSettings);
// Use the settings instance
services.AddSomeOtherService(options => {
ServiceFoo = fooSettings.ServiceFoo;
})
A little more explicit, but you have all your configuration and DI code in one place.
Of course this bypasses the I(Post)ConfigureOptions<T> entirely, so if there's other code that uses those interfaces to modify the FooSettings afterwards, my code won't notice it as it's reading directly from the configuration file. Given I control FooSettings and its users, that's no problem for me.
This should be the approach if you do want to use that interface:
First, register your custom config section that you want to pull the settings from:
var fooSettingsSection = configuration.GetSection("Foo");
services.Configure<FooSettings>(fooSettingsSection);
Then, create an options configurer:
public class ConfigureWSFedFromFooSettingsOptions
: IPostConfigureOptions<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions>
{
private readonly FooSettings _fooSettings;
public ConfigureWSFedFromFooSettingsOptions(IOptions<FooSettings> fooSettings)
{
_fooSettings = fooSettings.Value;
}
public void Configure(WsFederationOptions options)
{
options.MetadataAddress = _fooSettings.WsFedMetadataAddress;
options.Wtrealm = _fooSettings.WsFedWtRealm;
}
}
And finally link the stuff together:
services.AddTransient<IPostConfigureOptions<WsFederationOptions>, ConfigureWSFedFromFooSettingsOptions>();
The configurer will get your IOptions<FooSettings> injected, instantiated from the appsettings, and then be used to further configure the WsFederationOptions.

How to inject the .NET Core [IServiceProvider] itself into services?

How to inject the [IServiceProvider] interface into custom services? I mean after the [Startup] class finishes construction of [IServiceProvider] from [IServiceCollection] set of bindings. How do I then subscribe to the newly created [IServiceProvider] built after method [ConfigureServices] invoked?
If you want to call your service inside startup you should create a scope
// initial database
using (var scope = app.ApplicationServices.CreateScope())
{
var initDatabase = new YourClass(scope.ServiceProvider.GetService<YourServiceInterface>());
}
But Accessing to IServiceProvider in other services don't make sense. If you describe more You could get the right answer.

How to add http header into WCF channel

I have MVC client that invokes a WCF service. The MVC client needs to pass one custom header in httprequest. The MVC client is also using Unity for DI.
I have already gone through SO POST and others links but they are all suggesting to use message inspector and custom behavior(which might be the correct way) but i'm looking for quick and dirty way because this will be temporary solution.
// Unity type Registration
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IDocumentManagementChannel>(new PerRequestLifetimeManager(),
new InjectionFactory(f=> CreateDocumentManagementChannel()));
}
private static IDocumentManagementChannel CreateDocumentManagementChannel()
{
var factory = new ChannelFactory<IDocumentManagementChannel>("BasicHttpEndPoint");
var channel = factory.CreateChannel();
// How do i add HttpHeaders into channel here?
return channel
}
In the code above How do i add custom header after i create a channel?
1- Below code should send the soap header from MVC
string userName = Thread.CurrentPrincipal.Identity.Name;
MessageHeader<string> header = new MessageHeader<string>(userName);
OperationContext.Current.OutgoingMessageHeaders.Add(
header.GetUntypedHeader("String", "System"));
2- And this code should read it on WCF
string loginName = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("String", "System");
3- As for the channel, i recommend you create your custom System.ServiceModel.ClientBase as follows:
public abstract class UserClientBase<T> : ClientBase<T> where T : class
{
public UserClientBase()
{
string userName = Thread.CurrentPrincipal.Identity.Name;
MessageHeader<string> header = new MessageHeader<string>(userName);
OperationContext.Current.OutgoingMessageHeaders.Add(
header.GetUntypedHeader("String", "System"));
}
}
4- Create a custom client class that inherits from UserClientBase and use the base channel internally to call your IxxService which is the T here.

WCF - Passing CurrentPrincipal in the Header

I have a WCF service that needs to know the Principal of the calling user.
In the constructor of the service I have:
Principal = OperationContext.Current.IncomingMessageHeaders.GetHeader<MyPrincipal>("myPrincipal", "ns");
and in the calling code I have something like:
using (var factory = new ChannelFactory<IMyService>(localBinding, endpoint))
{
var proxy = factory.CreateChannel();
using (var scope = new OperationContextScope((IContextChannel)proxy))
{
var customHeader = MessageHeader.CreateHeader("myPrincipal", "ns", Thread.CurrentPrincipal);
OperationContext.Current.OutgoingMessageHeaders.Add(customHeader);
newList = proxy.CreateList();
}
}
This all works fine.
My question is, how can I avoid having to wrap all proxy method calls in the using (var scope...{ [create header and add to OperationContext]?
Could I create a custom ChannelFactory that will handle adding the myPrincipal header to the operation context? Something like that would save a whole load of copy/paste which I'd rather not do but I'm not sure how to achieve it:)
Thanks
The correct time to set a WCF principal is via IAuthorizationPolicy, by specifying a custom policy in configuration. This covered in full here. If you try setting the principal at other points (an inspector, perhaps) it can get reset by the system.