Web Connection
Too Many Redirects based on Diverting to another page
Gravatar is a globally recognized avatar based on your email address. Too Many Redirects based on Diverting to another page
  Roy Miller
  All
  Sep 25, 2014 @ 02:44pm
List Mates,

I have users logging into the website using Rick's login process. The user then can go anywhere on the website. Cool!

Now, during this browsing, I want to check and see if for any reason I want to 'Kick' them out and redirect to a generic page. (beside using session management via the admin.asp)

So, I have tried doing this in the following locations with the same results

OnProcessComplete()
OnProcessInit()

When the logic hits, to redirect to another page is used with

Response.Redirect('mcglogin.mcg')

The code runs, but never just stop on the redirected page. Eventually the browser complains about having too many redirects

What are my options? How best to do this?

Should I consider killing the current session and then redirect?

Any help is appreciated ....

Roy


Gravatar is a globally recognized avatar based on your email address. Re: Too Many Redirects based on Diverting to another page
  Roy Miller
  Roy Miller
  Sep 25, 2014 @ 03:31pm
List Mates: Got it working

For those interested:

The solution was to kill the current session

session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')


List Mates,

I have users logging into the website using Rick's login process. The user then can go anywhere on the website. Cool!

Now, during this browsing, I want to check and see if for any reason I want to 'Kick' them out and redirect to a generic page. (beside using session management via the admin.asp)

So, I have tried doing this in the following locations with the same results

OnProcessComplete()
OnProcessInit()

When the logic hits, to redirect to another page is used with

Response.Redirect('mcglogin.mcg')

The code runs, but never just stop on the redirected page. Eventually the browser complains about having too many redirects

What are my options? How best to do this?

Should I consider killing the current session and then redirect?

Any help is appreciated ....

Roy

Gravatar is a globally recognized avatar based on your email address. Re: Too Many Redirects based on Diverting to another page
  Rick Strahl
  Roy Miller
  Sep 26, 2014 @ 12:15pm
You can't redirect ALL trafic to the login page - you have to exclude the login in page (and any other pages that shouldn't be redirected) otherwise when you try to go to login you get redirected again - resulting in the effect of a stack overflow :-)

Typically in OnProcessInit() you set up the logic that checks authentication and before you hit that code you check for specific pages you want to ignore.

It looks something like this:

FUNCTION OnProcessInit
LOCAL lcFile

THIS.InitSession("ttrak",3600,.t.)
Response.cStyleSheet = "~/css/westwind.css"

this.cPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))

*** Check for auth here but exclude default and logon pages
IF !INLIST(this.cPageFile,"default","logon") AND ;
!THIS.Authenticate("ANY")
RETURN .F.
ELSE
*** Always grab the authenticated user so we can show on default page as well
this.cAuthenticatedUser = Session.GetSessionVar(this.cAuthenticationUserSecurityKey)
this.cAuthenticatedUserName = Session.GetsessionVar("AuthenticatedUserName")
this.nAuthenticatedUserPk = VAL(Session.GetSessionVar("AuthenticatedUserPk"))
ENDIF

RETURN .T.
ENDFUNC

Note that I use the built-in automatic authentication here with Authenticate() call.

You can override that behavior by replacing with a check for whatever authentication rules you use (ie. checking a Session var etc) and then redirect to the login page on failure. But the concept is the same - you need to ignore the login page so you don't get into an endless redirect loop.

+++ Rick ---



List Mates,

I have users logging into the website using Rick's login process. The user then can go anywhere on the website. Cool!

Now, during this browsing, I want to check and see if for any reason I want to 'Kick' them out and redirect to a generic page. (beside using session management via the admin.asp)

So, I have tried doing this in the following locations with the same results

OnProcessComplete()
OnProcessInit()

When the logic hits, to redirect to another page is used with

Response.Redirect('mcglogin.mcg')

The code runs, but never just stop on the redirected page. Eventually the browser complains about having too many redirects

What are my options? How best to do this?

Should I consider killing the current session and then redirect?

Any help is appreciated ....

Roy



Rick Strahl
West Wind Technologies

Making waves on the Web
from Maui

Gravatar is a globally recognized avatar based on your email address. Re: Too Many Redirects based on Diverting to another page
  Roy Miller
  Rick Strahl
  Sep 27, 2014 @ 03:31pm
Rick,

Thanks ... But I seem stuck in a loop here ( no pun)

The following code works on my development computer as an exe or just running the prgs. However, when I push this the server in a live mode it does not work. Not that it doesn't work, it acts like it doesn't even hit the code in question ... Here's the code:

FUNCTION OnProcessInit
LOCAL lcFile

lcPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))
IF ! INLIST(UPPER(lcPageFile), 'LOGIN', 'LOGON', 'DEFAULT')
lcSessionCookieName = THIS.cSessionKey
lcSessionId = THIS.oRequest.GetCookie(lcSessionCookieName)
lcSessionCookieName = THIS.cSessionKey
Process.InitSession("")
session = this.osession
llvalidsession = THIS.oSession.IsValidSession(lcSessionId)
IF ! llValidSession
Response.Redirect('mcglogin.mcg')
ENDIF

IF llValidSession
l_cSubky = session.getsessionvar('subky')
IF ! EMPTY(l_cSubky)
l_nSelect = SELECT()
SELECT subscriber
LOCATE FOR subscriber.subky = l_cSubky
IF subscriber.maint = .t.
session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')
ENDIF
SELECT ( l_nSelect)
ENDIF
ENDIF
ENDIF

IF !This.Authenticate() && If they're not, a login form should appear
RETURN
ENDIF

ENDFUNC

The critical peace of code that does not seem to do anything when it is live on the server is

IF llValidSession
l_cSubky = session.getsessionvar('subky')
IF ! EMPTY(l_cSubky)
l_nSelect = SELECT()
SELECT subscriber
LOCATE FOR subscriber.subky = l_cSubky
IF subscriber.maint = .t.
session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')
ENDIF
SELECT ( l_nSelect)
ENDIF
ENDIF


I attempted to use your code below, modifying etc and I just can't seem to get it to work. When I want to boot a user out, the maintenance flag is set to true and the only way I was able to make headway was to issue the Endsession and then it works ... while only on the development computer

Thanks in Advance for your help


You can't redirect ALL trafic to the login page - you have to exclude the login in page (and any other pages that shouldn't be redirected) otherwise when you try to go to login you get redirected again - resulting in the effect of a stack overflow :-)

Typically in OnProcessInit() you set up the logic that checks authentication and before you hit that code you check for specific pages you want to ignore.

It looks something like this:

FUNCTION OnProcessInit
LOCAL lcFile

THIS.InitSession("ttrak",3600,.t.)
Response.cStyleSheet = "~/css/westwind.css"

this.cPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))

*** Check for auth here but exclude default and logon pages
IF !INLIST(this.cPageFile,"default","logon") AND ;
!THIS.Authenticate("ANY")
RETURN .F.
ELSE
*** Always grab the authenticated user so we can show on default page as well
this.cAuthenticatedUser = Session.GetSessionVar(this.cAuthenticationUserSecurityKey)
this.cAuthenticatedUserName = Session.GetsessionVar("AuthenticatedUserName")
this.nAuthenticatedUserPk = VAL(Session.GetSessionVar("AuthenticatedUserPk"))
ENDIF

RETURN .T.
ENDFUNC

Note that I use the built-in automatic authentication here with Authenticate() call.

You can override that behavior by replacing with a check for whatever authentication rules you use (ie. checking a Session var etc) and then redirect to the login page on failure. But the concept is the same - you need to ignore the login page so you don't get into an endless redirect loop.

+++ Rick ---



List Mates,

I have users logging into the website using Rick's login process. The user then can go anywhere on the website. Cool!

Now, during this browsing, I want to check and see if for any reason I want to 'Kick' them out and redirect to a generic page. (beside using session management via the admin.asp)

So, I have tried doing this in the following locations with the same results

OnProcessComplete()
OnProcessInit()

When the logic hits, to redirect to another page is used with

Response.Redirect('mcglogin.mcg')

The code runs, but never just stop on the redirected page. Eventually the browser complains about having too many redirects

What are my options? How best to do this?

Should I consider killing the current session and then redirect?

Any help is appreciated ....

Roy



Gravatar is a globally recognized avatar based on your email address. Re: Too Many Redirects based on Diverting to another page
  Rick Strahl
  Roy Miller
  Sep 27, 2014 @ 07:17pm
Roy,

I'm not sure - you're basically doing all the session management yourself which is tricky. Frankly I wouldn't do that. Call InitSession() on every request so it's always there. Then only set values in the session to maintain the login state. That way all you do to check is

lcUser = lcSession.GetSessionVar("loginUserName")
IF EMPTY(lcUser) and NOT INLIST(lcScriptName,"login","index")
Response.Redirect("Login.wcsx")
ENDIF

If you doing your own login logic that's by far the easiest.

However, the UserSecurity built-in authentication mechanism does all of this for you - it's probably easier to override this and just hook in your own authentication instead. Look at the OnAuthenticate() to authenticate and Web Connection can manage the whole thing.

You can override the default behavior several ways.

You can implement OnAuthenticateUser() and implement your custom authentication logic - use a custom business object, or data lookup - whatever.

You pass llNoForcedLogin = .T. in the call to Authenticate in which case you can implement your own custom form (which is what you're doing). From within the form, then call Process.OnAuthenticate to actually validate the user and follow the pattern in the base class to set the properties to the username or whatever you need. Once that's there you can check for that to determine whether the user is logged in. The main thing is that you need to set:

Session.SetSessionVar(Process.cAuthentionUserSecurityKey,lcUserName)

This is the key that Web Connection sets and that's really all that's needed.

Personally I tend to add a few custom properties to my process class that include userPk, userEmail, UserDisplayName etc. which I also store in the session so that I don't have to do a lookup on each request, but that's optional.

The best way to see how this works is to look at wwProcess::Authenticate (the UserSecurity mode) and the wwProcess::OnAuthenticate() methods.

Hope this helps,

+++ Rick ---


Rick,

Thanks ... But I seem stuck in a loop here ( no pun)

The following code works on my development computer as an exe or just running the prgs. However, when I push this the server in a live mode it does not work. Not that it doesn't work, it acts like it doesn't even hit the code in question ... Here's the code:

FUNCTION OnProcessInit
LOCAL lcFile

lcPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))
IF ! INLIST(UPPER(lcPageFile), 'LOGIN', 'LOGON', 'DEFAULT')
lcSessionCookieName = THIS.cSessionKey
lcSessionId = THIS.oRequest.GetCookie(lcSessionCookieName)
lcSessionCookieName = THIS.cSessionKey
Process.InitSession("")
session = this.osession
llvalidsession = THIS.oSession.IsValidSession(lcSessionId)
IF ! llValidSession
Response.Redirect('mcglogin.mcg')
ENDIF

IF llValidSession
l_cSubky = session.getsessionvar('subky')
IF ! EMPTY(l_cSubky)
l_nSelect = SELECT()
SELECT subscriber
LOCATE FOR subscriber.subky = l_cSubky
IF subscriber.maint = .t.
session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')
ENDIF
SELECT ( l_nSelect)
ENDIF
ENDIF
ENDIF

IF !This.Authenticate() && If they're not, a login form should appear
RETURN
ENDIF

ENDFUNC

The critical peace of code that does not seem to do anything when it is live on the server is

IF llValidSession
l_cSubky = session.getsessionvar('subky')
IF ! EMPTY(l_cSubky)
l_nSelect = SELECT()
SELECT subscriber
LOCATE FOR subscriber.subky = l_cSubky
IF subscriber.maint = .t.
session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')
ENDIF
SELECT ( l_nSelect)
ENDIF
ENDIF


I attempted to use your code below, modifying etc and I just can't seem to get it to work. When I want to boot a user out, the maintenance flag is set to true and the only way I was able to make headway was to issue the Endsession and then it works ... while only on the development computer

Thanks in Advance for your help


You can't redirect ALL trafic to the login page - you have to exclude the login in page (and any other pages that shouldn't be redirected) otherwise when you try to go to login you get redirected again - resulting in the effect of a stack overflow :-)

Typically in OnProcessInit() you set up the logic that checks authentication and before you hit that code you check for specific pages you want to ignore.

It looks something like this:

FUNCTION OnProcessInit
LOCAL lcFile

THIS.InitSession("ttrak",3600,.t.)
Response.cStyleSheet = "~/css/westwind.css"

this.cPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))

*** Check for auth here but exclude default and logon pages
IF !INLIST(this.cPageFile,"default","logon") AND ;
!THIS.Authenticate("ANY")
RETURN .F.
ELSE
*** Always grab the authenticated user so we can show on default page as well
this.cAuthenticatedUser = Session.GetSessionVar(this.cAuthenticationUserSecurityKey)
this.cAuthenticatedUserName = Session.GetsessionVar("AuthenticatedUserName")
this.nAuthenticatedUserPk = VAL(Session.GetSessionVar("AuthenticatedUserPk"))
ENDIF

RETURN .T.
ENDFUNC

Note that I use the built-in automatic authentication here with Authenticate() call.

You can override that behavior by replacing with a check for whatever authentication rules you use (ie. checking a Session var etc) and then redirect to the login page on failure. But the concept is the same - you need to ignore the login page so you don't get into an endless redirect loop.

+++ Rick ---



List Mates,

I have users logging into the website using Rick's login process. The user then can go anywhere on the website. Cool!

Now, during this browsing, I want to check and see if for any reason I want to 'Kick' them out and redirect to a generic page. (beside using session management via the admin.asp)

So, I have tried doing this in the following locations with the same results

OnProcessComplete()
OnProcessInit()

When the logic hits, to redirect to another page is used with

Response.Redirect('mcglogin.mcg')

The code runs, but never just stop on the redirected page. Eventually the browser complains about having too many redirects

What are my options? How best to do this?

Should I consider killing the current session and then redirect?

Any help is appreciated ....

Roy






Rick Strahl
West Wind Technologies

Making waves on the Web
from Maui

Gravatar is a globally recognized avatar based on your email address. Re: Too Many Redirects based on Diverting to another page
  Roy Miller
  Rick Strahl
  Sep 29, 2014 @ 05:05pm
Rick ... Thanks I will study this and reattempt. Thank you for your welcomed input


Roy,

I'm not sure - you're basically doing all the session management yourself which is tricky. Frankly I wouldn't do that. Call InitSession() on every request so it's always there. Then only set values in the session to maintain the login state. That way all you do to check is

lcUser = lcSession.GetSessionVar("loginUserName")
IF EMPTY(lcUser) and NOT INLIST(lcScriptName,"login","index")
Response.Redirect("Login.wcsx")
ENDIF

If you doing your own login logic that's by far the easiest.

However, the UserSecurity built-in authentication mechanism does all of this for you - it's probably easier to override this and just hook in your own authentication instead. Look at the OnAuthenticate() to authenticate and Web Connection can manage the whole thing.

You can override the default behavior several ways.

You can implement OnAuthenticateUser() and implement your custom authentication logic - use a custom business object, or data lookup - whatever.

You pass llNoForcedLogin = .T. in the call to Authenticate in which case you can implement your own custom form (which is what you're doing). From within the form, then call Process.OnAuthenticate to actually validate the user and follow the pattern in the base class to set the properties to the username or whatever you need. Once that's there you can check for that to determine whether the user is logged in. The main thing is that you need to set:

Session.SetSessionVar(Process.cAuthentionUserSecurityKey,lcUserName)

This is the key that Web Connection sets and that's really all that's needed.

Personally I tend to add a few custom properties to my process class that include userPk, userEmail, UserDisplayName etc. which I also store in the session so that I don't have to do a lookup on each request, but that's optional.

The best way to see how this works is to look at wwProcess::Authenticate (the UserSecurity mode) and the wwProcess::OnAuthenticate() methods.

Hope this helps,

+++ Rick ---


Rick,

Thanks ... But I seem stuck in a loop here ( no pun)

The following code works on my development computer as an exe or just running the prgs. However, when I push this the server in a live mode it does not work. Not that it doesn't work, it acts like it doesn't even hit the code in question ... Here's the code:

FUNCTION OnProcessInit
LOCAL lcFile

lcPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))
IF ! INLIST(UPPER(lcPageFile), 'LOGIN', 'LOGON', 'DEFAULT')
lcSessionCookieName = THIS.cSessionKey
lcSessionId = THIS.oRequest.GetCookie(lcSessionCookieName)
lcSessionCookieName = THIS.cSessionKey
Process.InitSession("")
session = this.osession
llvalidsession = THIS.oSession.IsValidSession(lcSessionId)
IF ! llValidSession
Response.Redirect('mcglogin.mcg')
ENDIF

IF llValidSession
l_cSubky = session.getsessionvar('subky')
IF ! EMPTY(l_cSubky)
l_nSelect = SELECT()
SELECT subscriber
LOCATE FOR subscriber.subky = l_cSubky
IF subscriber.maint = .t.
session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')
ENDIF
SELECT ( l_nSelect)
ENDIF
ENDIF
ENDIF

IF !This.Authenticate() && If they're not, a login form should appear
RETURN
ENDIF

ENDFUNC

The critical peace of code that does not seem to do anything when it is live on the server is

IF llValidSession
l_cSubky = session.getsessionvar('subky')
IF ! EMPTY(l_cSubky)
l_nSelect = SELECT()
SELECT subscriber
LOCATE FOR subscriber.subky = l_cSubky
IF subscriber.maint = .t.
session.endSession(lcSessionid)
Response.Redirect('mcglogin.mcg')
ENDIF
SELECT ( l_nSelect)
ENDIF
ENDIF


I attempted to use your code below, modifying etc and I just can't seem to get it to work. When I want to boot a user out, the maintenance flag is set to true and the only way I was able to make headway was to issue the Endsession and then it works ... while only on the development computer

Thanks in Advance for your help


You can't redirect ALL trafic to the login page - you have to exclude the login in page (and any other pages that shouldn't be redirected) otherwise when you try to go to login you get redirected again - resulting in the effect of a stack overflow :-)

Typically in OnProcessInit() you set up the logic that checks authentication and before you hit that code you check for specific pages you want to ignore.

It looks something like this:

FUNCTION OnProcessInit
LOCAL lcFile

THIS.InitSession("ttrak",3600,.t.)
Response.cStyleSheet = "~/css/westwind.css"

this.cPageFile = lower(JUSTFNAME(Request.GetPhysicalPath()))

*** Check for auth here but exclude default and logon pages
IF !INLIST(this.cPageFile,"default","logon") AND ;
!THIS.Authenticate("ANY")
RETURN .F.
ELSE
*** Always grab the authenticated user so we can show on default page as well
this.cAuthenticatedUser = Session.GetSessionVar(this.cAuthenticationUserSecurityKey)
this.cAuthenticatedUserName = Session.GetsessionVar("AuthenticatedUserName")
this.nAuthenticatedUserPk = VAL(Session.GetSessionVar("AuthenticatedUserPk"))
ENDIF

RETURN .T.
ENDFUNC

Note that I use the built-in automatic authentication here with Authenticate() call.

You can override that behavior by replacing with a check for whatever authentication rules you use (ie. checking a Session var etc) and then redirect to the login page on failure. But the concept is the same - you need to ignore the login page so you don't get into an endless redirect loop.

+++ Rick ---



List Mates,

I have users logging into the website using Rick's login process. The user then can go anywhere on the website. Cool!

Now, during this browsing, I want to check and see if for any reason I want to 'Kick' them out and redirect to a generic page. (beside using session management via the admin.asp)

So, I have tried doing this in the following locations with the same results

OnProcessComplete()
OnProcessInit()

When the logic hits, to redirect to another page is used with

Response.Redirect('mcglogin.mcg')

The code runs, but never just stop on the redirected page. Eventually the browser complains about having too many redirects

What are my options? How best to do this?

Should I consider killing the current session and then redirect?

Any help is appreciated ....

Roy






© 1996-2024