Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have written custom UserDetailsService to validate user from database.First time it is working fine but when same user try to login after logout second time it is giving error.my application is based on Spring 3.1 , Spring security with Pretty faces on tomcat 7

org.springframework.security.authentication.BadCredentialsException: Bad credentials

here is my configuration details web.xml

<?xml version="1.0" encoding="UTF-8"?>
<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_2_5.xsd"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     version="2.5" metadata-complete="true">

<!-- 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/application-context.xml,
        /WEB-INF/spring/application-context-security.xml
    </param-value>
</context-param>

<context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>redmond</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>

<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<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>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

<!-- 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/application-context.xml,
            /WEB-INF/spring/application-context-security.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/jcsb</url-pattern>
</servlet-mapping>

     <!-- Pretty Face -->
<filter>
    <filter-name>Pretty Filter</filter-name>
    <filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Pretty Filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>

</filter-mapping>

<context-param>
    <param-name>facelets.DEVELOPMENT</param-name>
    <param-value>true</param-value>
</context-param>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<error-page>
    <exception-type>org.springframework.security.access.AccessDeniedException</exception-type>
    <location>/login.xhtml</location>
</error-page>

<session-config>
    <session-timeout>10</session-timeout>
</session-config>

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/index.html</location>
</error-page>

application-context.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:beans="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="com.swift.jcbs.web" />
<tx:annotation-driven />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="view">
                <bean class="com.suraj.jcbs.web.spring.ViewScope"/>
            </entry>
        </map>
    </property>
</bean>

application-context-security.xml

   <?xml version="1.0" encoding="UTF-8"?>
   <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:faces="http://www.springframework.org/schema/faces"
   xmlns:int-security="http://www.springframework.org/schema/integration/security"
   xmlns:tx="http://www.springframework.org/schema/tx" 
   xmlns:sec="http://www.springframework.org/schema/security"
   xsi:schemaLocation="http://www.springframework.org/schema/integration/security http://www.springframework.org/schema/integration/security/spring-integration-security-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/faces http://www.springframework.org/schema/faces/spring-faces-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<sec:global-method-security
    secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled">      
</sec:global-method-security>

    <!-- 
resource security 

Note: 
Access-denied-page is invoked when user is AUTHENTICATED but is not AUTHORIZED to access protected resources.
When user is NOT AUTHENTICATED, he is moved into form-login instead of access-denied-page.
-->
<sec:http access-denied-page="/access_denied.xhtml" use-expressions="true" auto-config="true" >
    <sec:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <sec:form-login login-page="/login.jsf"/>
    <sec:intercept-url pattern="/secured/**" access="isAuthenticated()"/>
    <sec:intercept-url pattern="/WEB-INF/faces/**" access="isAuthenticated()"/>

    <sec:logout logout-url="/facebook.stackoverflow.com/logout" logout-success-url="/facebook.stackoverflow.com/secured/home" delete-cookies="JSESSIONID" />
    <sec:session-management invalid-session-url="/facebook.stackoverflow.com/secured/home"> 
        <sec:concurrency-control error-if-maximum-exceeded="true" max-sessions="6"/>
    </sec:session-management>
</sec:http>


<!-- 
manager responsible for loading user account with assigned roles 
-->
<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider
        user-service-ref="userVerificationService"/>
</sec:authentication-manager>

  @Service
  public class UserVerificationService implements UserDetailsService {

private HashMap<String, org.springframework.security.core.userdetails.User> users = new HashMap<String, org.springframework.security.core.userdetails.User>();

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
    org.springframework.security.core.userdetails.User user = users.get(username);

    if (user == null) {
        throw new UsernameNotFoundException("UserAccount for name \""
                + username + "\" not found.");
    }

    return user;
}

@PostConstruct
public void init() {

    // sample roles     
    Collection<GrantedAuthority> adminAuthorities = new ArrayList<GrantedAuthority>();
    adminAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

    Collection<GrantedAuthority> userAuthorities = new ArrayList<GrantedAuthority>();
    adminAuthorities.add(new SimpleGrantedAuthority("ROLE_REGISTERED"));


    boolean enabled = true;
    boolean accountNonExpired = true;
    boolean credentialsNonExpired = true;
    boolean accountNonLocked = true;

    // sample users with roles set
    users.put("admin", new org.springframework.security.core.userdetails.User("admin", "admin", enabled, accountNonExpired,
            credentialsNonExpired, accountNonLocked, adminAuthorities));

    users.put("user", new org.springframework.security.core.userdetails.User("user", "user", enabled, accountNonExpired,
            credentialsNonExpired, accountNonLocked, userAuthorities));
}



 @Service
 public class AuthenticationServiceImpl implements AuthenticateService {

@Resource(name = "authenticationManager")
private AuthenticationManager authenticationManager;

public boolean login(String username, String password) {
    try {
        System.out.println("inside login");
         System.out.println("AuthenticationServiceImpl user name " +username +" Pass = "+password);
        Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
                username, password));
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        HttpUtils.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());

         return true;

    } catch (AuthenticationException e) {
        e.printStackTrace();
    }
    return false;
}

Here is my loginBean

   public String process() {

    System.out.println("user name " + username + " Pass = " + password);
    if (authenticateService.login(username, password)) {
        return "pretty:home";
    } else {
        FacesUtils.addErrorMessage("Invalid UserName or Password");
        return null;
    }
}
share|improve this question
add comment

1 Answer 1

From Spring 3.1 onwards, the User Credentials are being erased which usually causes some problems. I worked around this problem by turning off the said feature.

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <property name="eraseCredentialsAfterAuthentication" value="false"/>
</bean>

If you are using namespaces, you may use

<authentication-manager erase-credentials="false">
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.