Announcement Announcement Module
Collapse
No announcement yet.
Password changes not recognized (Acegi Security) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Password changes not recognized (Acegi Security)

    Hi Team,
    I have got a serious problem using Acegi Security Framework.

    I m using technology stack of Struts2, Acegi Security, JPA

    SecurityContextHolder is not recognising the change in the password of a user. I maintain my user credentials in the database. So i have configured my Spring Security Framework using AuthenticationProcessingFilter and datasource reading the database credentials.

    If i change my password from the front end form and then logout of my application and when attempted to login with the changed password, its thowing Bad Credentials exception.

    Only after restarting my server on which my application is deployed, then the new password, is reflected as a secured credential. How can i make my password change accepted dynamically without having to restart my server.

  • #2
    What does your full stack trace look like (please use the code tag)? You can view this by enabling debug logging. Are you using a custom AuthenticationProvider or UserDetailsService? Spring security uses whatever is returned by the AuthenticationManager (which uses AuthenticationProvider which might use UserDetailsService depending on your configuration). Are you caching the result of the call to the database?

    Comment


    • #3
      Password changes not recognized

      Hi Rob Winch,

      Im glad that you responded to my mail . But then i needed your help a bit more extensively so that i can get out of my problem immediately.

      applicationContext-acegi-security.xml:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
      <beans>
      <bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverM anagerDataSource">
      <property name="driverClassName">
      <value>oracle.jdbc.OracleDriver</value>
      </property>
      <property name="url">
      <value>jdbc:oracle:thin:@192.168.6.2:1521:IPORT</value>
      </property>
      <property name="username">
      <value>IPORTMAN</value>
      </property>
      <property name="password">
      <value>IPORTMAN</value>
      </property>
      </bean>
      <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
      <property name="filterInvocationDefinitionSource">
      <value><![CDATA[
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      PATTERN_TYPE_APACHE_ANT
      /**=concurrentSessionFilter,httpSessionContextInteg rationFilter,logoutFilter,authenticationProcessing Filter,securityContextHolderAwareRequestFilter,rem emberMeProcessingFilter,exceptionTranslationFilter ,filterInvocationInterceptor
      ]]></value>
      </property>
      </bean>

      <bean id="concurrentSessionFilter" class="org.acegisecurity.concurrent.ConcurrentSess ionFilter">
      <property name="sessionRegistry"><ref bean="sessionRegistry"/></property>
      <property name="expiredUrl" value="../"/>
      </bean>
      <!-- used by concurrentSessionFilter and concurrentSessionController -->

      <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContex tIntegrationFilter"/>

      <bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistr yImpl"/>

      <bean id="concurrentSessionController" class="org.acegisecurity.concurrent.ConcurrentSess ionControllerImpl">
      <property name="maximumSessions" value="100"/>
      <property name="exceptionIfMaximumExceeded" value="true" />
      <property name="sessionRegistry"><ref local="sessionRegistry"/></property>
      </bean>
      <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
      <constructor-arg value="/index.jsp?login=09"/> <!-- URL redirected to after logout -->
      <constructor-arg>
      <list>
      <ref bean="rememberMeServices"/>
      <bean class="org.acegisecurity.ui.logout.SecurityContext LogoutHandler"/>
      </list>
      </constructor-arg>
      </bean>
      <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationP rocessingFilter">
      <property name="authenticationManager" ref="authenticationManager"/>
      <property name="authenticationFailureUrl" value="/index.jsp?login=1"/>
      <property name="defaultTargetUrl" value="/Env/LoginCheck"/>
      <property name="filterProcessesUrl" value="/j_acegi_security_check"/>
      <property name="rememberMeServices" ref="rememberMeServices"/>
      </bean>

      <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHo lderAwareRequestFilter"/>

      <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeP rocessingFilter">
      <property name="authenticationManager" ref="authenticationManager"/>
      <property name="rememberMeServices" ref="rememberMeServices"/>
      </bean>

      <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFi lter">
      <property name="authenticationEntryPoint">
      <bean class="org.acegisecurity.ui.webapp.AuthenticationP rocessingFilterEntryPoint">
      <property name="loginFormUrl" value="/index.jsp?login=-1"/>
      <property name="forceHttps" value="true"/>
      </bean>
      </property>
      <property name="accessDeniedHandler">
      <bean class="org.acegisecurity.ui.AccessDeniedHandlerImp l">
      <property name="errorPage" value="/accessDenied.jsp"/>
      </bean>
      </property>
      </bean>

      <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecur ityInterceptor">
      <property name="authenticationManager" ref="authenticationManager"/>
      <property name="accessDecisionManager">
      <bean class="org.acegisecurity.vote.AffirmativeBased">
      <property name="allowIfAllAbstainDecisions" value="false"/>
      <property name="decisionVoters">
      <list>
      <bean class="org.acegisecurity.vote.RoleVoter"/>
      <bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
      </list>
      </property>
      </bean>
      </property>
      <property name="objectDefinitionSource"><ref local="myObjectDefinitionSource" /></property>

      </bean>

      <bean id="myObjectDefinitionSource" class="env.acegi.users.UrlPatternRolesDefinitionSo urce">
      <property name="uds" ref="userDetailsService"/>
      </bean>




      <bean id="userAuthDao" class = "env.acegi.usersauthorization.IptUsersAuthDAO" >

      </bean>

      <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedR ememberMeServices">
      <property name="userDetailsService" ref="userDetailsService"/>
      <property name="key" value="changeThis"/>
      </bean>

      <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager ">
      <property name="providers">
      <list>
      <ref local="daoAuthenticationProvider"/>
      <bean class="org.acegisecurity.providers.anonymous.Anony mousAuthenticationProvider">
      <property name="key" value="changeThis"/>
      </bean>
      <bean class="org.acegisecurity.providers.rememberme.Reme mberMeAuthenticationProvider">
      <property name="key" value="changeThis"/>
      </bean>
      </list>
      </property>
      <property name="sessionController"><ref bean="concurrentSessionController"/></property>
      </bean>
      <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenti cationProvider">
      <property name="userDetailsService" ref="userDetailsService"/>
      </bean>

      <!-- UserDetailsService is the most commonly frequently Acegi Security interface implemented by end users -->
      <bean id="userDetailsService" class="env.acegi.security.AcegiAuthentication">
      <property name="dataSource">
      <ref bean="dataSource"/>
      </property>
      </bean>

      <!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
      <bean id="loggerListener" class="org.acegisecurity.event.authentication.Logg erListener"/>

      </beans>

      and My objectDefinitionSource is implemented based on PathBasedFilterInvocationDefinitionMap as mentioned below:

      public class UrlPatternRolesDefinitionSource extends PathBasedFilterInvocationDefinitionMap {
      @Override
      @SuppressWarnings("finally")
      public ConfigAttributeDefinition lookupAttributes(String url){

      ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
      try{
      List<String> userlist = new ArrayList<String>();
      String username="";
      username = uds.getUname();

      if(!url.contains("dcode") && !url.contains("mcode") && !url.contains("cfgcode"))
      {
      configDefinition=null;
      return configDefinition;
      }

      if(username.equals("ADMIN"))
      {
      configDefinition=null;
      return configDefinition;
      }
      else
      {
      trimUrl(url);
      if(adcode)
      {
      ConfigAttribute config = new SecurityConfig("ROLE_"+username);
      return configDefinition;
      }
      for(String user : userlist)
      {
      ConfigAttribute config = new SecurityConfig("ROLE_"+user);
      configDefinition.addConfigAttribute(config);
      }
      }
      }
      }
      }// end of ELSE
      }// end of try

      catch(Exception e)
      {
      e.printStackTrace();
      configDefinition=null;
      }

      finally
      {
      return configDefinition;
      }

      }


      and my UserDetailService is implemented through JdbcDaoImpl
      please check the code below:

      public class AcegiAuthentication extends JdbcDaoImpl implements GrantedAuthority{

      @Override
      public UserDetails loadUserByUsername(String username) {
      try {
      uauthl = uauthd.findByUserName(username);

      this.uname = username;

      if(uauthl.size()==0){

      throw new UsernameNotFoundException(username);
      }

      System.out.println("im in this method");

      String queryString = "select model from IptUsers model where model.userName='"+username+"'";

      Query qry = manager.createQuery(queryString);

      System.out.println("the qur rewianasdfk " + qry);

      uauth=(IptUsers)qry.getSingleResult();

      urolesl=uauth.getIptUsersRoleses();

      int i = urolesl.size();
      if(i == 0)
      {
      return null;
      }

      GrantedAuthority ga[]= new GrantedAuthorityImpl[i];

      for(int j=0; j< urolesl.size();j++)
      {
      ga[j] =new GrantedAuthorityImpl(urolesl.get(j).getRoleName()) ;
      }
      return new CustomUser(uauth.getUserName(), uauth.getPassword(), true,ga);
      }

      finally{

      }
      }

      RobWinch please check the above code and give the me solution if possible with a code sample , to resolve my issue. I m badly in need of this solution. Please Rob help me timely. I appreciate you guys.

      Comment


      • #4
        You haven't answered all my original questions
        • What do the logs look like?
        • Can you provide the full stack trace for the Bad Credentials exception you mentioned in the first post? Please use the code tags for this (i.e. the # button)

        Additional questions/feedback
        • Please confirm that your UserDetailService is returning an updated User object with the new password. Spring security will use whatever you UserDetailsService is returning so the problem is likely in there. For example, are you certain that you are not accidentally creating a new user when you are changing the password? Writing some tests that ensure your data access is working before trying to integrate with Spring Security will probably make life easier for you.
        • It does not appear that your code is threadsafe. This appears to be the case because there are mutable member variables being used to create the return value of your methods. Since the UserDetailsService is shared, you should change these to be declared in your method not as member variables.
          Originally posted by ashil View Post
          public UserDetails loadUserByUsername(String username) {
          try {
          uauthl = uauthd.findByUserName(username);
        • It looks like your code is vulnerable to HQL injection attacks. Using parameters rather than string concatenation for queries will fix this.
          Originally posted by ashil View Post
          String queryString = "select model from IptUsers model where model.userName='"+username+"'";
        • In the future please use code tags (ie. the # button) when posting code or configuration as this makes the post a lot easier to read. You might consider using the edit button to add them to your previous post.
        • If possible I would recommend updating from Acegi to Spring Security 3.x (at minimum Spring Security 2.x) so you are not susceptible to this vulnerability.

        Comment

        Working...
        X