Asp.Net Core 2.0 - Custom Middleware dependency injection - jwt

I have written custom middleware for JWT Token generation (based on code from some tutorials for Asp.Net Core 1.1) This middleware uses some dependencies:
DbContext, UserManager, SignInManager
I am upgrading my Asp.Net Core Web API from 1.1 to 2.0 version of ASP.NET.
And after most of the modifications from https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x
I have encountered such an error:
Application startup exception
System.InvalidOperationException: Cannot resolve scoped service 'MyApplicationWebApi.Models.DatabaseContext' from root provider.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, ServiceProvider serviceProvider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.<UseMiddleware>b__0(RequestDelegate next)
at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
My Middleware constructor looks like this:
#region constructor
public JwtProvider(RequestDelegate next,
IOptions<JwtProviderOptions> options,
DatabaseContext dbContext,
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager)
{
_next = next;
_options = options.Value;
// Instantiate through Dependency Injection
_dbContext = dbContext;
_userManager = userManager;
_signInManager = signInManager;
}
#endregion
I have also seen that in new tutorials, books for ASP.NET 2.0 the JWT token generation is usually resolved using some TokenController endpoint rather then custom TokenMiddleware. And I have a question:
Should I migrate from using custom middleware JwtProvider to JwtProviderController ?
Can I inject DbContext, UserManager, SignInManager into custom Middlware? (I have read that into constructor I can only inject singleton DI's services, and into Invoke() I can inject scoped DI's services. Is that true, and are DbContext, UserManager, SignInManager such scoped services.)
In Program.cs I have created some scope using
host.services.CreateScope() maybe I should make something like this in Custom TokenMiddleware?

Related

Persistence unit not injected in webservice

I have an application that was working on Java 6 + Glassfish 3. I am migrating this project to run on Glassfish 5.1 with oracle java 8.
The application builds without problems. During deployment the only jpa/eclipselink related lines are
Info: EclipseLink, version: Eclipse Persistence Services - 2.7.4.v20190115-ad5b7c6b2a
Info: /file:/home/eelke/NetBeansProjects/MplusLicentieService/build/web/WEB-INF/classes/_MplusLicentieServicePU login successful
However when a soap call is performed a NullPointerException is triggered. I have verified with the debugger that the pointer that is null is in fact the persistence unit. Here is the definition of the webservice, the EntitiyManager and one of the methods that failed. Within the method em == null. Left out other statements and variables.
#WebService(serviceName = "LicentieWebService")
public class LicentieWebService {
#PersistenceContext(unitName = "MplusLicentieServicePU")
private EntityManager em;
#Resource
private javax.transaction.UserTransaction utx;
#WebMethod(operationName = "getLicentie2")
public QLicentieAntwoord getLicentie2(
#WebParam(name = "licentieNr") String licentieNr,
#WebParam(name = "filiaalNr") int filiaal,
#WebParam(name = "werkplekNr") int werkplek,
#WebParam(name = "codewoord") String codewoord) {
try {
Licentie lic = em.find(Licentie.class, licentieNr);
...
} catch (ApplicationError ex) {
...
}
}
I also tried redefining the persistence unit in netbeans but this didn't change anything.
Some additional findings
In the same project is also a statelesss EJB which has a function that is called by a timer schedule. Into this EJB a second stateless EJB is injected with #Inject, this works. Into this second EJB the same persistent context is injected as in the webservice. This works, it is injected and queries are executed as expected.
Found some log lines which might be related
Info: JAX-WS RI specific descriptor (WEB-INF/sun-jaxws.xml) is found
in the archive web and hence Enterprise Web Service (109) deployment
is disabled for this archive to avoid duplication of services.

Why isn't JobScope and StepScope available from an MVC thread?

I'm getting Error creating bean with name 'scopedTarget.scopedTarget.processVlsCasesJob': Scope 'job' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton from a job factory class. The factory is where the job and step beans are created in the correct job/step scopes from a bean invoked during main application start up.
#Component("processVlsCasesJobFactory")
public class ProcessVlsCasesJobFactoryImpl
extends BatchJobFactoryAncestorImpl
implements ProcessVlsCasesJobFactory {
...
#Bean
#Scope(scopeName = "job", proxyMode = ScopedProxyMode.INTERFACES)
public ProcessVlsCasesJob processVlsCasesJob() {
return new ProcessVlsCasesJobImpl();
}
...
#Bean
#Scope(scopeName = "step", proxyMode = ScopedProxyMode.INTERFACES)
public ProcessVlsCasesProcessCases processVlsCasesProcessCases() {
return new ProcessVlsCasesProcessCasesImpl();
}
...
// other bean methods creating the step objects
Any attempt to allow Spring to auto-register any bean in the Job/Steps scope fails with that type of error. If those scopes are only available when (I guess) a job is running, how do I "create" the bean in the scope from the thread of the main MVC application running in Tomcat?
Why isn't JobScope and StepScope available from an MVC thread?
Those are custom scopes specific to Spring Batch, they are not part of Spring MVC. You need to specifically register them (or use #EnableBatchProcessing to have them automatically registered)
how do I "create" the bean in the scope from the thread of the main MVC application running in Tomcat?
The main thread (processing the web request) should call a JobLauncher configured with an asynchronous TaskExecutor so that the batch job is executed in a separate thread. Please see the Running Jobs from within a Web Container section which provides more details and a code example of how to do that.
I finally found the answer: #EnableBatchProcessing doesn't work within an MVC application context. In the #Configuration bean I created to configure SB (with DB2) and set up all the SB beans (like jobLauncher), I added:
jobScope = new JobScope();
jobScope.setAutoProxy(Boolean.FALSE);
jobScope.setName(JobScoped.SCOPE_NAME);
((ConfigurableBeanFactory)applicationContext.getAutowireCapableBeanFactory())
.registerScope(JobScoped.SCOPE_NAME, jobScope);
stepScope = new StepScope();
stepScope.setAutoProxy(Boolean.FALSE);
stepScope.setName(StepScoped.SCOPE_NAME);
((ConfigurableBeanFactory)applicationContext.getAutowireCapableBeanFactory())
.registerScope(StepScoped.SCOPE_NAME, stepScope);
Then the two scopes were finally available at run time and the job/step scoped beans were registered at deployment and ran properly.
Was #EBP added as part of Spring Boot? Is it only supposed to be used via a command line tool?

Add-Migration doesn't work after upgrading from Entity Framework Core 1.1 to 2

I upgraded my ASP.NET project from Entity Framework Core 1.1. to Entity Framework Core 2.
I have a class library that targets the .net framework.
I have multiple DBContext in my class library
When I run the command Add-Migration MyMigration I get
More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.
I then run Add-Migration MyMigration -Context MyContext
I then get
Unable to create an object of type 'MyContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
This command use to work
It seems like your upgrade not only Ef,but also Asp.Net CORE. Change your Program.cs file to:
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
// Tools will use this to get application services
public static IWebHost BuildWebHost(string[] args) =>
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}

Handle TimeoutReply message with Rebus configured with autofac

I'm trying out Rebus with the (external) timeoutservice.
The TimeoutService correctly sends back a TimeoutReply.
Then the subscriber logs an error that the TimeoutReplyHandler cannot be invoked.
I'm using Autofac for dependency injection and use the following configuration to register the Handlers:
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(IHandleMessages))))
.AsImplementedInterfaces()
.InstancePerDependency()
.PropertiesAutowired();
var container = builder.Build();
adapter = new AutofacContainerAdapter(container);
The following exception is thrown:
Autofac.Core.DependencyResolutionException: None of the constructors
found with 'Public binding flags' on type
'Rebus.Bus.TimeoutReplyHandler' can be invoked wi th the available
services and parameters: Cannot resolve parameter
'Rebus.Bus.IHandleDeferredMessage handleDeferredMessage ' of
constructor 'Void .ctor(Rebus.Bus.IHandleDeferredMessage)'. at
Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IC
omponentContext context, IEnumerable1 parameters) at
Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1
parameters) at Autofac.Core.Resolving.InstanceLookup.Execute()
at
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifeti
meScope currentOperationScope, IComponentRegistration registration,
IEnumerable` 1 parameters)
The TimeoutReply is handled by the internal class TimeoutReplyHandler, which needs an IHandleDeferredMessage in the ctor.
The internal class DeferredMessageReDispatcher implements IHandleDeferredMessage and needs the IBus in the ctor.
IHandleDeferredMessage is also internal scoped.
How should I configure the autofac container to handle TimeoutReply?
The TimeoutReplyHandler is newed up by Rebus when an incoming TimeoutReply needs to be handled - it is not supposed to be in your container :)
I am guessing that you have some Autofac assembly scanning that happens to come by the TimeoutReplyHandler, thus ending up registering one of Rebus' internal types as if it was your handler.
See if you can remove the registration from the container, possibly by registering only types from your own assemblies.

JTA controlled transactions in JBoss AS7 using EclipseLink, Transaction is required

Environment
Application server: JBoss AS7 (7.1.1 Final)
JPA implementation: EclipseLink (2.4.1)
OS: Windows 7 DB: PostgreSQL 8.4
Update 2, solved
The problem was that i instantiated the AccountService class instead of injecting it using #EJB. After fixing that EntityManager was inected correctly in the service and a transaction was available when doing em.persist(account);
Update
I made a minimal project that shows my problems. Posted to Github:
https://github.com/gotling/jboss-eclipselink-problem
I have two problems that are probably related and due to me not understanding the use of EJB's correct.
I can not get EnityManager to be injected in AccountService.java in persistance JAR, resulting in NullPointerException.
If sending EntityManager in constructor to AccountService no tranasaction is found when doing em.persist.
Project structure
EJB
lib/persistanceunit.jar
web-service.war
Problem
I'm trying to get JBoss to manage transactions in my Java EE service. Problem is that EclipseLink does not seem to pick up the transaction managed by JBoss when trying to persist an entity.
I have followed the guide https://community.jboss.org/wiki/HowToUseEclipseLinkWithAS7 (Alternative 1 and Alternative 2 Step 4) on how to configure JBoss with EclipseLink.
Setup
WAR
Entity manager is injected like this in web-service.war:
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
There is actually a controller class between the class above and the service class, where transformation of the Account object is done, removed it to shorten code.
Persistance Unit
Entity is created like this
AccountService.java in persistanceunit.jar
#Stateless
public class AccountService {
private EntityManager em;
public AccountService(EntityManager em) {
this.em = em;
}
public void create(Account account) {
em.persist(account);
}
}
Stack trace
When calling a WS that should persist the Account entity I get an exception on em.persist(account);
...
Caused by: javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
at org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:692) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.jpa.container.AbstractEntityManager.persist(AbstractEntityManager.java:562) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at se.magos.service.AccountService.create(AccountService.java:50) [persistenceunit-0.0.1-SNAPSHOT.jar:]
Questions
I've enabled Trace logging. Should not id.au.ringerc.as7.eclipselinkpersistence be visible in the log?
Is it somehow possible to get the EntityManager injected inside the service class inside the persistanceunit.jar?
In which JBoss / EclipseLink version should this wor out of the box?
You should annotate the bean with #TransactionManagement(TransactionManagementType.CONTAINER) and the create method with #TransactionAttribute(TransactionAttributeType.REQUIRED).
The first annotation is required in order to let the application server know that transactions are managed by the container, the latter to let the method start a transaction, if there is no current one, as soon as it is invoked.
The problem was that AccountService class was instantiated instead of injected using #EJB annotation. After fixing that EntityManager was injected correctly in the service and a transaction was available when doing em.persist(account);
Before
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
public void notify(Notify notify) {
AccountService accountService = new AccountService(em);
accountService.create(notify);
}
}
After
#WebService(....)
public class NotificationConsumerImpl implements NotificationConsumer {
#PersistenceContext(unitName="foo")
EntityManager em;
#EJB
AccountService accountService;
public void notify(Notify notify) {
accountService.create(notify);
}
}