Skip to content
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

Add ManagementAPI factory for initialization #179

Closed
psxvoid opened this issue Apr 4, 2018 · 20 comments
Closed

Add ManagementAPI factory for initialization #179

psxvoid opened this issue Apr 4, 2018 · 20 comments
Labels
enhancement An enhancement or improvement to the SDK that could not be otherwise categorized as a new feature

Comments

@psxvoid
Copy link

psxvoid commented Apr 4, 2018

In order to use ManagementApiClient we have to initialize it (from documentation):

var client = new ManagementApiClient("your token", new Uri("https://YOUR_AUTH0_DOMAIN/api/v2"));

It would be nice to create a wrapper interface (e.g. IManagementAPIClientFactory) which should accept an IConfigurationProvider for initializing the client. Then we would have to inject IManagementAPIClientFactory into any service that uses IManagementAPIClient and get the client via `IManagementAPIFactory.GetClient()'.

Or it is even possible to create a separate project\add an extension for AspNetCore in order to automatically register such service (e.g.: serviceCollection.AddAuth0ManagementAPI()).

It should help reduce the amount of repetitive code we have to write (applicable to auth0.net 5.x)

@jerriep jerriep self-assigned this Apr 4, 2018
@jerriep
Copy link
Contributor

jerriep commented Apr 4, 2018

It appears you are using ASP.NET Core, right?

If so, I am not sure why you need a factory. Using the built-in DI framework you can specify a delegate which instructs the DI framework how to construct a new instance of IManagementApiClient.

So, in your ConfigureServices method, do something like the following:

services.AddScoped<IManagementApiClient>(provider => new ManagementApiClient("your token", "YOUR_AUTH0_DOMAIN"));

Or, if you need some values from configuration, ensure you inject IConfiguration into your Startup class, and then use that inside the delegate, e.g.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IManagementApiClient>(provider => new ManagementApiClient(Configuration["Auth0:Token"], Configuration["Auth0:Domain"]));

        // register the rest of your services
    }
}

Would that not work for you?

@psxvoid
Copy link
Author

psxvoid commented Apr 5, 2018

Yep, I am using AspNetCore.

The issue with this approach: Configuration["Auth0:Token"] cannot be retrieved via the configuration easily - the token expires via 24h (accordingly with the documentation: Management API: Tokens (Auto)).

So, we have to provide a service which should automatically provide a valid token to the ManagementApiClient.

It's still possible to register a service that will auto-refresh the token and use it in a custom provider (in the same manner as was shown in the answer above). But it's very inconvenient - we have a micro-services architecture and we should provide such service to each of them.

@jerriep
Copy link
Contributor

jerriep commented Apr 5, 2018

Sorry, at this moment there are no plans to support the sort of integration you require with ASP.NET Core. You will have to write something yourself to generate and cache the Management API tokens, and use it in the factory delegate for DI, or generate a new token once it has expired.

That being said, it might be worth your while to reach out to the Auth0 support team. They may have come across this in their interactions with other customers, and can perhaps have some sample code already in place to speed you along. (I am not a full-time Auth0 employee, so I cannot help you with that part of it)

@robertmclaws
Copy link
Contributor

@jerriep this is the second situation in a couple days where I've seen feedback about how Auth0's library is too complicated and your response has been lackluster. Auth0 was built on being ridiculously simple for developers, and the .NET libraries they used to ship were as comprehensive as possible. I know this because I helped fill in the gaps at the very beginning so it could Just Work.

If everyone has to register the Cookie Provider, Auth0 should do it for them. If everyone has to generate and cache Management API tokens, Auth0 should do it for them. Why make people write their own (potentially incorrect) implementations of the same code over and over again?

I mean, Microsoft just had to ship a factory for HttpClients, it is not unreasonable to assume the factory pattern would be useful to future customers here as well.

@jerriep
Copy link
Contributor

jerriep commented Apr 8, 2018

@robertmclaws What you proposed with us registering the cookie middleware on behalf of the user goes completely against what every other piece of middleware out there does. Doing things which are not standard will cause more support issues, not less.

You are also conveniently leaving out the fact that I particularly requested input from @nicosabena on that one because from a support point of view, he can better indicate whether this will cause more or less issues.

Furthermore, the decision was made a long time ago internally at Auth0 (when we were doing the first bits of ASP.NET Core integration) to not add too many unnecessary wrappers, but to stick to the standard, platform-provided middleware as far as possible. Once again, your request is going against this.

This particular issue raised here is the first of its kind AFAIK. We cannot accept every single suggestion every customer makes. If more customers have this particular issue, it is something which can be investigated. That still does not change the fact that at this moment there are no plans to support the sort of integration they require with ASP.NET Core.

If you think you or other customers are being treated unfairly by me, then please raise the issue with Auth0 management. Actually, let me do that for you and CC @woloski @aaguiarz and @cocojoe in here. (For the record for the three of you, the issue Robert believes he was treated "lackluster" by me is this one)

For your particular issue, I will tell them the same. I think it is a bad decision which can create more support issues.

@nicosabena
Copy link
Member

Hi guys. Personally, I have to agree with Jerrie on this one. The concern of object creation shouldn't be part of the library itself, as this is best done by either simple boilerplate code or inversion of control/dependency injection frameworks. It would be a bad design decision to force one type of usage to users.
The factory interface itself might even be replaceable with a Func<T> on some frameworks, and the implementation will also vary depending on particular design decisions.
I agree that we could help by providing some additional samples, showing how to solve certain scenarios (like caching a token until it expires), but it would be outside the scope of this library to try to solve every possible scenario that is related more to app infrastructure than to authentication.

@psxvoid
Copy link
Author

psxvoid commented Apr 10, 2018

Hi,

It's still possible to provide additional types of NuGet packages that can be supported by a community. The good example of it - AutoMapper library for AspNetCore:

AutoMapper.Extensions.Microsoft.DependencyInjection

It's not another AutoMapper implementation. It doesn't break any AutoMappers "philosophies". It just another "boilerplait" for AspNetCore. We are not forced to use it. But it has 812,990 Total Downloads (valid for 10.04.2018) on the NuGet. And it should say something to us.

@jerriep
Copy link
Contributor

jerriep commented Apr 10, 2018

@psxvoid Many of Auth0's stuff is in fact "community supported", but hardly any contributions come from the community. Ultimately it comes down Auth0 employees.

It is nice to mention packages like AutoMapper.Extensions.Microsoft.DependencyInjection, but the Auth0 Management API SDK is no AutoMapper. It, in itself, does not even get those sort of number of downloads you are mentioning, so to point at that and say "look, here's proof!" is not accurate.

Yours is the first request I have ever received for something like this. Surely you cannot reasonably expect a vendor to jump at every single request from every single developer?

BTW, I do not think your suggestion will not be helpful. I think it will be very helpful in your situation, but so far I have not seen much evidence that this is a wide-spread request.

Also, your specific request is for ASP.NET Core, but what about all the other platforms where developers use the Auth0 .NET SDK? What about OWIN apps? UWP apps? Xamarin apps? WinForms apps? Should we go and implement something which makes generating and cacheing the token easier on all those platforms too? And then we've only covered .NET. What about Node? Java? Ruby? All the hundreds of frameworks across all the popular programming languages?

In an ideal world the resources would be available to implement all those, but please understand that right now this is not a possibility. Over time some of this may or may not happen, but this will not address your immediate problem.

@nicosabena made a suggestion to me, and there is something we can perhaps do to make things a little bit easier, but it will still require work on your side, unfortunately. And it will likely not happen this week.

So, for now, my original suggestion stands to reach out to Auth0 support and see whether they have come across this before and can maybe help you with a code sample. Have you reached out to them?

@psxvoid
Copy link
Author

psxvoid commented Apr 10, 2018

@jerriep Yep, we should consider the business value of the feature and further implications it introduces.

Regarding your question about reaching out Auth0 support - we've already implemented this type of a factory - it requests the token and initializes the client. And we pushed it to a private NuGet feed in order to share between microservices. But it's not very convenient to support it on our own - we are not specialized in an authentication and\or a security as Auth0 does.

There are no any guidance from Auth0 and answers on questions such as "why we should cache the token for ManagementAPI" and "how to do it in the way it was supposed to be done" (e.g.: why just don't get the new token each time we initialize ManagementAPI).

So, the main reason on opening the issue not in "requesting" the feature but in sharing the knowledge and experience in order to help (may be) to make great product a little bit better.

@jerriep
Copy link
Contributor

jerriep commented Apr 10, 2018

@psxvoid Thanks for the feedback, I will notify the documentation team of your concerns and see whether better guidance can be provided for that

@jerriep jerriep added the enhancement An enhancement or improvement to the SDK that could not be otherwise categorized as a new feature label Apr 17, 2018
@finsterdexter
Copy link

As someone who had to figure this out myself, and write the token factory myself, this is a sorely needed feature and one which would increase the value of these client libraries immensely.

@ckittel
Copy link

ckittel commented Aug 29, 2018

Does anyone here have a token refresh factory they would feel comfortable sharing as a starting point for one of our new implementations? I'd like to compare notes.

@junaidahmed92
Copy link

junaidahmed92 commented Sep 6, 2018

Is there anyway to create a separate class that will fetch access_token via AuthenticationApi and use that token in initialization of ManagementApiClient? Something like
new ManagementApiClient(Token.GetAccessToken(), "Domain" ); ?

@finsterdexter
Copy link

@ckittel Here's the token factory I use:

https://gist.github.com/finsterdexter/5e74b3bd4af8052ae6da4850af5e2124

I add that class to DI in startup via AddSingleton. It will hold onto a token for the lifetime of the class, and only fetch a new one if the service is restarted or if the token expires. This factory is then used as a dependency on controllers that need to interact with the Management API.

@adriangodong
Copy link

Chiming in, I have the same problem.

I'll write a Nuget package to handle this, but as a rough requirement:

  • Server-side factory of IManagementApiClient
  • Can be used in async methods
  • Can be used in sync methods
  • DI-friendly
  • Automatic token rotation/refresh

@adriangodong
Copy link

Here you go
https://www.nuget.org/packages/FriendlySpork

@damieng
Copy link
Contributor

damieng commented Apr 2, 2019

As the Auth0.Net library can be used across a variety of the .NET standards and platforms there are no immediate plans to add this functionality.

As customers move to .NET core and away from .NET desktop we will re-evaluate this decision. For now it is relatively simple to work around as the various suggestions have helpfully illustrated.

@damieng damieng closed this as completed Apr 2, 2019
@Hawxy
Copy link
Contributor

Hawxy commented Jan 12, 2021

For people that stumble upon this thread and are using .NET Core 3.1 or 5.0, I released a new package that deals with the Auth0.NET Clients and token caching/renewal in a more idiomatic way: https://github.com/Hawxy/Auth0Net.DependencyInjection

It's compatible with both ASP.NET Core and .NET Generic Host (console/service) scenarios.

@frederikprijck
Copy link
Member

frederikprijck commented Jan 12, 2021

Thank you for sharing this @Hawxy, this looks very interesting. We are making plans to look at the current state of our .NET SDKs and how we want to move forward, so I am interested to see if there is more like that kind of things we can bring to the table.

I do think there is some confusion around these kind of things, such as people might think they need that package to implement OAuth in an ASP.NET (Core) WebAPI or MVC project, but that is not the case. It looks like this is mostly for Machine2Machine communication, including (but not limited to) the Management API.

Anyway, thanks for creating this and sharing it with the people here! I am definetly a fan of supporting DI OOTB instead of manually including the boilerplate in every project. However, I also think this should not be part of the SDK itself (or atleast not the same Nuget package) as, as was mentioned earlier, the Management SDK here is used in all kind of projects (Xamarin, WPF, Winforms, ...) which do or do not benefit from those DI setups.

That said, happy to take these kind of things into consideration, while also respecting your effort that you put into this for the community.

@Hawxy
Copy link
Contributor

Hawxy commented Jan 12, 2021

I do think there is some confusion around these kind of things, such as people might think they need that package to implement OAuth in an ASP.NET (Core) WebAPI or MVC project, but that is not the case.

I did consider that possibility, as one of your competitors offers a package in that space that people might look for on the Auth0 side. I attempted to make the docs as clear as possible and didn't include any keywords that the would cause the user to accidentally stumble upon the repo when searching for OAuth stuff. I can add an explicit section regarding this if it becomes a problem.

However, I also think this should not be part of the SDK itself (or atleast not the same Nuget package) as, as was mentioned earlier, the Management SDK here is used in all kind of projects (Xamarin, WPF, Winforms, ...) which do or do not benefit from those DI setups.

Sure, most of the time this type of package is separate so I wouldn't expect it to be bundled with the SDK itself.

It looks like this is mostly for Machine2Machine communication, including (but not limited to) the Management API.

Kinda, it does configuration and registration of the Authentication & Management clients for normal usage and just adds extensions to make MtM scenarios between internal services as easy as possible. Due to the internal handlers being managed by the IHttpClientFactory implementation, you also get OOTB logging as an added bonus:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An enhancement or improvement to the SDK that could not be otherwise categorized as a new feature
Projects
None yet
Development

No branches or pull requests