1

I'm new to Spring Security and I having major issues while setting up a basic example. I'm trying to run this example http://javapointers.com/tutorial/spring-custom-userdetailsservice-example/ but I does not work for me. Here is the code:

Controller

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);

        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

        String formattedDate = dateFormat.format(date);

        model.addAttribute("serverTime", formattedDate );

        return "home";
    }
    @RequestMapping(value = "/admin", method = RequestMethod.GET)
    public String viewAdmin() {
        return "admin";
    }
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String viewLogin() {
        return "login";
    }
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String viewLogout() {
        return "logout";
    }
}

CustomUserDetailsService

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    static final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        Map<String, Object> userMap = userService.getUserByUsername(s);

        //check if this user with this username exist, if not, throw an exception
        // and stop the login process
        if (userMap == null) {
            throw new UsernameNotFoundException("User details not found with this username: " + s);
        }

        String username = (String) userMap.get("username");
        String password = (String) userMap.get("password");
        String role = (String) userMap.get("role");

        List authList = getAuthorities(role);

        //get the encoded password
        String encodedPassword = passwordEncoder.encode(password);

        User user = new User(username, encodedPassword, authList);

        return user;
    }

    private List getAuthorities(String role) {
        List authList = new ArrayList();
        authList.add(new SimpleGrantedAuthority("ROLE_USER"));

        //you can also add different roles here
        //for example, the user is also an admin of the site, then you can add ROLE_ADMIN
        //so that he can view pages that are ROLE_ADMIN specific
        if (role != null && role.trim().length() > 0) {
            if (role.equals("admin")) {
                authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            }
        }

        return authList;
    }
}

User Service

@Service("userService")
public class UserService {

    public Map<String, Object> getUserByUsername(String username) {
        Map<String, Object> userMap = null;
        //logic here to get your user from the database
        if (username.equals("admin") || username.equals("user")) {
            userMap = new HashMap();
            userMap.put("username", "admin");
            userMap.put("password", "password");
            //if username is admin, role will be admin, else role is user only
            userMap.put("role", (username.equals("admin")) ? "admin" : "user");
            //return the usermap
            return userMap;
        }
        //if username is not equal to admin, return null
        return null;
    }
}

servlet-context.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" xmlns:mvc="http://www.springframework.org/schema/mvc"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <mvc:annotation-driven></mvc:annotation-driven>

    <!--  <resources mapping="/resources/**" location="/resources/" />-->

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="com.test8.security8"></context:component-scan>

    <http use-expressions="true" auto-config="false">
        <!--we intercept request and make sure that login users with specific role can only access the pages-->
        <intercept-url pattern="/home" access="hasRole('ROLE_USER')" />
        <intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />

        <form-login login-page="/login" default-target-url="/home"
                    authentication-failure-url="/login?error=" />
        <logout invalidate-session="true" logout-success-url="/logout" />
    </http>

    <authentication-manager>
        <authentication-provider user-service-ref="customUserDetailsService">
            <password-encoder ref="encoder"/>
        </authentication-provider>
    </authentication-manager>

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    <beans:bean id="customUserDetailsService" class="com.test8.security8.service.CustomUserDetailsService"/>


</beans:beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</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>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--Spring Security Filter-->  
    <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>

</web-app>

I'm getting this error:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:638)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1159)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:282)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:979)
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:324)
Sorbete
  • 63
  • 8
  • dumb questions: do you have your spring-security.xml configured and in the correct location? - do you have the necessary JAR files added to your application's war file? – blurfus Dec 22 '14 at 19:09
  • Hi thanks for your comment, I included spring-security-web, spring-security-core and spring-security-config (3.2.3.RELEASE the three of them) in the pom file. Spring security is configured in servlet-context.xml so I do not use a separate XML file. servlet-context.xml is in the default folder where it was created by STS – Sorbete Dec 22 '14 at 19:16
  • possible duplicate of [Spring security - org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined](http://stackoverflow.com/questions/14800523/spring-security-org-springframework-beans-factory-nosuchbeandefinitionexceptio) and [Spring Security: No bean named 'springSecurityFilterChain' is defined](http://stackoverflow.com/questions/27600899/spring-security-no-bean-named-springsecurityfilterchain-is-defined) – M. Deinum Dec 22 '14 at 19:17
  • 1
    The `DelegatingFilterProxy` can only access beans from the root context. Move your security configuration to the `root-context.xml`. – M. Deinum Dec 22 '14 at 19:17

0 Answers0