I am trying to get the HTTP session in my JAX-RS service. Usually I use in a JSF managed bean:
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
But this time I need it in a JAX-RS service method. So the current instance of FacesContext is null. Is there another way to get it? I tried with contextual injection of HttpServletRequest, but I couldn't make it work.
Related
I want to be able to reload my Swagger configuration without redeploying my service.
So I'm trying to use an IOptionsSnapshot directly in the Startup.ConfigureServices() method :
public void ConfigureServices(IServiceCollection services)
{
services.Configure<SwaggerSettings>(Configuration.GetSection("BaseTemplate:Swagger"));
var swaggerSettings = new IOptionsSnapshot<SwaggerSettings>(); //get an instance
//Configure Swagger
}
I guess that the Startup.ConfigureServices() is called only once when the application is starting ?
Is there any workaround to use and reload a IOptionsSnapshot in the the Startup.ConfigureServices() ?
Yes, the Startup.ConfigureServices() is called only once when the application is starting.
Is there any workaround to use and reload a IOptionsSnapshot in the
the Startup.ConfigureServices() ?
Do you mean you want to create the service instance each time they're requested from the service container or once per client request (connection)? If that is the case, you could try to use AddTransient method or AddScoped method to register the service. Code like this:
services.AddScoped<IMyDependency, MyDependency>();
More detailed information, see:
Transient
Transient lifetime services are created each time they're requested from the service container. This lifetime works best for lightweight, stateless services. Register transient services with AddTransient.
In apps that process requests, transient services are disposed at the end of the request.
Scoped
For web applications, a scoped lifetime indicates that services are created once per client request (connection). Register scoped services with AddScoped.
In apps that process requests, scoped services are disposed at the end of the request.
Reference: Dependency injection in ASP.NET Core and Service lifetimes.
I need to get a scoped service injected into an IOperationFilter but it won't work by c-tor:
class MyOperationFilter: IOperationFilter
{
public MyOperationFilter(IMyService service) { }
}
it will give an error:
System.InvalidOperationException: 'Cannot resolve scoped service from root provider site:
this is expected because only a transient service can get injected, not a scoped one.
So how can I get a scoped service injected in an IOperationFilter?
There's no example in the documentation or anywhere else. The examples I've seen use transient not scoped services.
In ASP.NET Core, a scoped service can get injected into the middleware by adding the service as parameter to the Invoke method. But Swashbuckle doesn't seem to have an extension to allow this.
Looking at the source code, I cannot see Swashbuckle to have a way to do this.
You can go with two methods:
Inject IHttpContextAccessor if we are talking about scoped service for user request, and then request the scoped service to request.
_httpContextAccessor.HttpContext.RequestServices.GetRequiredService<ICurrentIdentity>();
2.Inject IServiceProvider and create a new scope, and then request your scoped service, but it will not have references to the current request.
serviceProvider.CreateScope().ServiceProvider.GetService<MyScopedService>()
I'm seeing some strange behaviour when using stateless token-based authentication on a rest API written using Spring Boot.
The client includes a JWT token with each request, and a custom filter I've written that extends GenericFilterBean adds an Authentication object based on the claims in the token to the security context using the following :
SecurityContextHolder.getContext().setAuthentication(authentication);
And clears the context after processing the request by doing :
SecurityContextHolder.getContext().setAuthentication(null);
However when the simple app I've developed performs a range of operations, I sometimes see that the security context isn't being set correctly - sometimes it's null for a request that has supplied a token. The filter is being called correctly, setAuthencation() is also being called, but the request fails authentication, and throws a 403 denied.
If I explicitly turn off any http Session management by setting the session creation policy to STATELESS, this behaviour stops.
Any ideas what could be happening here? Is the security context being shared between threads dealing with requests in some way?
It seems that the context can be shared, according the official documentation here :
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html
In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another. Alternatively you can create a new instance just at the point where you temporarily change the context. The method SecurityContextHolder.createEmptyContext() always returns a new context instance.
I have a solution with an MVC application and a Web API. They're in separate projects and domains (using CORS). I built it as a Web API to have the flexibility for adding consumers but currently my MVC application is the only consumer. As such I'm debating whether to use HttpClient inside my MVC Controller or directly instantiate the ApiController.
In either case, I'm using dependency injection (Autofac) so I'd also like to know how to configure that because neither HttpClient or ApiController have any kind of interface that I can inject through constructor parameters like I usually do so I'm not sure how to handle this.
What should the lifetime scopes be for the injected instance? HttpClient should probably be Singleton since it's not encouraged to dispose it after each request.
NOTE By calls to the API return large datasets used to populate charts which is why I'm leaning a bit away from HttpClient as I feel I will incur additional overhead using Http. Is it an antipattern to directly instantiate the ApiController?
Thanks
You could always do this
var httpClient = new HttpClient(new HttpServer(GlobalConfiguration.Configuration));
This allows you to continue using the HttpClient but the requests get passed directly to the WebApi server without ever making a network request. This way if you later decide to separate out your WebAPI your client code doesn't change
So I already have a working implementation of StructureMap with the WCF service (including custom instance provider, behaviors, etc.)
When I try to have an object that is instantiated only once per user request, I use the InstanceScope.HttpContext and it throws because the context is null.
Do anyone have a proper way of doing that?
On the server-side of the WCF service? By default, WCF has nothing to do with ASP.NET and thus all your HttpContext etc. aren't there.
By default, your WCF services will be called on a "per-call" basis, e.g. each request gets a brand-new, separate, totally isolated instance of your service class. Why not just put those things into the service class as internal fields??
Or you might want to check out this blog post on how to abstract request state and providing sample implementations for ASP.NET (using HttpContext.Items) and WCF.