I'm trying to configure a custom permission evaluator but whenever the app starts up it's complaining of a circular reference.
The configuration code is:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
private static Logger logger = LogManager.getLogger(MethodSecurityConfig.class.getName());
#Autowired
DataSource dataSource;
#Autowired
Environment env;
#Autowired
AuthenticationManager auth;
public MethodSecurityConfig() {
logger.debug("Loading method security config.");
}
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return auth;
}
/**
* Override to set up the custom expression handler.
* #return The custom expression handler
*/
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return expressionHandler();
}
/**
* Defines a custom permission evaluator to evaluate the access permissions for Spring security.
* #return The default expression handler configured with a custom permission evaluator.
*/
#Bean
public DefaultMethodSecurityExpressionHandler expressionHandler(){
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
handler.setPermissionEvaluator(permissionEvaluator());
return handler;
}
/**
* Custom implementation of a permission evaluator
* #return An instance of {#link BasePermissionEvaluator}
*/
#Bean
public PermissionEvaluator permissionEvaluator() {
return new BasePermissionEvaluator();
}
}
When the app start up this exception occurs:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.setPermissionEvaluator(java.util.List); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'permissionEvaluator': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[AutowiredAnnotationBeanPostProcessor.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[AbstractAutowireCapableBeanFactory.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[AbstractAutowireCapableBeanFactory.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[AbstractAutowireCapableBeanFactory.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305) ~[AbstractBeanFactory$1.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[DefaultSingletonBeanRegistry.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301) ~[AbstractBeanFactory.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196) ~[AbstractBeanFactory.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368) ~[ConstructorResolver.class:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(A
What am I doing wrong here? I tried various things like adding the AuthenticationManager. Is there something else I need to override?
I had faced the same issue. In my case the reason was there was another security configuration class which has #EnableGlobalMethodSecurity annotation. Removing that annotation solved the issue.
The reason to have two security configuration classes is described here.
To my understanding this happens when Spring first processes the other configuration class, because of #EnableGlobalMethodSecurity permissionEvaluator and similar beans are registered that time and later when this configuration class is processed we got this error.
Also looks like this behaviour is arbitrary, depends on which configuration class is first processed based on classpath ordering.
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 am new to vaadin flow. I am trying to create a list view by following tutorial provided on site.
https://vaadin.com/docs/v14/flow/tutorials/in-depth-course/configuring-vaadin-grid
#Route("")
public class MainView extends VerticalLayout {
private ContactService contactService;
private Grid<Contact> grid = new Grid<>(Contact.class);
public MainView(ContactService contactService) {
this.contactService = contactService;
addClassName("list-view");
setSizeFull();
configureGrid();
add(grid);
updateList();
}
private void configureGrid() {
grid.addClassName("contact-grid");
grid.setSizeFull();
grid.setColumns("firstName", "lastName", "email", "status");
}
private void updateList() {
grid.setItems(contactService.findAll());
}
}
Here when i am executing updateList() method i am getting nullPointerExecption on service instance. I tried using repository.findAll() but facing same issue.
To check the if there is issue in service I created REST API and called the same method in service here i am getting proper result. Please help.
This is the error I am getting.
There was an exception while trying to navigate to '' with the exception message 'Error creating bean with name 'com.example.demo.ui.MainView': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.demo.ui.MainView]: Constructor threw exception; nested exception is java.lang.NullPointerException'
Annotate your ContactService implementation with #Service?
I successfully integrated swagger to several spring boot services.
Had to allow the endpoints to bypass authentication by adding in respective #EnableWebSecurity class that extends WebSecurityConfigurerAdapter (this had worked for other services fine) :
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#Order(1)
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.antMatcher("/**")
...
.antMatchers("/actuator/**").permitAll()
.antMatchers("/v2/api-docs", "/configuration/**", "/webjars/**","/swagger*/**") // ADDED THIS for swagger
.permitAll() // ADDED THIS for swagger
.antMatchers("/challenge").permitAll()
.antMatchers("/token").permitAll() // ENDPOINT with complaint now, that was previously ok.
.anyRequest()
.authenticated()
.and()
.cors();
}
...
}
For a specific one, however, once I added the relevant swagger code & dependencies, it seems to have broken and complains on what was working initially.
this is endpoint with the complaint :
#PostMapping("/token")
public ResponseDto token(#Valid #RequestBody TokenRequest request) {
try {
return service.generateJwtFromCode(request.getId(), request.getCode());
}
...
catch (Exception exception) {..
}
}
nested exception is on no constructor found for this class:
#AllArgsConstructor
public class TokenRequest {
#NotEmpty
#JsonProperty
private final String id;
#NotEmpty
#Getter
private final String code;
public UUID getId() {
return UUID.fromString(id);
}
}
Could not resolve parameter [0] in responseDTO Controller.token(Service.TokenRequest): Type definition error: [simple type, class TokenRequest]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `service.TokenRequest` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
o.s.web.servlet.DispatcherServlet : Failed to complete request: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class service.TokenRequest]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `service.TokenRequest` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in …
Not sure what it has to do with swagger integration. If i remove swagger integration code, it works fine with the same code, and doesn't complain about the type-conversion failure.
For resolving this, I also took someone's suggestion of
upgrading dependency for com.fasterxml.jackson.core
and rebuilding the code. But still no success.
compileOnly 'com.fasterxml.jackson.core:jackson-databind:2.11.2'
Things I have tried but didn't resolve:
Added a default/empty constructor
(for most others with similar problem it worked by that, for me it complaint thereafter on
error: variable id might not have been initialized
}
Added this to the tokenRequest class:
#Value
#AllArgsConstructor(onConstructor = #__(#JsonCreator(mode = JsonCreator.Mode.PROPERTIES))
Had a different error:
c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class TokenRequest]]
InvalidDefinitionException: Invalid type definition for type `TokenRequest`: More than one argument (#0 and #1) left as delegating for Creator [constructor for TokenRequest, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=#com.fasterxml.jackson.annotation.JsonCreator(mode=DELEGATING)}]: only one allowed
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62)...
Solution was to add a default constructor AND also remove final variables.
#AllArgsConstructor
public class TokenRequest {
#NotEmpty
#JsonProperty
private String id; // code fixed issue
#NotEmpty
#Getter
private String code; // code fixed issue
public TokenRequest(){} // code fixed issue
public UUID getId() {
return UUID.fromString(id);
}
}
I'm using:
Spring-data-neo4j 4.2.0-SNAPSHOT (tried with 4.2.0.RC1 too)
and since the DATAGRAPH-939 commit, I'm not able to work with repositories anymore.
#Repository
public interface MyEventRepository extends GraphRepository<Event> {}
The error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myEventRepository': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Class<org.springframework.data.repository.Repository<?, ?>>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1148)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1050)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:735)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 25 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Class<org.springframework.data.repository.Repository<?, ?>>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1466)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1097)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 41 common frames omitted
Here is an example of my failing test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = { SimpleTest.TestConfiguration.class })
public class SimpleTest {
#Configuration
#EnableNeo4jRepositories("com.nagra.ml.sp.cpm.core.repositories.test")
public static class TestConfiguration {
#Bean
public org.neo4j.ogm.config.Configuration configuration() {
org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration();
config .driverConfiguration()
.setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
return config;
}
#Bean
public SessionFactory sessionFactory() {
return new SessionFactory(configuration(), "com.nagra.ml.sp.cpm.model");
}
#Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
}
#Test
public void test() {
assertTrue(true);
}
}
According to documentation, the way of declaring repositories seems to be correct, am I doing something wrong ?
Thanks
I no longer have issues with repositories. I'm now using SDN 4.2.0.RELEASE with Spring boot 1.5.1 and I no longer extends GraphRepository as explained in SDN4.2.0 documentation.
I have a class that I moved under the grails-app/services directory in order to inject the springSecurityService. This class is the implementation (Is that the proper terminology?) of the spring userDetailsService class. Here is my declaration in resources.groovy:
userDetailsService(com.company.product.PracticeUserDetailsService) {
grailsApplication = ref('grailsApplication')
}
This class is extending GormUserDetailsService.
My attempted dependencyInjection results in a null object.
class PracticeUserDetailsService extends GormUserDetailsService{
def springSecurityService
UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException {
// impl omitted
}
}
If I create some test controller or some service in grails and inject the springSecurityService, it works fine. So, there is perhaps something about this particular class that is not placing it in the Grails ecosystem. I checked out this to try to manually inject it as follows:
beans = {
springSecurityTEST(grails.plugins.springsecurity.SpringSecurityService) {}
}
Move PracticeUserDetailsService from grails-app/services to src/groovy and change your Spring bean definition in resources.groovy to:
userDetailsService(com.company.product.PracticeUserDetailsService) {
grailsApplication = ref('grailsApplication')
springSecurityService = ref('springSecurityService')
}
For me it happened when I used GrailsApp.run(Application, args) to run the app...