Skip to content

DI in AuthorizationRequirement #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Brandon2255p opened this issue Feb 24, 2020 · 15 comments
Closed

DI in AuthorizationRequirement #73

Brandon2255p opened this issue Feb 24, 2020 · 15 comments
Labels
question Further information is requested

Comments

@Brandon2255p
Copy link

I am struggling to figure out how to inject into an AuthorizationRequirement
I am trying to inject IClient in the following code example.

When setting up the policy, I have to use a constructor which means I am not using DI

                _.AddPolicy(GraphQLPolicyNames.HomeAccess, policy =>
                {
                    policy.AddRequirement(new BasicAccessRequirement());
                    policy.AddRequirement(new HomeAccessRequirement());
                });
    public class HomeAccessRequirement : IAuthorizationRequirement
    {
        private readonly IClient client;
        public HomeAccessRequirement(IClient client)
        {
            this.client = client;
        }
        public Task Authorize(AuthorizationContext context)
        {
            if (AuthorizationHelpers.IsAdminOrSuperAdmin(context.User))
            {
                return Task.FromResult(0);
            }
            var hasId = context.InputVariables.ContainsKey("Id");
            if (hasId)
            {
                dynamic id;
                context.InputVariables.TryGetValue("Id", out id);
                var home = client.GetData(id);
            }

            return Task.FromResult(0);
        }
    }

How can I achieve DI to inject the IClient which is needed for authorization

@sungam3r
Copy link
Member

Unfortunately there is no such possibility.

@Ekkeir
Copy link

Ekkeir commented Feb 24, 2020

Instead of making IAuthorizationRequirement DI-dependent, use in as simple class to hold requirement-related information.
And then create a DI-dependent handler (HomeAccessHandler : AuthorizationHandler<HomeAccessRequirement>) to process the requirement.
This should help you.
P.S. Note the "Handler registration" section.

@sungam3r
Copy link
Member

This is core auth package, for ASP.NET Core other one exists.

@Ekkeir
Copy link

Ekkeir commented Mar 3, 2020

@sungam3r my bad, missed repo name.

@sungam3r
Copy link
Member

@Brandon2255p how about that?

  services.AddGraphQLAuth((_, s) =>
  {
                _.AddPolicy(GraphQLPolicyNames.HomeAccess, policy =>
                {
                    policy.AddRequirement(s.GetRequiredService<BasicAccessRequirement>());
                    policy.AddRequirement(s.GetRequiredService<HomeAccessRequirement>());
                });
  };

You should of cource configure your requirements in DI-container.

@sungam3r sungam3r added needs confirmation The problem is most likely resolved and requires verification by the author question Further information is requested labels May 19, 2020
@sungam3r
Copy link
Member

Closed due to lack of feedback.

@sungam3r sungam3r removed the needs confirmation The problem is most likely resolved and requires verification by the author label Oct 29, 2020
@mmmikeal
Copy link

i tried your solution @sungam3r for a similar issue i'm having but i get System.InvalidOperationException: 'No service for type 'CoreAPI.HomeAccessRequirement' has been registered.'

@mmmikeal
Copy link

mmmikeal commented May 12, 2021

services.AddSingleton<IAuthorizationRequirement>(x => new HomeAccessRequirement(x.GetRequiredService<IClient>()) );

        `services.AddGraphQLAuth((_, s) =>
        {
            _.AddPolicy("UserRolePolicy", p => p.AddRequirement(s.GetRequiredService<HomeAccessRequirement>()));
        });`

the above did not work, I am relatively new to C# is my error glaringly obvious?

@mmmikeal
Copy link

I see how to do it via what @Ekkeir is saying using handlers in Asp.net core but i cannot find an example or how to create a DI handler class for core auth @sungam3r

@joemcbride
Copy link
Member

joemcbride commented May 14, 2021

AddGraphQLAuth is not a part of this project (maybe it is in the server project?), but for using DI it should look closer to this:

services.AddSingleton<HomeAccessRequirement>();


services.AddGraphQLAuth((_, s) =>
{
    _.AddPolicy("UserRolePolicy", p => p.AddRequirement(s.GetRequiredService<HomeAccessRequirement>()));
});

If you register HomeAccessRequirement as IAuthorizationRequirement, then DI does not have a registration of HomeAccessRequirement, only IAuthorizationRequirement.

Also just noticed that you may be referencing #54 (comment) for that extension.

@mmmikeal
Copy link

thanks joe, not exactly what i was looking for as i have another service that needs to be injected into HomeAccessRequirement and the above did not work. I am attempting the other route which is to make my injected service available to httpcontextaccessor

@joemcbride
Copy link
Member

If you have another service that needs to be injected, that other service just needs to be also registered with DI. If it doesn't work this way, then it won't work the other way either.

@joemcbride
Copy link
Member

services.AddTransient<HomeAccessRequirement>();
services.AddTransient<IClient, MyClient>();


public class HomeAccessRequirement : IAuthorizationRequirement
{
    private readonly IClient client;
    public HomeAccessRequirement(IClient client)
    {
        this.client = client;
    }
    public Task Authorize(AuthorizationContext context)
    {
        ...
    }
}

services.AddGraphQLAuth((_, s) =>
{
    _.AddPolicy("UserRolePolicy", p => p.AddRequirement(s.GetRequiredService<HomeAccessRequirement>()));
});

@mmmikeal
Copy link

thanks! @joemcbride i have been going in circles over and over with this. Seems like I need to look into why I can't dependency inject this...

@joemcbride
Copy link
Member

@mmmikeal Here's a full working example that uses injection in a IAuthorizationRequirement.

graphql-dotnet/examples#66

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants