I'm trying to perform integration of my GWT application and Spring Security. And when I add @PreAuthorize("hasRole('ROLE_USER')")
annotation to the method of my DAO class following exception appears:
No unique bean of type [server.dao.ElementServiceDAO] is defined: expected single bean but found 0
DaoServiceLocator can't find DAO bean, but in debug mode I see elementServiceDAO bean in ApplicationContext instance.
My DAO class looks like this:
@Service
public class ElementServiceDAO extends EntityDAO {
@PreAuthorize("hasRole('ROLE_USER')")
@SuppressWarnings("unchecked")
public Layer getFullRenderingTopology() {
...
}
}
DAO service locator's code:
public class DaoServiceLocator implements ServiceLocator {
@Override
public Object getInstance(final Class<?> clazz) {
try {
final HttpServletRequest request = RequestFactoryServlet
.getThreadLocalRequest();
final ServletContext servletContext = request.getSession()
.getServletContext();
final ApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
return context.getBean(clazz);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
applicationContext-security.xml:
<authentication-manager>
<authentication-provider>
<user-service>
<user name="operator" password="operator" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="guest" password="guest" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<global-method-security pre-post-annotations="enabled" />
Please give me any advice!
When ElementServiceDAO
implements an interface (in your case - transitively via EntityDAO
), Spring by default creates an interface-based proxy to apply security aspects. So, elementServiceDAO
in your application context is a proxy that isn't instance of ElementServiceDAO
, therefore it cannot be retrieved by type.
You either need to
force creation of target-class-based proxies as follows
<global-method-security
pre-post-annotations="enabled" proxy-target-class = "true" />
or create a business interface for ElementServiceDAO
and use that interface instead of implementation class.
See also: