I am trying to integrate spring security using java configuration for couple of days with no luck and it got my brains out figuring what's going wrong. Really looking for some help here.
The java files i have used for the configuration are AppConfig.java, SecurityConfig.java, SpringAnnotationWebInitializer.java SpringSecurityInitializer.java, AppInitializer.java and web.xml is also there. I am listing the code for each file below.
First of all web.xml
<web-app>
<!-- <context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param> -->
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<!-- <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> -->
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>backend.configuration.AppConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
Next is SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
Next SpringSecurityInitializer.java
#Order(1)
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer{
}
SpringAnnotationWebInitializer.java
public class SpringAnnotationWebInitializer extends AbstractContextLoaderInitializer {
#Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(AppConfig.class);
return applicationContext;
}
}
AppConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "backend")
#Import({SecurityConfig.class})
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public ResourceBundleViewResolver resourceBundleViewResolver() {
ResourceBundleViewResolver resolver = new ResourceBundleViewResolver();
resolver.setBasename("messages");
resolver.setOrder(0);
return resolver;
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/static/");
viewResolver.setSuffix(".html");
viewResolver.setOrder(1);
return viewResolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("/static/");
}
}
Finally AppInitializer.java
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
FilterRegistration.Dynamic filter = ctx.getServletContext().addFilter(
"springSecurityFilterChain", new DelegatingFilterProxy());
filter.addMappingForUrlPatterns(null, false, "/*");
}
}
When I run this application on tomcat I am getting the following NullPointer Exception
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:799)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
... 6 more
Caused by: java.lang.NullPointerException
at backend.configuration.AppInitializer.onStartup(AppInitializer.java:33)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5456)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 6 more
Sep 14, 2015 8:11:11 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:300)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:731)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Catalina.start(Catalina.java:689)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1131)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:799)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 6 more
at the following line in AppInitializer.java
filter.addMappingForUrlPatterns(null, false, "/*");
I think I am not able to initialize the security filter. I have tried the following links for the solution but was not able to get any success. I am definitely missing something.
NullPointerException at org.springframework.security.web.FilterChainProxy.getFilters
springSecurityFilterChain nullPointer Exception
I have tried lot of other links as well but still stuck. Please help me out here
Finally, able to fix now. Need to change the two files - SpringAnnotationWebInitializer.java and AppInitializer.java
Changed the SpringAnnotationWebInitializer.java to extend "AbstractAnnotationConfigDispatcherServletInitializer" instead of "AbstractContextLoaderInitializer" and removed the servlet and filter initialization from AppInitializer.java
So the final code for these two files is as follows:
SpringAnnotationWebInitializer.java
public class SpringAnnotationWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return null;
}
}
AppInitializer.java
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
}
}
Finally, the basic spring security is integrated (phewww). I hope this will help others, as this has all the configuration(except maven dependencies) that is needed to integrate the basic spring-security using java configuration into your app.
Related
Given existing web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<display-name>/</display-name>
<listener><listener-class>m.Web.startup.Listener</listener-class></listener>
<listener><listener-class>m.Store.Listener</listener-class></listener>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<servlet-mapping>
<servlet-name>mmm.com.dispatcher.servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mmm.com.dispatcher.servlet</servlet-name>
<servlet-class>m.Web.startup.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.XmlWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/Web/config/ConfigWeb.xml
classpath:/Auth/config/ConfigAuth.xml
classpath:/Assets/config/ConfigAssets.xml
classpath:/Accounts/config/ConfigAccounts.xml
classpath:/App/config/ConfigApp.xml
classpath:/Accounts/config/ConfigAccounts.xml
classpath:/Store/config/ConfigStore.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I've added:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.0.48</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.0.48</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>8.0.48</version>
</dependency>
and attempted to do:
private static void c() throws LifecycleException {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
Tomcat tomcat = new Tomcat();
tomcat.setBaseDir(tmpDir.getAbsolutePath());
tomcat.setPort(8080);
XmlWebApplicationContext context = new XmlWebApplicationContext();
DispatcherServlet servlet = new DispatcherServlet(context);
servlet.setContextConfigLocation("""
classpath:/Web/config/ConfigWeb.xml
classpath:/Auth/config/ConfigAuth.xml
classpath:/Assets/config/ConfigAssets.xml
classpath:/Accounts/config/ConfigAccounts.xml
classpath:/App/config/ConfigApp.xml
classpath:/Accounts/config/ConfigAccounts.xml
classpath:/Store/config/ConfigStore.xml
""");
Tomcat.addServlet(tomcat.addContext(tomcat.getHost(), "/", tmpDir.getAbsolutePath()), "mmm.com.dispatcher.servlet", servlet);
new m.Web.startup.Listener();
new m.Store.Listener();
tomcat.start();
tomcat.getServer().await();
}
But is not working.
The server starts but several things are not working. localhost:8080 results in an error page.
Also tried:
public static void e() throws LifecycleException {
Tomcat tomcat = new Tomcat() {
#Override
public Context addWebapp(String contextPath, String docBase) throws ServletException {
Context context = null;
try {
context = new StandardContext();
context.setName(contextPath);
context.setPath(contextPath);
context.setDocBase(docBase);
context.setRealm(this.getHost().getRealm());
ContextConfig contextConfig = new ContextConfig();
context.addLifecycleListener(contextConfig);
String pathToWebXml = docBase + "Store/web.xml";
if (new File(pathToWebXml).exists()) {
contextConfig.setDefaultWebXml(pathToWebXml);
} else {
contextConfig.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML");
}
host.addChild(context);
} catch (Exception e) {
log.error("Error deploying webapp", e);
}
return context;
}
};
tomcat.setPort(8081);
Service service = tomcat.getService();
service.addConnector(sslConnector());
try {
URL resource = TomcatServer.class.getClassLoader().getResource(".");
tomcat.addWebapp("", resource.getPath());
//add others here...
} catch (ServletException e) {
log.error("Problem webapp. Could be fatal?");
}
tomcat.start();
tomcat.getServer().await();
}
But this results in errors such as :
WARNING: Failed to scan
[file:/Users/j/.m2/repository/xalan/xalan/2.7.2/xercesImpl.jar] from classloader hierarchy
java.io.IOException: java.lang.reflect.InvocationTargetException
at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:185)
at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:65)
at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:49)
at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:374)
at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:309)
at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:278)
at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:229)
at org.apache.catalina.startup.ContextConfig.processJarsForWebFragments(ContextConfig.java:1898)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1131)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:783)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:307)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5212)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.GeneratedConstructorAccessor6.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:182)
... 21 more
Caused by: java.nio.file.NoSuchFileException: /Users/j/.m2/repository/xalan/xalan/2.7.2/xercesImpl.jar
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
at java.base/sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:148)
at java.base/java.nio.file.Files.readAttributes(Files.java:1843)
at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1198)
at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:701)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:240)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:171)
at java.base/java.util.jar.JarFile.<init>(JarFile.java:347)
... 26 more
Jun 23, 2021 2:57:15 PM org.apache.tomcat.util.scan.StandardJarScanner processURLs
WARNING: Failed to scan [file:/Users/j/.m2/repository/xalan/xalan/2.7.2/xml-apis.jar] from classloader hierarchy
java.io.IOException: java.lang.reflect.InvocationTargetException
at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:185)
at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:65)
at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:49)
at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:374)
at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:309)
at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:278)
at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:229)
at org.apache.catalina.startup.ContextConfig.processJarsForWebFragments(ContextConfig.java:1898)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1131)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:783)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:307)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5212)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.GeneratedConstructorAccessor6.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:182)
... 21 more
Caused by: java.nio.file.NoSuchFileException: /Users/j/.m2/repository/xalan/xalan/2.7.2/xml-apis.jar
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
at java.base/sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:148)
at java.base/java.nio.file.Files.readAttributes(Files.java:1843)
at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1198)
at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:701)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:240)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:171)
at java.base/java.util.jar.JarFile.<init>(JarFile.java:347)
... 26 more
Note that currently I am starting it from within a static void main from within Intellij.
The method e() here relies on parsing the existing web.xml file, but this is not working and it fails it seems due to lacking classpath stuff.
The first method c() relies on trying to replicate the configuration, but I am missing ways of trying to properly replicating it.
I am unable for instance to add a Listener in the same manner, and I am unable to configure for instance the session-config parameter.
The first one has no classpath issues and starts but I think some things like the listeners are not properly set up, nor their events fired.
EDIT 1:
Perhaps this the way to add listeners, in c():
Context ctx = tomcat.addContext(tomcat.getHost(), "/", tmpDir.getAbsolutePath());
ctx.addApplicationListener(m.Web.startup.Listener.class.getCanonicalName());
ctx.addApplicationListener(m.Store.Listener.class.getCanonicalName());
But again things start up, but still error in tomcat. Unsure if the classpath: ... in original web.xml mimicked in c() are accurately applied as well.
EDIT 2:
Now gotten most things up, however WebSockets (annotated in the code) is not being picked up, as well as HttpSessionListener not being triggered.
In web.xml you could define a listener that implemented several interfaces such as ServletContextListener, HttpSessionListener but with embedded Tomcat this does not seem to work. I am also not able to register them separately either as of now, but that should be possible. Still annoying.
I just wish you could just feed it the web.xml and it could configure itself, just like the standalone one does. I don't get why that has to be so hard.
private static void c() throws LifecycleException, ServletException, URISyntaxException, DeploymentException, IOException {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
Tomcat tomcat = new Tomcat();
tomcat.setBaseDir(tmpDir.getAbsolutePath());
tomcat.setPort(8080);
Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
ctx.addApplicationListener(m.Web.startup.Listener.class.getCanonicalName());
ctx.addApplicationListener(m.Store.Listener.class.getCanonicalName());
ctx.addApplicationListener(Listener.class.getCanonicalName());
ctx.setSessionTimeout(30);
Wrapper wrapper = Tomcat.addServlet(ctx, "mmm.com.dispatcher.servlet", m.Web.startup.DispatcherServlet.class.getCanonicalName());
wrapper.addInitParameter("contextClass", org.springframework.web.context.support.XmlWebApplicationContext.class.getCanonicalName());
wrapper.addInitParameter("contextConfigLocation", """
classpath:/Web/config/ConfigWeb.xml
classpath:/Auth/config/ConfigAuth.xml
classpath:/Assets/config/ConfigAssets.xml
classpath:/Accounts/config/ConfigAccounts.xml
classpath:/App/config/ConfigApp.xml
classpath:/Accounts/config/ConfigAccounts.xml
classpath:/Store/config/ConfigStore.xml
""");
wrapper.setLoadOnStartup(1);
if ( true ) {
wrapper.addMapping("/");
}
else if ( false ) {
ctx.addServletMappingDecoded("/", "mmm.com.dispatcher.servlet", true);
}
tomcat.start();
if ( false ) {
ContainerProvider.getWebSocketContainer().connectToServer(Socket.class, new URI("ws://"));
}
tomcat.getServer().await();
}
Heyy coders...I was setting up Apache tiles and was configuring the java & xml classes..But now when i am starting the server i am getting an error like..please help me to solve this issue and my tiles also not working ..
SEVERE: Error during ServletContainerInitializer processing
javax.servlet.ServletException: Failed to instantiate WebApplicationInitializer class
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:155)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5139)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1377)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1367)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:902)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1377)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1367)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:902)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:932)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:633)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:344)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:475)
Caused by: java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:223)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:120)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:269)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:242)
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:131)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:272)
at org.springframework.web.context.AbstractContextLoaderInitializer.<init>(AbstractContextLoaderInitializer.java:44)
at org.springframework.web.servlet.support.AbstractDispatcherServletInitializer.<init>(AbstractDispatcherServletInitializer.java:60)
at org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer.<init>(AbstractAnnotationConfigDispatcherServletInitializer.java:42)
at com.wanclik.config.AppInitializer.<init>(AppInitializer.java:8)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:152)
... 29 more
Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1363)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1186)
... 47 more
My java Classes are..
Appconfig.java
#Configuration
#EnableWebMvc
#EnableAsync
#ComponentScan( basePackages = "com.wanclik" )
public class AppConfig extends WebMvcConfigurerAdapter {
/**
* Configure TilesConfigurer.
*/
#Bean
public TilesConfigurer tilesConfigurer(){
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[] {"/WEB-
INF/pages/tiles/tiles.xml"});
tilesConfigurer.setCheckRefresh(true);
return tilesConfigurer;
}
/**
* Configure ViewResolvers to deliver preferred views.
*/
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
TilesViewResolver viewResolver = new TilesViewResolver();
registry.viewResolver(viewResolver);
}
/**
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
2.AppInitializer.java
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
}
XML files are..
1.Web.xml
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>SEO Rest APIs</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
</web-app>
2.mvc-dispatcher-servlet.xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:component-scan base-package="com.wanclik" />
<context:property-placeholder location="classpath:*.properties" />
<util:properties id="props" location="classpath:*.properties" />
<mvc:annotation-driven />
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/pages/tiles/tiles.xml</value>
</list>
</property>
</bean>
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>
From the logs it shows that org.slf4j.impl.StaticLoggerBinder class not found so please ensure that you have dependency in your pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.6</version>
</dependency>
I am trying to add Spring security with customized login page and access to database to my Spring MVC application. It seems like my mapping is wrong as it can not map j_spring_security_check.
To solve the issue I had a look at following pages 1,2,3 but could not solve the issue yet.
If you do not have much time, please read PART 2 below, that is where edited section of the question begins. Otherwise, please read both PART 1 and PART 2.
PART 1
I also added following lines to my web.xml file but the application returns following exceptions.
<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>
Caused by: java.lang.IllegalStateException: Duplicate Filter registration for 'springSecurityFilterChain'. Check to ensure the Filter is only configured once.
at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.registerFilter(AbstractSecurityWebApplicationInitializer.java:215)
at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.insertSpringSecurityFilterChain(AbstractSecurityWebApplicationInitializer.java:147)
at org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer.onStartup(AbstractSecurityWebApplicationInitializer.java:121)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5423)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 6 more
Jun 13, 2015 2:44:54 PM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Catalina.start(Catalina.java:691)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:456)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1131)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:800)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 6 more
Jun 13, 2015 2:44:54 PM org.apache.catalina.startup.Catalina start
SEVERE: The required Server component failed to start so Tomcat is unable to start.
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.startup.Catalina.start(Catalina.java:691)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:456)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardService[Catalina]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 7 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 9 more
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1131)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 11 more
Without adding that filter once the form is submitted the request will be catch by following controller.
#Controller
public class MainController {
#RequestMapping("/{viewName}")
public String index(#PathVariable String viewName) {
...
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
<servlet>
<servlet-name>my</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- <listener> -->
<!-- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> -->
<!-- </listener> -->
<!-- <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> -->
<servlet-mapping>
<servlet-name>my</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/my-security.xml
</param-value>
</context-param>
</web-app>
my-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<http auto-config="true" access-denied-page="/notFound.jsp"
use-expressions="true">
<intercept-url pattern="/" access="permitAll" />
</http>
<!-- <beans:import resource="security-db.xml" /> -->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="alex" password="123456" authorities="ROLE_USER" />
<user name="mkyong" password="123456" authorities="ROLE_USER, ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
AppConfig.java
#EnableWebMvc
#Configuration
#ComponentScan({ "com.myproject.*" })
#EnableTransactionManagement
#Import({ SecurityConfig.class })
public class AppConfig {
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(
dataSource());
builder.scanPackages("com.myproject.model").addProperties(
getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.format_sql", "true");
prop.put("hiberate.show_sql", "true");
prop.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return prop;
}
#Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("jack");
ds.setPassword("jack");
return ds;
}
#Bean
public HibernateTransactionManager txManager() {
return new HibernateTransactionManager(sessionFactory());
}
}
SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("userDetailsService")
UserDetailsService userDetailsService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(
passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/profile/**")
.access("hasRole('ADMIN')").and().formLogin()
.loginPage("/signin").failureUrl("/signin?error")
.usernameParameter("username").passwordParameter("password")
.and().logout().logoutSuccessUrl("/index").and().csrf().and()
.exceptionHandling().accessDeniedPage("/403");
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
SpringMVCInitializer.java
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpringMvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
LoginController.java
#Controller
public class LoginController {
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
#RequestParam(value = "error", required = false) String error,
#RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
}
**
PART 2
Based on Thomas's suggestions I changed the code as following
**
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
<servlet>
<servlet-name>my</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>my</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
AppConfig.java
#EnableWebMvc
#Configuration
#ComponentScan({ "com.myproject" })
#EnableTransactionManagement
#Import({ SecurityConfig.class })
public class AppConfig {
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(
dataSource());
builder.scanPackages("com.myproject.model").addProperties(
getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.format_sql", "true");
prop.put("hiberate.show_sql", "true");
prop.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return prop;
}
#Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("jack");
ds.setPassword("jack");
return ds;
}
#Bean
public HibernateTransactionManager txManager() {
return new HibernateTransactionManager(sessionFactory());
}
}
SecurityConfig.java
#Configuration
#EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("userDetailsService")
UserDetailsService userDetailsService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
// auth.userDetailsService(userDetailsService).passwordEncoder(
// passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/profile/**")
.access("hasRole('ADMIN')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.and().logout().logoutSuccessUrl("/index").and().csrf().and()
.exceptionHandling().accessDeniedPage("/403");
}
#Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
SpringMVCInitializer.java
public class SpringMvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
MainController
#Controller
public class MainController {
#RequestMapping("/{viewName}")
public String index(#PathVariable String viewName) {
System.err.println("View Name is :" + viewName);
if (isValidView(viewName)) {
return viewName;
}
return null;
}
Regarding MainController, this is the way that I handle static pages such as www.myproject.com/index, www.myproject.com/contactus etc. My other question regarding this issue is here
There are several issues in your code. The most important one is that you are mixing the Java configuration and the XML configuration for Spring Security. Decide which configuration you prefer to use. In my answer, I will focus on the Java-based configuration, as I would completely remove the XML configuration from your code.
In your case, the #EnableWebSecurity annotation by default already registers the appropriate filters. But if your are using the Spring MVC, it should rather be #EnableWebMvcSecurity.
Furthermore, look at your HttpSecurity configuration:
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/profile/**")
.access("hasRole('ADMIN')").and().formLogin()
.loginPage("/signin").failureUrl("/signin?error")
.usernameParameter("username").passwordParameter("password")
.and().logout().logoutSuccessUrl("/index").and().csrf().and()
.exceptionHandling().accessDeniedPage("/403");
}
You are obviously telling that login page will be at /signin, but in your LoginController the mapping is for /login. And what for you config the .usernameParameter("username") .passwordParameter("password")? It's already done this way in Spring Security default configuration.
You should also add the SecurityInitializer class, which in Spring Security 3.2 can look like this:
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityConfig.class);
}
}
So to sum up, the basic steps to add the Spring Security to your project is to do the following:
Add the appropriate (Maven, Gradle) dependencies for Spring Security;
Configure the Spring Security class annotated with #EnableWebMvcSecurity, especially in configureGlobal(...) and configure(...) methods;
Register the class extending AbstractSecurityWebApplicationInitializer;
Provide the mapping for login page in your controller and write down the custom form in JSP page.
The basic login form can look like this:
<form name='loginForm' method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td colspan='2'><input name="submit" type="submit"
value="submit" /></td>
</tr>
</table>
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
These basic steps enable the Spring Security in your project. For more information, the good tutorials are:
http://docs.spring.io/spring-security/site/docs/3.2.x/guides/hellomvc.html
http://docs.spring.io/spring-security/site/docs/3.2.x/guides/form.html
Good luck :)
I would highly suggest you to follow either Java or XML config. I personally prefer Java config.
Remove all Spring Security related XML configs and create following
files.
Amend the permission addresses to whatever you have.
public class MessageSecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer { //register the springSecurityFilterChain with the war
}
public class MessageWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class }; //make sure your config file gets loaded
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return null;
}
#Configuration
#EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
System.err.println("in here");
auth.inMemoryAuthentication().withUser("user#yahoo.com")
.password("password").roles("USER"); //access to inmemory credentials
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**", "/", "/index", "/aboutus")
.permitAll() //allow access to your static pages and resources
.antMatchers("/profile/**")
.hasRole("USER") //profile address is only available to users ( do not need to add ROLE_ as Spring does it for you)
.and() //and is equivalent of end tag in XML
.formLogin().loginPage("/signin").failureUrl("/signin?error")
.permitAll().and().logout().logoutUrl("/singout").permitAll();
}
For further explanation and to access to DB refer to the documentation
I am in the proces of creating simple CRUD program with Spring data rest Spring data rest,
but I have a problem with security configuration (example was taken from here.
I have a WebAppInitializer:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{JpaRepositoryConfig.class, SecurityConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{CustRepositoryRestMvcConfiguration.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Filter[] getServletFilters() {
return new Filter[]{ new DelegatingFilterProxy("springSecurityFilterChain")};
}
}
I have a next crud repository:
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.repository.annotation.RestResource;
import org.springframework.security.access.prepost.PreAuthorize;
#PreAuthorize("hasRole('ROLE_USER')")
#RestResource(path = "products", rel = "products")
public interface ProductRepository extends PagingAndSortingRepository<Product, Long> {
#PreAuthorize("hasRole('ROLE_ADMIN')")
#Override
Product save(Product s);
#PreAuthorize("hasRole('ROLE_ADMIN')")
#Override
void delete(Long aLong);
}
I have a next security configuration:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("greg").password("turnquist").roles("USER").and()
.withUser("ollie").password("gierke").roles("USER", "ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/products").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/products/**").hasRole("ADMIN")
.antMatchers(HttpMethod.PATCH, "/products/**").hasRole("ADMIN").and()
.csrf().disable();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
I used next version of dependencies:
<java-version>1.7</java-version>
<spring-data-rest-version>1.0.0.RELEASE</spring-data-rest-version>
<spring.version>3.2.2.RELEASE</spring.version>
<org.slf4j-version>1.7.5</org.slf4j-version>
From project configured log4j I am getting these errors:
SEVERE: Error filterStart
org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/admin] startup failed due to previous errors
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationCon
text - Closing Root WebApplicationContext: startup date [Tue Dec 30 00:09:21 EET
2014]; root of context hierarchy
......
DEBUG: org.springframework.beans.factory.support.DisposableBeanAdapter - Invokin
g destroy() on bean with name 'org.springframework.security.config.annotation.au
thentication.configuration.AuthenticationConfiguration'
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Re
trieved dependent beans for bean '(inner bean)': [(inner bean), productRepositor
y]
DEBUG: org.springframework.beans.factory.support.DisposableBeanAdapter - Invokin
g destroy() on bean with name 'securityConfig'
From tomcat 7.0.56 localhost log I also have these errors in the logs:
SEVERE: Exception starting filter delegatingFilterProxy
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:568)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1102)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326)
at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:236)
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4830)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5510)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1083)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1879)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
What is causing the errors in these logs?
After searching Google for more than 3 hours, I'm giving up on this.
I have this web.xml:
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>ar.com.dera.simor.config</param-value>
</context-param>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
<error-page>
<error-code>404</error-code>
<location>/not_found</location>
</error-page>
OK, I did it work just with the servlet, and Spring Security.
But also, I want to configure (in Java) the jsp-config and the error-page.
How can I do this?
This is my WebInitializer class:
#Configuration
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(WebConfig.class);
rootContext.scan("ar.com.dera.simor.config");
ServletRegistration.Dynamic appServlet = servletContext.addServlet(
"appServlet", new DispatcherServlet(rootContext));
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/");
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter utf8Filter = new CharacterEncodingFilter();
utf8Filter.setEncoding("UTF-8");
utf8Filter.setForceEncoding(true);
return new Filter[] { utf8Filter };
}
}
Basically, you can't. ServletContext does not provide any methods to configure errors pages and JSPs from scratch. It does, however, provide a getJspConfigDescriptor method to get the <jsp-config> configuration (readonly).