Skip to main content
Known Participant
August 13, 2014
Question

CF11 : cflogin doesn't "stuck" after session/login timeout

  • August 13, 2014
  • 6 replies
  • 6918 views

Hi,

Since migrating from CFMX7 to CF11 we are experiencing some weird failure with cflogin (using session or cookie storage).

Basically when we log-in on the application after a session/client timeout the first login doesn't last for longer than the login submit request.

The second login however is OK

I made a very simple application.cfc/index.cfm with short timeouts to check this:

<cfcomponent

output="false"

hint="I define the application settings and event handlers.">

        <!--- Define the application settings. --->

        <cfset this.name = hash( getCurrentTemplatePath() ) />

        <cfset this.applicationTimeout = createTimeSpan( 0, 0, 10, 0 ) />

        <cfset this.sessionTimeout = createTimeSpan( 0, 0, 0, 10 ) />

        <!--- Set up the application. --->

        <cfset THIS.SessionManagement = true />

        <cfset THIS.ClientManagement = true />

        <cfset THIS.SetClientCookies = true />

        <cfset THIS.loginStorage = "Session" />

        <cfset THIS.clientStorage = "sidys" />

        <!--- Define the request settings. --->

        <cfsetting showdebugoutput="false" />

        <cffunction

                name="OnRequestStart"

                access="public"

                returntype="boolean"

                output="true"

                hint="Fires at first part of page processing.">

             

                <!--- Define arguments. --->

                <cfargument

                name="TargetPage"

                type="string"

                required="true"

                />

                <cfset SetLocale("fr_FR") />

             

                <cfif IsDefined("Form.logout") or IsDefined("URL.logout")>

                        <cflogout />

                </cfif>

                <cflogin idletimeout="20">

                        <cfdump var="#Session#">

                        <cfinclude template="form.inc" />

<cfif not isDefined("cflogin") or (cflogin.name IS "" OR cflogin.password IS "")>

        <cfoutput>

                <form method="post">

                <b>login :</b>

                <input type="text" name="j_username" size="24" class="champ" />

                <b>passwordnbsp;:</b>

                <input type="password" name="j_password" size="15" class="champ" />

                <input type="submit" value="Login" class="button" name="submit" />

                </form>

        </cfoutput>

        <cfabort>

<cfelse>

        <cflock timeout="10" scope="Session" type="exclusive">

                <cfloginuser name="#cflogin.name#" Password="#cflogin.password#" roles="role">

                <cfset Session.id=cflogin.name />

        </cflock>

</cfif>

                </cflogin>

                <cfdump var="#Session#">

                <cfif GetAuthUser() NEQ "">

                        <cfoutput>

                                <form method="Post">

                                <input type="submit" Name="Logout" value="Logout">

                                </form>

                        </cfoutput>

                     

                </cfif>

             

                 <cfreturn true />

        </cffunction>

</cfcomponent>

    This topic has been closed for replies.

    6 replies

    mvierow
    Inspiring
    February 18, 2016

    Just wanted to jump in as a developer experiencing the same issue.

    In most of my applications I am handling authentication on my own, using CFID/CFTOKEN to access a session scope where I keep credentials, those are not affected. The ones where I decided to use isUserInRole()/isUserLoggedIn(), I am affected. So one work around is to manage your roles in the session scope instead of the roles attribute of cfloginuser. Create your own UDF to replace the two previous functions that instead accesses whatever you've placed in the session scope.

    Found this in security.log also. Time matches when I attempted to sign in:

    "Information","ajp-bio-8014-exec-7","02/18/16","10:31:15",,"An error occurred while fetching element from authcache."

    Known Participant
    January 28, 2016

    I hope this is resolved soon, I have several sites that started requiring you to log in twice at random due to upgrading to CF11.  I have Update 7.  I really don't want to have to go modify the code if it is just an update fix.

    CCPSWebmaster
    Participant
    June 16, 2015

    Other than in my example above:

    <cfloginuser name="#CFLOGIN.name##createUUID()#" password="#CFLOGIN.password#" roles="ROLES">


    Should fix the Double Login Issue. Although I am not sure if it creates any other issues.

    CCPSWebmaster
    Participant
    June 16, 2015

    I am having the same issue, but I noticed something very strange...

    Here is my Application.cfc

    <cfcomponent>

         <cfset This.name = "WebsiteCMS">

         <cfset This.applicationTimeout = "#createTimeSpan(5,0,0,0)#">

         <cfset This.datasource = "CMS">

         <cfset This.loginStorage = "session">

         <cfset This.Sessionmanagement = true>

         <cfset This.Sessiontimeout = "#createTimeSpan(0,0,0,10)#">

         <cfset This.mappings["/www"] = getDirectoryFromPath(getCurrentTemplatePath())>

         <!--- Application Starts --->

         <cffunction name="onApplicationStart">

              <cfset APPLICATION.DOMAIN = "http://localhost/website/">

              <cfset APPLICATION.DIRECTORY = "C:\inetpub\wwwroot\website\">

         </cffunction>

         <!--- A Page Request is made --->

         <cffunction name="onRequestStart" access="public">

              <cfargument type="string" name="targetPage" required="true">

              <cflogin idletimeout="#createTimeSpan(0,0,0,10)#">

                   <cfif IsDefined("CFLOGIN.name") and Len(Trim(CFLOGIN.name)) and Len(Trim(CFLOGIN.password))>

                        <!--- Check if User has Access --->

                        <cfif CFLOGIN.name is "USERWITHACCESS">

                             <!--- Check if User Exists --->

                             <cftry>

                                  //////////////////////////  LDAP Minified for obvious reasons //////////////////////////////

                                  <cfldap action="query"

                                       name="CheckIfUser"

                                  >

                                  <cfcatch type="any">

                                       <cfset LoginMessage = "Username or Password Incorrect">

                                  </cfcatch>

                             </cftry>

                             <cfif CheckIfUser.recordCount gt 0>

                                  <!--- If User Exists and HAS Access --->

                                  <!--- Authenticate user to check password --->

                                  <cftry>

                                       ///////////////////////////// LDAP Minified for obvious reasons //////////////////////////////

                                       <cfldap action="query"

                                            name="AuthenticateUser"

                                       >

                                       <cfset LoginMessage = "Success">

                                       <cfcatch type="any">

                                            <cfset LoginMessage = "Username or Password Incorrect">

                                       </cfcatch>

                                  </cftry>

                             </cfif>

                             <!--- If User authentication succeeded --->

                             <cfif LoginMessage is "Success">

                                  <cfloginuser name="#CFLOGIN.name##createUUID()#" password="password" roles="user">

                             <cfelse>

                                  <cfinclude template="loginForm.cfm"><cfabort>

                             </cfif>

                        <cfelse>

                             <!--- User Does NOT have access --->

                             <cfset LoginMessage = "You do not have access to this System">

                             <cfinclude template="loginForm.cfm"><cfabort>

                        </cfif>

                   <cfelse>

                        <!---#### they didn't fill out form, return to the login form. ####--->

                        <cfinclude template="loginForm.cfm"><cfabort>

                   </cfif>

              </cflogin>

         </cffunction>

    </cfcomponent>

    Please take note of the <cfloginuser> line:

    <cfloginuser name="#CFLOGIN.name##createUUID()#" password="password" roles="user">


    I was attempting to force each login to be unique to see if it was a SESSION causing the issue.


    I login and refresh the page a couple of times, but then something interesting happened.


    I was greated with the login screen with the error message:

    "You do not have access to this System"


    What this means is that for some reason the CFLOGIN.name and CFLOGIN.password fields were resent to the server. However because this message came up that means the userID was NOT "USERWITHACCESS"


    So to test my theory I modified the alert message:

    <cfset LoginMessage = "You do not have access to this System " & CFLOGIN.name>


    SURE ENOUGH this is what I got:

    You do not have access to this System USERWITHACCESS17E0C4A160-EAEB-5C23-FDF8DB569F65D3C2


    What this means is the <cfloginuser> tag is resubmitting the CFLOGIN variables.

    So I logged in again, and started refeshing the page to keep the <cflogin> timeout from firing.

    I Timed it. I get that error at Exactly 10 Seconds after I log in which is the Timeout I have set for the SESSION Variables.

    It seems like when the SESSION variable times out but the <cflogin> has not coldfusion resubmits the Login information that was stored in the <cfloginuser> tag. However the User is retaining the OLD Session ID instead of being re-assigned to the new ID.

    Can anyone else verify my logic?

    Also the only reason I have the <cfif CFLOGIN.name is "USERWITHACCESS"> in there is because of a last minute "Hey we only want these people to have access!" And we have yet to create the Group on our AD server (to check with LDAP) So it was quickly thrown in there. Which luckily caused me to notice this!

    itisdesign
    Inspiring
    May 17, 2015

    Hi Benoit,

    I believe 3732198 resolved the java.lang.NullPointerException in CF10 Update 14.  I've added the following comment to 3839458:

    -----------

    Another workaround is duplicate the <cflogin>/cflogin(). Example:

    <cflogin ..>

    <cflogin ..>

    When both have allowconcurrent=true (the default), then both will run. isUserLoggedIn() returns YES after the 1st, but the 1st login actually fails. The 2nd runs and logs in correctly.

    Repro attached as Application.cfc

    When THIS.loginStorage="cookie", then the issue does not reoccur if an old cfauthorization cookie is still present.

    -----------

    Thanks!,

    -Aaron

    BKBK
    Community Expert
    Community Expert
    August 14, 2014

    <cfset this.name = hash( getCurrentTemplatePath() ) />

    Problematic, as the application's name changes per page request. Sessions are dependent on the application name. Therefore, the session will break whenever the template path changes.

    To verify this hypothesis, test it with

            <cfset this.name = hash("test string") />

    <cfset this.applicationTimeout = createTimeSpan(1,0,0,0) />

    <cfset this.sessionTimeout = createTimeSpan(0,0,20,0 ) />

    silmarilAuthor
    Known Participant
    August 14, 2014

    Well no, actually the TemplatePath() is the path to Application.cfc in this case. It's an example taken from bennadel.com blog, but i also did try a fixed application name, it doesn't change anything.

    Also: this exact same application behave correctly on a BlueDragon 7.1 server.

    Using loginStorage="Cookie" on CF11 however seem a bit better, but there are some weirdness occasionnaly.

    silmarilAuthor
    Known Participant
    August 17, 2014

    I have discovered the cause of the issue. When I examined the logs, I found that the tests I performed generated many errors in coldfusion-out.log and security.log. The error message was "An error occurred while fetching element from authcache".

    Looking further, I found that what you and I observed was in fact the expected behaviour. It is all due to the new security enhancements since Coldfusion 10. If you follow this link, you will read:

    "Now you can have only one active session open for one user for a given application that uses the cflogin tag."


    This tells you that, from Coldfusion 10 onwards, cflogin can only store one username-password set per session. So, imagine that the session is still active, and the current login has just timed out. When you now attempt a second login, comprising a username-password pair distinct from the first, Coldfusion will log you out.

    This gives me a clue as to why it was difficult for me to reproduce the issue. I kept using the same username-password pair, which is allowed by the security enhancements. According to this hypothesis, you could readily reproduce the issue because you tested with varying login credentials.  





    I do see the error fetching from authcache but i do use the same login/password on the tests sequences, and also on our production application we don't have any other choice that using the same login/password.

    However i did one check, as i said before CF11 has added the tag "allowConcurrent" to tweak the multi-login problem, and if i switch to 'allowConcurrent="false"' which seem to be the previous comportement from CF10 then if the session timeout before the login there is no problem.

    If i change it back to the default "allowConcurrent='true'" then it start failing again.

    Also the authcache errors doesn't seem to be 100% related to the failure since the message doesn't happen all the time