You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Steve <st...@sjlt.co.uk> on 2009/05/19 13:46:34 UTC

Accessing protected resources via a login page

Hi everyone,

 

I have an application that insists on a user being logged in before they can
access specific resources.

 

Currently, if a user who is not logged in, attempts to access these
resources, they are simply redirected to the login page. This works fine and
is implemented using an interceptor.

 

I now want to enhance this behaviour so that, on successful login, they are
forwarded to the original page requested. This means I need to save the
original URL requested, including arbitrary parameters, and forward to this
URL from the login page.

 

Can anyone advise on the best way to do this?

 

Cheers,

 

Steve


RE: Accessing protected resources via a login page

Posted by Steve <st...@sjlt.co.uk>.
Hi Stuart,

You're quite right. I'm not sure how I missed this as I actually logged the
output from getQueryString! Still, this has certainly simplified my code.

My interceptor calls setUrl on the action. This URL is then passed through a
<s:hidden> tag on the login form via a getUrl call. 

If the interceptor finds that the user is not logged in it aborts returning
"login". This is handled as follows: -

<global-results>
	  
	<result name="login" type="redirect">
    		/goLoginPage.action?url=${encodedUrl}
    	</result>
    	
</global-results>

Here I specifically encode the URL. My base action has the following getter
in addition to the normal getUrl and setUrl

public String getEncodedUrl () throws java.io.UnsupportedEncodingException 
{ 
	return java.net.URLEncoder.encode (url, "UTF-8"); 
}

Struts automatically decodes the parameters so no decoding method is
required.

Cheers,

Steve

-----Original Message-----
From: Stuart Ellidge [mailto:stuart.ellidge@adaptris.com] 
Sent: 20 May 2009 17:11
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

Hi Steve,

Glad to hear you got it working - just as an observation (and I really
haven't tested this to check, so it is a question), but would
HttpServletRequest.getQueryString() not have provided you with the original
parameters? So a combination of both getRequestURL and getQueryString could
have provided you with the complete request string.

Anyway, the real reason for responding is that I'm not sure what you mean
with when you mention the single parameter issue. At some stage soon I'll
probably be adding query string (parameter) support into our interceptor and
if you could post an example, I can file it away for future reference.

Thanks
Stuart


On 20/05/2009 17:00, "Steve" <st...@sjlt.co.uk> wrote:

Thanks to Stuart, Lukasz and Wes for your advice.

I decided to stick with a home-grown solution because I'm only interested in
GET's right now and I don't want the complexity of adding Spring into the
mix with EJB3, Struts and JPA already working well together. This is because
I haven't used Spring before.

It's all working now but Spring may have been a better option!

Stuart's code worked fine until I bought parameters into the mix.
Unfortunately getRequestURL () doesn't return the parameters and I couldn't
find any other method that did. Therefore I had to iterate through the
parameters map and rebuild the parameters part of the request URL.

This worked fine with a single parameter but failed with two or more
parameters. This turned out to be a known issue with the redirect result
when used with ${url}. In this case the returned string is not URL encoded
so the single url parameter gets split on the embedded &. I added an extra
method to the action (getEncodedURL ()) and then used ${encodedUrl}. This
worked fine as the parameters interceptor automatically decodes parameters.

Cheers,

Steve

-----Original Message-----
From: Stuart Ellidge [mailto:stuart.ellidge@adaptris.com]
Sent: 19 May 2009 16:56
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

Hi Steve,

What you are asking is relatively simple really - we implemented an
interceptor to capture the current request URL and store it in the current
value stack. We can subsequently reference it in our JSPs and use it in
forms in several places to enable us to redirect to the original page after
certain events occur. Here is the intercept method:

  public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
StringBuffer returnUrl = new StringBuffer(request.getRequestURL());
invocation.getStack().set("returnURL", returnUrl);    return
invocation.invoke();  }

In your example, you would add setUrl and getUrl methods to the login action
class and then use the ${returnURL} in your JSP to create the request
parameter / hidden input.

Also, don't forget about the ability to use OGNL within your results... so
your result could be of type "redirect" sending to a location of ${url}
(that being the parameter name in your example below, and resolving to
LoginAction.getUrl().

Regards
Stuart

p.s. the reason for using the interceptor, rather than just accessing the
request URL directly in the JSP is that by the time the JSP is rendered,
that URL points to the JSP itself, rather than the action.



On 19/05/2009 16:44, "Steve" <st...@sjlt.co.uk> wrote:

I would rather avoid using Acegi as I'm not using Spring. I'm using Struts 2
and EJB3.

I appreciate the Acegi can be used without Spring. But it still seems like
overkill to solve this one issue.

I was hoping to generate a call to login.action like
".../login.action?url=<complete request string>". I guess storing the
request string in the session would work just as well. Do you know the
easiest way to access the request string from an interceptor or action?

Many Thanks,

Steve

-----Original Message-----
From: Lukasz Lenart [mailto:lukasz.lenart@googlemail.com]
Sent: 19 May 2009 15:26
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

2009/5/19 Steve <st...@sjlt.co.uk>:
> Can anyone advise on the best way to do this?

Use Acegi, it has such functionality built-in or store request path in
session when redirecting to login page and after successful login,
read it from session and redirect to it. It should be achievable with
the same interceptor you created.


Regards
--
Lukasz
http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Accessing protected resources via a login page

Posted by Stuart Ellidge <st...@adaptris.com>.
Hi Steve,

Glad to hear you got it working - just as an observation (and I really haven't tested this to check, so it is a question), but would HttpServletRequest.getQueryString() not have provided you with the original parameters? So a combination of both getRequestURL and getQueryString could have provided you with the complete request string.

Anyway, the real reason for responding is that I'm not sure what you mean with when you mention the single parameter issue. At some stage soon I'll probably be adding query string (parameter) support into our interceptor and if you could post an example, I can file it away for future reference.

Thanks
Stuart


On 20/05/2009 17:00, "Steve" <st...@sjlt.co.uk> wrote:

Thanks to Stuart, Lukasz and Wes for your advice.

I decided to stick with a home-grown solution because I'm only interested in
GET's right now and I don't want the complexity of adding Spring into the
mix with EJB3, Struts and JPA already working well together. This is because
I haven't used Spring before.

It's all working now but Spring may have been a better option!

Stuart's code worked fine until I bought parameters into the mix.
Unfortunately getRequestURL () doesn't return the parameters and I couldn't
find any other method that did. Therefore I had to iterate through the
parameters map and rebuild the parameters part of the request URL.

This worked fine with a single parameter but failed with two or more
parameters. This turned out to be a known issue with the redirect result
when used with ${url}. In this case the returned string is not URL encoded
so the single url parameter gets split on the embedded &. I added an extra
method to the action (getEncodedURL ()) and then used ${encodedUrl}. This
worked fine as the parameters interceptor automatically decodes parameters.

Cheers,

Steve

-----Original Message-----
From: Stuart Ellidge [mailto:stuart.ellidge@adaptris.com]
Sent: 19 May 2009 16:56
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

Hi Steve,

What you are asking is relatively simple really - we implemented an
interceptor to capture the current request URL and store it in the current
value stack. We can subsequently reference it in our JSPs and use it in
forms in several places to enable us to redirect to the original page after
certain events occur. Here is the intercept method:

  public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
StringBuffer returnUrl = new StringBuffer(request.getRequestURL());
invocation.getStack().set("returnURL", returnUrl);    return
invocation.invoke();  }

In your example, you would add setUrl and getUrl methods to the login action
class and then use the ${returnURL} in your JSP to create the request
parameter / hidden input.

Also, don't forget about the ability to use OGNL within your results... so
your result could be of type "redirect" sending to a location of ${url}
(that being the parameter name in your example below, and resolving to
LoginAction.getUrl().

Regards
Stuart

p.s. the reason for using the interceptor, rather than just accessing the
request URL directly in the JSP is that by the time the JSP is rendered,
that URL points to the JSP itself, rather than the action.



On 19/05/2009 16:44, "Steve" <st...@sjlt.co.uk> wrote:

I would rather avoid using Acegi as I'm not using Spring. I'm using Struts 2
and EJB3.

I appreciate the Acegi can be used without Spring. But it still seems like
overkill to solve this one issue.

I was hoping to generate a call to login.action like
".../login.action?url=<complete request string>". I guess storing the
request string in the session would work just as well. Do you know the
easiest way to access the request string from an interceptor or action?

Many Thanks,

Steve

-----Original Message-----
From: Lukasz Lenart [mailto:lukasz.lenart@googlemail.com]
Sent: 19 May 2009 15:26
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

2009/5/19 Steve <st...@sjlt.co.uk>:
> Can anyone advise on the best way to do this?

Use Acegi, it has such functionality built-in or store request path in
session when redirecting to login page and after successful login,
read it from session and redirect to it. It should be achievable with
the same interceptor you created.


Regards
--
Lukasz
http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org



RE: Accessing protected resources via a login page

Posted by Steve <st...@sjlt.co.uk>.
Thanks to Stuart, Lukasz and Wes for your advice.

I decided to stick with a home-grown solution because I'm only interested in
GET's right now and I don't want the complexity of adding Spring into the
mix with EJB3, Struts and JPA already working well together. This is because
I haven't used Spring before.

It's all working now but Spring may have been a better option!

Stuart's code worked fine until I bought parameters into the mix.
Unfortunately getRequestURL () doesn't return the parameters and I couldn't
find any other method that did. Therefore I had to iterate through the
parameters map and rebuild the parameters part of the request URL.

This worked fine with a single parameter but failed with two or more
parameters. This turned out to be a known issue with the redirect result
when used with ${url}. In this case the returned string is not URL encoded
so the single url parameter gets split on the embedded &. I added an extra
method to the action (getEncodedURL ()) and then used ${encodedUrl}. This
worked fine as the parameters interceptor automatically decodes parameters.

Cheers,

Steve

-----Original Message-----
From: Stuart Ellidge [mailto:stuart.ellidge@adaptris.com] 
Sent: 19 May 2009 16:56
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

Hi Steve,

What you are asking is relatively simple really - we implemented an
interceptor to capture the current request URL and store it in the current
value stack. We can subsequently reference it in our JSPs and use it in
forms in several places to enable us to redirect to the original page after
certain events occur. Here is the intercept method:

  public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
StringBuffer returnUrl = new StringBuffer(request.getRequestURL());
invocation.getStack().set("returnURL", returnUrl);    return
invocation.invoke();  }

In your example, you would add setUrl and getUrl methods to the login action
class and then use the ${returnURL} in your JSP to create the request
parameter / hidden input.

Also, don't forget about the ability to use OGNL within your results... so
your result could be of type "redirect" sending to a location of ${url}
(that being the parameter name in your example below, and resolving to
LoginAction.getUrl().

Regards
Stuart

p.s. the reason for using the interceptor, rather than just accessing the
request URL directly in the JSP is that by the time the JSP is rendered,
that URL points to the JSP itself, rather than the action.



On 19/05/2009 16:44, "Steve" <st...@sjlt.co.uk> wrote:

I would rather avoid using Acegi as I'm not using Spring. I'm using Struts 2
and EJB3.

I appreciate the Acegi can be used without Spring. But it still seems like
overkill to solve this one issue.

I was hoping to generate a call to login.action like
".../login.action?url=<complete request string>". I guess storing the
request string in the session would work just as well. Do you know the
easiest way to access the request string from an interceptor or action?

Many Thanks,

Steve

-----Original Message-----
From: Lukasz Lenart [mailto:lukasz.lenart@googlemail.com]
Sent: 19 May 2009 15:26
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

2009/5/19 Steve <st...@sjlt.co.uk>:
> Can anyone advise on the best way to do this?

Use Acegi, it has such functionality built-in or store request path in
session when redirecting to login page and after successful login,
read it from session and redirect to it. It should be achievable with
the same interceptor you created.


Regards
--
Lukasz
http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Accessing protected resources via a login page

Posted by Wes Wannemacher <we...@wantii.com>.
On Tuesday 19 May 2009 05:05:11 pm dusty wrote:
> I think this is more difficult than most people think.  There are a lot of
> use cases and edge cases that make most home grown solutions pretty
> fragile. I think GETs are pretty easy but it gets a little more exciting
> when you are dealing with POSTs to a secure resource.  People tend to get
> pissed off if you lose their POST data and redirect them back to the form
> to start over.
>
> Spring Security handles this pattern quite well.  It is understandable that
> you are reluctant because you are not using Spring service wiring, but you
> can get robust Authentication and Authorization services with a little
> configuration.  The good news is your site will behave the way people
> expect it to.
>
> There are other issues like what happens when an AJAX request is sent for a
> secure resource after a session timeout, etc...
>

To second what dusty is saying, POSTs are not the only resources that can't be 
easily persisted across a login request. Another situation to think of is AJAX 
requests. I had a situation where someone would leave a search screen open and 
periodically put in a parameter, then click search. Since the whole operation 
happened via async request, if the session had timed out, then the login form 
would be retrieved by the async request. It made for an ugly results table 
since it didn't parse well. So, handrolling a solution works for GET requests, 
but just about anything else will go haywire. 

Bringing in ACEGI (now called Spring Security) is quite easy and Spring is 
mostly non-intrusive, so if you aren't using it anywhere else, it is no harm. 

-Wes


-- 

Wes Wannemacher
Author - Struts 2 In Practice 
Includes coverage of Struts 2.1, Spring, JPA, JQuery, Sitemesh and more
http://www.manning.com/wannemacher


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Accessing protected resources via a login page

Posted by dusty <du...@yahoo.com>.
I think this is more difficult than most people think.  There are a lot of
use cases and edge cases that make most home grown solutions pretty fragile. 
I think GETs are pretty easy but it gets a little more exciting when you are
dealing with POSTs to a secure resource.  People tend to get pissed off if
you lose their POST data and redirect them back to the form to start over.  

Spring Security handles this pattern quite well.  It is understandable that
you are reluctant because you are not using Spring service wiring, but you
can get robust Authentication and Authorization services with a little
configuration.  The good news is your site will behave the way people expect
it to.

There are other issues like what happens when an AJAX request is sent for a
secure resource after a session timeout, etc...  




Stuart Ellidge wrote:
> 
> Hi Steve,
> 
> What you are asking is relatively simple really - we implemented an
> interceptor to capture the current request URL and store it in the current
> value stack. We can subsequently reference it in our JSPs and use it in
> forms in several places to enable us to redirect to the original page
> after certain events occur. Here is the intercept method:
> 
>   public String intercept(ActionInvocation invocation) throws Exception {   
> HttpServletRequest request = ServletActionContext.getRequest();       
> StringBuffer returnUrl = new StringBuffer(request.getRequestURL());       
> invocation.getStack().set("returnURL", returnUrl);    return
> invocation.invoke();  }
> 
> In your example, you would add setUrl and getUrl methods to the login
> action class and then use the ${returnURL} in your JSP to create the
> request parameter / hidden input.
> 
> Also, don't forget about the ability to use OGNL within your results... so
> your result could be of type "redirect" sending to a location of ${url}
> (that being the parameter name in your example below, and resolving to
> LoginAction.getUrl().
> 
> Regards
> Stuart
> 
> p.s. the reason for using the interceptor, rather than just accessing the
> request URL directly in the JSP is that by the time the JSP is rendered,
> that URL points to the JSP itself, rather than the action.
> 
> 
> 
> On 19/05/2009 16:44, "Steve" <st...@sjlt.co.uk> wrote:
> 
> I would rather avoid using Acegi as I'm not using Spring. I'm using Struts
> 2
> and EJB3.
> 
> I appreciate the Acegi can be used without Spring. But it still seems like
> overkill to solve this one issue.
> 
> I was hoping to generate a call to login.action like
> ".../login.action?url=<complete request string>". I guess storing the
> request string in the session would work just as well. Do you know the
> easiest way to access the request string from an interceptor or action?
> 
> Many Thanks,
> 
> Steve
> 
> -----Original Message-----
> From: Lukasz Lenart [mailto:lukasz.lenart@googlemail.com]
> Sent: 19 May 2009 15:26
> To: Struts Users Mailing List
> Subject: Re: Accessing protected resources via a login page
> 
> 2009/5/19 Steve <st...@sjlt.co.uk>:
>> Can anyone advise on the best way to do this?
> 
> Use Acegi, it has such functionality built-in or store request path in
> session when redirecting to login page and after successful login,
> read it from session and redirect to it. It should be achievable with
> the same interceptor you created.
> 
> 
> Regards
> --
> Lukasz
> http://www.lenart.org.pl/
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Accessing-protected-resources-via-a-login-page-tp23614657p23623986.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Accessing protected resources via a login page

Posted by Stuart Ellidge <st...@adaptris.com>.
Hi Steve,

What you are asking is relatively simple really - we implemented an interceptor to capture the current request URL and store it in the current value stack. We can subsequently reference it in our JSPs and use it in forms in several places to enable us to redirect to the original page after certain events occur. Here is the intercept method:

  public String intercept(ActionInvocation invocation) throws Exception {    HttpServletRequest request = ServletActionContext.getRequest();        StringBuffer returnUrl = new StringBuffer(request.getRequestURL());        invocation.getStack().set("returnURL", returnUrl);    return invocation.invoke();  }

In your example, you would add setUrl and getUrl methods to the login action class and then use the ${returnURL} in your JSP to create the request parameter / hidden input.

Also, don't forget about the ability to use OGNL within your results... so your result could be of type "redirect" sending to a location of ${url} (that being the parameter name in your example below, and resolving to LoginAction.getUrl().

Regards
Stuart

p.s. the reason for using the interceptor, rather than just accessing the request URL directly in the JSP is that by the time the JSP is rendered, that URL points to the JSP itself, rather than the action.



On 19/05/2009 16:44, "Steve" <st...@sjlt.co.uk> wrote:

I would rather avoid using Acegi as I'm not using Spring. I'm using Struts 2
and EJB3.

I appreciate the Acegi can be used without Spring. But it still seems like
overkill to solve this one issue.

I was hoping to generate a call to login.action like
".../login.action?url=<complete request string>". I guess storing the
request string in the session would work just as well. Do you know the
easiest way to access the request string from an interceptor or action?

Many Thanks,

Steve

-----Original Message-----
From: Lukasz Lenart [mailto:lukasz.lenart@googlemail.com]
Sent: 19 May 2009 15:26
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

2009/5/19 Steve <st...@sjlt.co.uk>:
> Can anyone advise on the best way to do this?

Use Acegi, it has such functionality built-in or store request path in
session when redirecting to login page and after successful login,
read it from session and redirect to it. It should be achievable with
the same interceptor you created.


Regards
--
Lukasz
http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org



RE: Accessing protected resources via a login page

Posted by Steve <st...@sjlt.co.uk>.
I would rather avoid using Acegi as I'm not using Spring. I'm using Struts 2
and EJB3.

I appreciate the Acegi can be used without Spring. But it still seems like
overkill to solve this one issue.

I was hoping to generate a call to login.action like
".../login.action?url=<complete request string>". I guess storing the
request string in the session would work just as well. Do you know the
easiest way to access the request string from an interceptor or action?

Many Thanks,

Steve

-----Original Message-----
From: Lukasz Lenart [mailto:lukasz.lenart@googlemail.com] 
Sent: 19 May 2009 15:26
To: Struts Users Mailing List
Subject: Re: Accessing protected resources via a login page

2009/5/19 Steve <st...@sjlt.co.uk>:
> Can anyone advise on the best way to do this?

Use Acegi, it has such functionality built-in or store request path in
session when redirecting to login page and after successful login,
read it from session and redirect to it. It should be achievable with
the same interceptor you created.


Regards
-- 
Lukasz
http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Accessing protected resources via a login page

Posted by Lukasz Lenart <lu...@googlemail.com>.
2009/5/19 Steve <st...@sjlt.co.uk>:
> Can anyone advise on the best way to do this?

Use Acegi, it has such functionality built-in or store request path in
session when redirecting to login page and after successful login,
read it from session and redirect to it. It should be achievable with
the same interceptor you created.


Regards
-- 
Lukasz
http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org