Search code examples
springmavenspring-mvcspring-securityspring-java-config

Spring Seccurity Java based Configuration not working. It will always show index.jsp page


I am converting my simple demo project from bean configuration to pure java based configuration. there small problem some where but i cannot find where it occurs please help me. I use this tutorial for build my project Spring Security 4 Hello World Annotation+XML Example

but there small defferent between this project and my project that is project maven archetype my one is multi module maven project.

here is my project archetype

maven archetype

following files are the I used for do my configuration

This pom is the root pom and each module has there own poms. this pom is inside the sms module

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>com.geek</groupId>
<artifactId>sms</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>sms</name>

<properties>
    <spring.version>4.2.0.RELEASE</spring.version>
    <spring-security.version>4.0.2.RELEASE</spring-security.version>
    <jstl.version>1.2</jstl.version>
    <junit.version>3.8.1</junit.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

<build>
    <defaultGoal>install</defaultGoal>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                <warSourceDirectory>webapp</warSourceDirectory>
                <warName>sms-web</warName>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
    <finalName>smsweb</finalName>
</build>

<modules>
  <module>sms-core</module>
  <module>sms-web</module>
</modules>


<dependencies>

    <!-- Spring framework -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>3.2.2.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.2.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>2.5.6</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring-security.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring-security.version}</version>
    </dependency>

    <!-- mongodb java driver -->
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>2.11.0</version>
    </dependency>

    <!-- Spring data mongodb -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>1.2.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>

     <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>${jstl.version}</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
         <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.1</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>commons-digester</groupId>
        <artifactId>commons-digester</artifactId>
        <version>2.1</version>
    </dependency>

  </dependencies>


 </project>

AppConfig.java

package com.geek.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.geek.*" )
public class AppConfig {

@Bean
public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver
                       = new InternalResourceViewResolver();
    viewResolver.setViewClass(JstlView.class);
    viewResolver.setPrefix("/WEB-INF/pages/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
}

}

SecurityConfig.java

package com.geek.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");
    auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
    auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");//dba have two roles.
}

@Override
protected void configure(HttpSecurity http) throws Exception {

  http.authorizeRequests()
    .antMatchers("/", "/home").permitAll() 
    .antMatchers("/admin/**").access("hasRole('ADMIN')")
    .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
    .and().formLogin()
    .and().exceptionHandling().accessDeniedPage("/Access_Denied");

}

}

SpringMvcInitializer.java

package com.geek.config;

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[] { "/" };
}

}

SpringSecurityInitializer.java

package com.geek.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

}

LoginController.java

package com.geek.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

@RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
public String homePage(ModelMap model) {
    model.addAttribute("greeting", "Hi, Welcome to mysite. ");
    return "welcome";
}

@RequestMapping(value = "/admin", method = RequestMethod.GET)
public String adminPage(ModelMap model) {
    model.addAttribute("user", getPrincipal());
    return "admin";
}

@RequestMapping(value = "/db", method = RequestMethod.GET)
public String dbaPage(ModelMap model) {
    model.addAttribute("user", getPrincipal());
    return "dba";
}

@RequestMapping(value="/logout", method = RequestMethod.GET)
   public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      if (auth != null){    
         new SecurityContextLogoutHandler().logout(request, response, auth);
      }
      return "welcome";
   }

@RequestMapping(value = "/Access_Denied", method = RequestMethod.GET)
public String accessDeniedPage(ModelMap model) {
    model.addAttribute("user", getPrincipal());
    return "accessDenied";
}

private String getPrincipal(){
    String userName = null;
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

    if (principal instanceof UserDetails) {
        userName = ((UserDetails)principal).getUsername();
    } else {
        userName = principal.toString();
    }
    return userName;
}

}

what was i expected is when i am trying to log into my application using this

http://localhost:8080/sms-web I need redirect to the login.jsp page or something any other page but this will redirect to the index.jsp.

when i am trying to run this sms-web.war using external tomcat and put my war file into webapps folder it will end up with error like this

 > uring scanning can improve startup time and JSP compilation time.
 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
 SLF4J: Defaulting to no-operation (NOP) logger implementation
 SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further 
 details.
 11-Jun-2017 14:18:55.435 SEVERE [localhost-startStop-1] 
 org.apache.catalina.core.ContainerBase.addChildInternal 
 ContainerBase.addChild: start:
 org.apache.catalina.LifecycleException: Failed to start component 
 [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/sms-web]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:952)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1823)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
 Caused by: java.lang.NoSuchMethodError: 

org.springframework.core.annotation.AnnotationAwareOrderComparator.sort(Ljava/util/List;)V at

org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:171) at

org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178 ) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ... 10 more

11-Jun-2017 14:18:55.435 SEVERE [localhost-startStop-1] 
org.apache.catalina.startup.HostConfig.deployWAR Error deploying web 
application archive F:\Pe
rsonal\Cingle Eve\Server\apache-tomcat-8.5.9\webapps\sms-web.war
java.lang.IllegalStateException: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: Failed to start component 
[StandardEngine[Cat
alina].StandardHost[localhost].StandardContext[/sms-web]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:756)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:952)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1823)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

 11-Jun-2017 14:18:55.455 INFO [localhost-startStop-1] 
 org.apache.catalina.startup.HostConfig.deployWAR Deployment of web 
 application archive F:\Person
al\Cingle Eve\Server\apache-tomcat-8.5.9\webapps\sms-web.war has finished in 
3,913 ms

What's wrong I did please help me to the find the answer...


Solution

  • Looks like you have a mess in your dependencies mixing different spring versions. Try using dependencies below:

    <dependencies>
        <!-- Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <!-- mongodb java driver -->
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>${mongo-driver.version}</version>
        </dependency>
        <!-- Spring data mongodb -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>${spring-data.version}</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>${cglib.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet-api.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>${servlet-jsp-api.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-digester3</artifactId>
            <version>${commons-digester.version}</version>
        </dependency>
    </dependencies>
    

    With following properties:

    <properties>
        <spring.version>4.3.9.RELEASE</spring.version>
        <spring-security.version>4.2.3.RELEASE</spring-security.version>
        <mongo-driver.version>3.4.2</mongo-driver.version>
        <spring-data.version>1.10.4.RELEASE</spring-data.version>
        <cglib.version>3.2.5</cglib.version>
        <servlet-api.version>3.1.0</servlet-api.version>
        <servlet-jsp-api.version>2.3.1</servlet-jsp-api.version>
        <commons-digester.version>3.2</commons-digester.version>
        <jstl.version>1.2</jstl.version>
        <junit.version>4.12</junit.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    

    I've used latest spring version and updated few other dependencies.

    Also in order to redirect to login page from index do the following:

    .antMatchers("/", "/home").access("hasRole('ADMIN')")