I'm doing my own custom security with Spring Security and a solr core, it seems like I did something wrong but I'm not sure what.
Stack trace:
Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0' while setting constructor argument with key [5]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': Cannot resolve reference to bean 'org.springframework.security.authentication.ProviderManager#0' while setting bean property 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authentication.ProviderManager#0': Cannot resolve reference to bean 'authenticationManager' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager': Cannot resolve reference to bean 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0': Cannot resolve reference to bean while setting bean property 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'CustomUserDetails' is defined
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:231)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
This the security-context.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<security:global-method-security
secured-annotations="enabled"></security:global-method-security>
<security:http auto-config="true" realm="Protected Web"
pattern="/**" authentication-manager-ref="authenticationManager">
<security:csrf disabled="true" />
<security:intercept-url pattern="/index/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')" />
<security:intercept-url pattern="/rest/api/1.0/**" access="isAuthenticated()" />
<security:intercept-url pattern="/**" access="permitAll" />
<security:form-login login-page="/login"
username-parameter="j_username" login-processing-url="/j_spring_security_check"
password-parameter="j_password" authentication-failure-url="/login?error=1"
default-target-url="/index" always-use-default-target="true" />
<security:logout invalidate-session="true"
delete-cookies="true" logout-url="/j_spring_security_logout"
logout-success-url="/login" />
<security:session-management>
<security:concurrency-control
max-sessions="2" />
</security:session-management>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="CustomUserDetails" />
</security:authentication-manager>
</beans>
The class CustomUserDetails
:
@Service
public class CustomUserDetails implements UserDetailsService {
private static final Logger logger = Logger.getLogger(StatusAppJob.class);
@Autowired
private UserAppRepository userAppRepository;
@Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
List<UsuarioApp> result = getUserDetails(username);
if(!result.isEmpty())
{
}
else{
throw new UsernameNotFoundException(username + " not found");
}
UserDetails user = new User(username, result.get(0).getPassword(), true, true, true, true, getAuthorities(result.get(0).getRol()));
return user;
}
public Collection<? extends GrantedAuthority> getAuthorities(String rol) {
List<SimpleGrantedAuthority> auths = new java.util.ArrayList<SimpleGrantedAuthority>();
auths.add(new SimpleGrantedAuthority(rol));
return auths;
}
public List<UsuarioApp> getUserDetails(String user) {
// TODO Auto-generated method stub
return userAppRepository.findUser(user);
}
}
The app-context.xml
file:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>secturv2</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/solr-config.xml,
/WEB-INF/Spring-Quartz.xml,
/WEB-INF/spring/security-context.xml,
/WEB-INF/spring/postgres-config.xml
</param-value>
</context-param>
<!--, /WEB-INF/spring/postgres-config.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Sesiones de Hibernate -->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sfTurismo</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<error-code>401</error-code>
<location>/error</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/error</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error</location>
</error-page>
</web-app>
EDIT:
Added the servlet-context.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<annotation-driven />
<context:component-scan base-package="mx.sectur.turismo" />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<resources location="/views/" mapping="/**" />
<beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<beans:bean
class="org.springframework.data.repository.support.DomainClassConverter">
<beans:constructor-arg ref="conversionService" />
</beans:bean>
<mvc:annotation-driven conversion-service="conversionService">
<mvc:argument-resolvers>
<beans:bean
class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
<beans:property name="maxPageSize" value="10"></beans:property>
</beans:bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<interceptors>
<beans:bean id="webContentInterceptor"
class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<beans:property name="cacheSeconds" value="0" />
<beans:property name="useExpiresHeader" value="true" />
<beans:property name="useCacheControlHeader" value="true" />
<beans:property name="useCacheControlNoStore" value="true" />
</beans:bean>
</interceptors>
</beans:beans>
Why I'm getting
Cannot resolve reference to bean while setting bean property 'userDetailsService'"
message?
These issue is due to referencing bean using wrong name.
Please override the name of the bean created by @Service annotation like this
@Service("CustomUserDetails")
public class CustomUserDetails implements UserDetailsService
By default, Spring will lower case the first character of the component – from ‘CustomUserDetails’ to ‘customUserDetails’. And you can retrieve this component with name ‘customUserDetails’.
so you can also modify below code if you do not want to override default name as below
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetails" />
</security:authentication-manager>
Please refer this link for better understanding this concept
Other thing that might be causing issue is you have defined annotation driven in servelet-xml which is in web application context where your service bean is getting initialized. but you have defined security-context in main application context. hence just create a file give any name to it and shift to that file.
I had a similar problem once.
The application-context file should be present in the resources folder in order for the ClassPathXmlApplicationContext to load the context config file.
The class path resource of you bean is wrong or the file name is not properly mentioned. In your case you have not mentioned the bean name and spring context is unable to autodetect it and get this instance from the context.
There are two ways to do this
Use @service on top of the class which is used to auto detect the class like
@Service("BeanName") // so that spring context can autodetect it and we can get its instance from the context
class className{
//class members
//constructors
//methods
}
Mention bean class properly
<bean id="1" class="com.package.javafilename"></bean>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With