I've got a problem (of course :)). I have a spring 4.2 application with Spring Security and Spring MVC (with Rest API) and I want to test the effectiveness of the annotation #Secured(ROLE_FOO) present on a REST method.
So I need to install spring-security-test library for this. OK.
Then I follow up some tutorials (or doc) like the official one : http://docs.spring.io/autorepo/docs/spring-security/4.1.0.RC1/reference/htmlsingle/
Here my test code (I'am trying to remove all "uneccessary" code.
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#IntegrationTest
public class UserResourceIntTest {
private MockMvc restUserMockMvc2;
#Autowired
private WebApplicationContext context;
....//Injection, Mocks declarations here
#Before
public void setup() {
this.restUserMockMvc2 = MockMvcBuilders.webAppContextSetup(context).apply(SecurityMockMvcConfigurers.springSecurity()).build();
}
#Test
#WithMockUser(roles="ROLE_VIEWER")
public void testGetUserListe() throws Exception {
//here getAuthentication() returns null !!! why ???
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// restUserMockMvc2.perform(get("/api/users/liste")
// .principal(SecurityContextHolder.getContext().getAuthentication()))
// .accept(MediaType.APPLICATION_JSON))
// .andExpect(status().isForbidden());
// .andExpect(content().contentType("application/json"));
}
Here the method I want to test :
#RestController
#RequestMapping("/api")
public class UserResource {
#RequestMapping(value = "/users/liste", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
#Transactional(readOnly = true)
#Secured({ AuthoritiesConstants.TC_ADMIN })
public ResponseEntity<List<ManagedUserDTO>> getUserListe(Pageable pageable, Principal principal) throws URISyntaxException {
//doSomething...
}
Can you tell me WHY in my test,
SecurityContextHolder.getContext().getAuthentication()
returns null ??
#WithMockUser should authenticate a user automatically (the principal hence)
Thanks
EDIT1 : the setup part of the test (concerning only the security instruction) :
#Inject
private FilterChainProxy springSecurityFilterChain;
#Inject
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
#Before
public void setup() {
....
this.restUserMockMvc2 = MockMvcBuilders
.standaloneSetup(userResource2)
.alwaysDo(print()) .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain))
.setCustomArgumentResolvers(pageableArgumentResolver)
.build();
...
}
EDIT2 : just to be clear on the class definition :
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#TestExecutionListeners(listeners={ServletTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
WithSecurityContextTestExecutionListener.class})
public class UserResourceIntTest {
}
The problem is that Spring Security's WithSecurityContextTestExecutionListener is not being executed because #IntegrationTest is overriding the default TestExecutionListeners.
Most likely you don't need #IntegrationTest with MockMvc, so you should be able to remove it entirely and resolve your issue.
Alternatively you can resolve this by explicitly adding WithSecurityContextTestExecutionListener to your class like:
#TestExecutionListeners(listeners = { WithSecurityContextTestExecutionListener.class, IntegrationTestPropertiesListener.class,
DirtiesContextBeforeModesTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class })
#IntegrationTest
public class UserResourceIntTest {
Related
In the process of setup a bridge between guice and jersey, I ran into one problem.
When trying to create a jersey filter, I was unable to inject guice dependencies into it.
I found a duplicate, however there is no solution to the problem there.
Everything is exactly the same.
The only difference is that I don't get a startup error. The filter works, but my dependencies are null.
Interestingly, Filter and HttpFilter work fine. But it doesn't really work for me.
There's another thing that's interesting. In the resource, which I understand is an HK2 dependency, I can inject guice bean.
#ApplicationPath("/test")
private static class TestApplicationConfig extends ResourceConfig
{
public TestApplicationConfig()
{
register(JacksonFeature.class);
register(AuthFilter.class);
register(new ContainerLifecycleListener()
{
public void onStartup(Container container)
{
ServletContainer servletContainer = (ServletContainer) container;
ServiceLocator serviceLocator = container.getApplicationHandler().getServiceLocator();
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
Injector injector = (Injector) servletContainer
.getServletContext()
.getAttribute(Injector.class.getName());
guiceBridge.bridgeGuiceInjector(injector);
}
public void onReload(Container container)
{
}
public void onShutdown(Container container)
{
}
});
}
}
In ServletModule child.
serve(path).with(ServletContainer.class, ImmutableMap.of(
"javax.ws.rs.Application", TestApplicationConfig.class.getName(),
"jersey.config.server.provider.packages", sb.toString()));
I trying with register(AuthFilter.class) and #Provider
#Singleton
#Provider
public class AuthFilter implements ContainerRequestFilter
{
#Inject
private SomeInjectedService someInjectedService; **// null here**
#Context
private ResourceInfo resourceInfo;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
// some code
}
}
SomeInjectedService I register by guice
bind(SomeInjectedService.class).asEagerSingleton();
Where can I start diagnosing and what can I do?
UPD:
I noticed different behavior when using different annotations.
If I use javax.inject.Inject, I get the following error message.
org.glassfish.hk2.api.MultiException: A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=SomeInjectedService,parent=AuthFilter,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1496814489)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of some.package.AuthFilter errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on some.package.AuthFilter
If com.google.inject.Inject, just null. As I understand this method is not correct.
Considering that javax Inject is trying to inject the service but can't find it. Can we conclude that the bridge is not working correctly? But if it's not working correctly, why can I inject this service into my resource?
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class SomeResource
{
private final SomeInjectedService someInjectedResource;
#Inject // here I use javax annotation and this code working correctry
public SomeResource(SomeInjectedService someInjectedResource)
{
this.someInjectedResource = someInjectedResource;
}
#GET
#Path("/{user}")
public Response returnSomeResponse(#PathParam("user") String user) throws Exception
{
// some code
}
}
I have the following handler I am using trying to attach behavior to any IRequest that also implements IRetryOnConflict.
public class RetryOnConcurrencyRequestHandlerDecorator<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>, IRetryOnConflict
{
private readonly IConcurrencyRetryPolicy retryPolicy;
private readonly IRequestHandler<TRequest, TResponse> innerHandler;
public RetryOnConcurrencyRequestHandlerDecorator(IRequestHandler<TRequest, TResponse> innerHandler, IConcurrencyRetryPolicy retryPolicy)
{
this.innerHandler = innerHandler;
this.retryPolicy = retryPolicy;
}
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken)
{
return retryPolicy.Execute(() => innerHandler.Handle(request, cancellationToken));
}
}
And here is my registration code that runs on startup:
container.Register(typeof(IRequestHandler<,>), typeof(RetryOnConcurrencyRequestHandlerDecorator<,>), setup: Setup.Decorator);
I was looking at some of our log files and I am seeing the following errors:
System.TypeLoadException
GenericArguments[0], 'ReadModel.SaleRegistrations.Queries.GetSaleRegistration', on 'Infrastructure.MediatR.RetryOnConcurrencyRequestHandlerDecorator`2[TRequest,TResponse]' violates the constraint of type parameter 'TRequest'.
system.private.corelib!DomainNeutralILStubClass.IL_STUB_PInvoke
system.private.corelib!System.RuntimeTypeHandle.Instantiate
system.private.corelib!System.RuntimeType.MakeGenericType
dryioc!DryIoc.ReflectionFactory+ClosedGenericFactoryGenerator+<>c__DisplayClass3_0.<GetGeneratedFactory>b__0
dryioc!DryIoc.Throw.IfThrows
dryioc!DryIoc.ReflectionFactory+ClosedGenericFactoryGenerator.GetGeneratedFactory
dryioc!DryIoc.Container+<>c__DisplayClass56_0.<DryIoc.IContainer.GetDecoratorExpressionOrDefault>b__4
dryioc!ImTools.ArrayTools.Map
dryioc!DryIoc.Container.DryIoc.IContainer.GetDecoratorExpressionOrDefault
dryioc!DryIoc.Factory.GetExpressionOrDefault
dryioc!DryIoc.Container.ResolveAndCacheFactoryDelegate
dryioc!DryIoc.Container.DryIoc.IResolver.Resolve
dryioc!DryIoc.Resolver.Resolve
mediatr!MediatR.ServiceFactoryExtensions.GetInstance
mediatr!MediatR.Internal.RequestHandlerBase.GetHandler
mediatr!MediatR.Internal.RequestHandlerWrapperImpl`2+<>c__DisplayClass0_0[System.__Canon,System.__Canon].<Handle>g__Handler|0
mediatr!MediatR.Pipeline.RequestPreProcessorBehavior`2+<Handle>d__2[System.__Canon,System.__Canon].MoveNext
System.Private.CoreLib!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start
System.Private.CoreLib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon].Start
mediatr!MediatR.Pipeline.RequestPreProcessorBehavior`2[System.__Canon,System.__Canon].Handle
mediatr!MediatR.Internal.RequestHandlerWrapperImpl`2+<>c__DisplayClass0_1[System.__Canon,System.__Canon].<Handle>b__2
mediatr!MediatR.Pipeline.RequestPostProcessorBehavior`2+<Handle>d__2[System.__Canon,System.__Canon].MoveNext
System.Private.CoreLib!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start
System.Private.CoreLib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon].Start
mediatr!MediatR.Pipeline.RequestPostProcessorBehavior`2[System.__Canon,System.__Canon].Handle
mediatr!MediatR.Internal.RequestHandlerWrapperImpl`2+<>c__DisplayClass0_1[System.__Canon,System.__Canon].<Handle>b__2
mediatr!MediatR.Internal.RequestHandlerWrapperImpl`2[System.__Canon,System.__Canon].Handle
mediatr!MediatR.Mediator.Send
functions!Functions.Components.SaleRegistrations.Aggregator.Activities.GetSaleRegistrationActivityController+<Execute>d__2.MoveNext
System.Private.CoreLib!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start
functions!Functions.Components.SaleRegistrations.Aggregator.Activities.GetSaleRegistrationActivityController.Execute
functions!Functions.Components.SaleRegistrations.Aggregator.Activities.GetSaleRegistrationActivity+<GetSaleRegistration>d__1.MoveNext
System.Private.CoreLib!System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start
functions!Functions.Components.SaleRegistrations.Aggregator.Activities.GetSaleRegistrationActivity.GetSaleRegistration
anonymously hosted dynamicmethods assembly!dynamicClass.lambda_method
microsoft.azure.webjobs.host!
microsoft.azure.webjobs.host!
system.private.corelib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1+<>c[System.__Canon,System.__Canon].<.cctor>b__9_0
system.private.corelib!System.Threading.ExecutionContext.RunInternal
system.private.corelib!System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[System.__Canon,System.__Canon].MoveNext
system.private.corelib!System.Runtime.CompilerServices.YieldAwaitable+YieldAwaiter+<>c.<OutputCorrelationEtwEvent>b__6_0
system.private.corelib!System.Runtime.CompilerServices.AsyncMethodBuilderCore+ContinuationWrapper.Invoke
system.private.corelib!System.Threading.QueueUserWorkItemCallback.ExecuteWorkItem
system.private.corelib!System.Threading.ThreadPoolWorkQueue.Dispatch
system.private.corelib!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback
What this is telling me is for some reason the following IRequest is somehow being decorated with my RetryOnConcurrencyRequestHandlerDecorator even though it does not implement IRetryOnConflict.
public class GetSaleRegistration : IRequest<SaleRegistration>
{
}
Any ideas on where I am going wrong?
Thanks!
#SpringBootTest(webEnvironment = RANDOM_PORT)
#ActiveProfiles("test")
class ContextLoadingSpec extends Specification {
#Autowired
TestRestTemplate testRestTemplate
def '/ should load the context'() {
when:
ResponseEntity<Object> entity = testRestTemplate.getForEntity('/', Object.class)
then:
entity.statusCode == HttpStatus.OK
}
#TestConfiguration
static class Config {
#Bean
RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder()
.basicAuthorization('user', 'xxxxxxxx')
}
}
}
Creating a TestConfiguration doesn't seem correct to me here. The credentials should be in 'application.yml' and the authentication call should have been mocked. Please suggest a better way of writing this test.
I'm trying to use StructureMap with nServiceBus.
The Project:
Uses a GenericHost Endpoint to send command messages
Configures nServiceBus using the StructMapBuilder.
Uses a simple StructureMap registry config
Uses a start up class TestServer supporting IWantToRunAtStartup
The TestServer class has ctor dependency on a TestManager class
The TestManager class has ctor dependency on IBus
ObjectFactory.WhatDoIHave() shows StructureMap knows how to construct the classes.
When run I get buildup errors. nServiceBus seems to be overwriting the config?
Note that when I add a IBus ctor depenendency to my event handlers without any other config all appears fine.
Error:
Exception when starting endpoint, error has been logged. Reason: Error creating object with name 'nSeviceBusStructureMapTest.TestServer' : Unsatisfied dependency expressed through constructor argument with index 0 of type [nSeviceBusStructureMapTest.ITestManager] : No unique object of type [nSeviceBusStructureMapTest.ITestManager] is defined : Unsatisfied dependency of type [nSeviceBusStructureMapTest.ITestManager]: expected at least 1 matching object to wire the [miningServiceManage] parameter on the constructor of object [nSeviceBusStructureMapTest.TestServer]
Source:
using System;
using System.Diagnostics;
using NServiceBus;
using StructureMap;
using StructureMap.Configuration.DSL;
namespace nSeviceBusStructureMapTest
{
public class TestSmRegistry : Registry
{
public TestSmRegistry()
{
For<ITestManager>().Use<TestManager>();
For<TestServer>().Use<TestServer>();
}
}
public class TestEndPoint : AsA_Server, IConfigureThisEndpoint
{
public void Init()
{
Configure.With().StructureMapBuilder(ObjectFactory.Container);
ObjectFactory.Configure(c => c.AddRegistry<TestSmRegistry>());
Debug.WriteLine(ObjectFactory.WhatDoIHave());
}
}
public class TestServer : IWantToRunAtStartup
{
public TestServer(ITestManager miningServiceManage)
{
_miningServiceManage = miningServiceManage;
}
private readonly ITestManager _miningServiceManage;
public void Run()
{
_miningServiceManage.Run();
}
public void Stop() { }
}
public interface ITestManager
{
void Run();
}
public class TestManager : ITestManager
{
public TestManager(IBus bus)
{
_bus = bus;
}
private readonly IBus _bus;
public void Run()
{
if (_bus == null) Debug.WriteLine("Error no bus");
// Send messages on bus;
}
}
}
<MsmqTransportConfig InputQueue="test" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig>
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
Any ideas?
You have to specify IWantCustomInitialization on the endpoint config class. Otherwise NServiceBus won't call the Init() method. You also need to specify what serializer to use so add:
Configure.With()
.StructureMapBuilder()
.XmlSerializer();
Hope this helps!
I'm new to IoC/DI frameworks. The first one I am trying is the Ninject framework. It seems straightforward, but I can't get my console application to run. I keep getting an ActivationException stating:
"Error activating MainWindow: the StandardProvider returned an instance of type FutureRealisticDateManager, which is not compatible with the requested service.
Using default binding from MainWindow to FutureRealisticDateManager (via StandardProvider)
declared by DateBindingModule.Load()
Activation path:
1) active request for MainWindow
from Program.Main()
using default binding from MainWindow to FutureRealisticDateManager (via StandardProvider)
declared by DateBindingModule.Load()"
My code is very simple. Here is my Program file...
class Program
{
static void Main(string[] args)
{
IKernel k = new StandardKernel(new DateBindingModule());
MainWindow mw = k.Get<MainWindow>();
mw.Show();
Console.ReadLine();
}
}
Here is my ninject binding module...
public class DateBindingModule : StandardModule
{
public override void Load()
{
Bind<MainWindow>().To<FutureRealisticDateManager>();
}
}
Here is the class that receives the injected class...
class MainWindow
{
private IRealisticDateManager _d;
[Inject]
public MainWindow(IRealisticDateManager dateManager)
{
_d = dateManager;
}
public void Show()
{
Console.WriteLine("*** MainWindow [" + _d.GetRealisticDate().ToString() + "] ");
}
}
And here is the actual class being injected...
public class FutureRealisticDateManager : TestNinject.IRealisticDateManager
{
public DateTime GetRealisticDate()
{
return DateTime.Now.AddDays(15);
}
}
And finally the simple interface that the injected class should implement...
public interface IRealisticDateManager
{
DateTime GetRealisticDate();
}
Can anybody see what I am doing wrong?
It fails because your binding is not right:
Bind<MainWindow>().To<FutureRealisticDateManager>();
FutureRealisticDataManager does not inherit from MainWindow.
Instead you should write:
Bind<IRealisticDateManager>().To<FutureRealisticDateManager>();
This tells Ninject to return FutureRealisicDateManager whenever IRealisicDateManager is requested.
This way when you call k.Get<MainWindow>() kernel will inject FutureRealisticDateManager to the constructor.