简体   繁体   中英

Using a fluent security custom policy with castle windsor

I have Fluent Security setup (and working) to secure my controller actions and have used castle windsor to resolve everything (pretty much as shown in the castlewindsor-fluentsecurity project you can download). What I want to do now is create a custom policy that runs a query on our Active Directory. I've created a test policy that implements ISecurityPolicy but it doesn't have a default constructor since I need to inject the interface to access the AD. Here's the policy:-

 public class TestPolicy : ISecurityPolicy
{
    private readonly IQueryHandler<GetUserQuery, User> userQueryHandler;

    public TestPolicy(IQueryHandler<GetUserQuery, User> userQueryHandler)
    {
        this.userQueryHandler = userQueryHandler;
    }
    public PolicyResult Enforce(ISecurityContext context)
    {
        var adUser = userQueryHandler.Handle(new GetUserQuery());

        if (adUser.HasManager())
        {
            return PolicyResult.CreateSuccessResult(this);
        }
        return PolicyResult.CreateFailureResult(this, "Access denied!");
    }
}

The IQueryHandler is used elsewhere and resolves correctly. I added the policy to the controller:-

configuration.For<Areas.People.Controllers.InfoController>().AddPolicy<TestPolicy>();

but when called this fails with:- TestPolicy could not be loaded! Make sure the policy has an empty constructor or is registered in your IoC-container. Now looking through the documentation it seems I'm missing the step where I tell the SecurityConfigurator that I'm using an IoC. The docs don't show a specific Castle Windsor example but I 'came up with':-

SecurityConfigurator.Configure(configuration => configuration.ResolveServicesUsing(type => _container.ResolveAll(type).Cast<object>()));

Well it doesn't work and it seems strange that the SecurityConfigurator requires the Castle Windsor container when by the time SecurityConfig.RegisterSecurityRules() is called I've pretty much finished with Castle Windsor. Can anyone show me how I should be configuring Fluent Security in this instance?

OK - well I finally got it working:
In the SecurityConfigurator I have
configuration.ResolveServicesUsing( type => container.ResolveAll(type).Cast<object>(), type => container.Kernel.HasComponent(type) ? container.Resolve(type) : null );
I changed the Controller policy to add an interface, rather than an actual policy:

configuration.For<Areas.People.Controllers.InfoController>().AddPolicy<ITestPolicy>();


The interface implements ISecurityPolicy:

    public interface ITestPolicy : ISecurityPolicy
{
}


And then the Interface can be wired up with Castle:

container.Register(Component.For<ITestPolicy>().ImplementedBy<TestPolicy>());


I think the custom policy examples at Fluent Docs could do with saying that you need to use a policy interface so that it can be resolved by CastleWindsor... (Unless I'm using it wrong!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM