igriffiths / pwm

Automatically exported from code.google.com/p/pwm
0 stars 0 forks source link

AgreesiveURLParsing feature seems missing in new 1.5.1 build (was present in last 1.4.1 build) #18

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

Configure Access Manager's Password Expiration servlet URL to redirect to PWM 
along with the LogoutURL and forceAuth query string params that would customize 
the logout location and tell the IDP to re-prompt the user for authentication. 
Instead, it just sends me to the static logoutURL specified in the PWM config 
XML file, ignoring the custom logout location provided in the URL by NAM when 
the user first accesses PWM.

NAM Password Expiration servlet looks like this: 
https://pwm.mycompany.com/pwm/private/ChangePassword?passwordExpired=true&forceA
uth=TRUE&logoutURL=<RETURN_URL>

Works fine in 1.4.3 b922, but seemingly broken now in 1.5.1 b975.

What version of the product are you using? On what operating system?

1.5.1 (b975)
Server: SLES 11 64 bit, fully patched; Tomcat 6.0.29; JDK 1.6.21

Original issue reported on code.google.com by stefan.e...@gmail.com on 25 Aug 2010 at 9:43

GoogleCodeExporter commented 9 years ago
Try URLEncoding the value.

Original comment by jrivard on 15 Sep 2010 at 3:12

GoogleCodeExporter commented 9 years ago
Hi Jason,

I URL encoded our Password Expiration servlet URL in NAM from:

https://pwm.mycompany.com/pwm/private/ChangePassword?passwordExpired=true&forceA
uth=TRUE&logoutURL=<RETURN_URL>

To:

https://pwm.mycompany.com/pwm/private/ChangePassword?passwordExpired%3dtrue%26fo
rceAuth%3dTRUE%26logoutURL%3d%3cRETURN_URL%3e

But it had no effect. Is it possible to re-institute the AgressiveURLParsing 
feature present in past releases?

Original comment by stefan.e...@gmail.com on 21 Sep 2010 at 5:55

GoogleCodeExporter commented 9 years ago
It's possible to re-add the feature, but I'd like to avoid it if possible, It 
caused another issue with session verification.  

Can you post a trace of the PWM log at TRACE level when it first sees that URL?

Original comment by jrivard on 21 Sep 2010 at 6:43

GoogleCodeExporter commented 9 years ago
Looks like TRACE is on by default in this 1.5.1 build of PWM.

However, I do not see any good details in the log as the user logs in with that 
URLencoded version of the URL; only one line is created in the catalina.out:

2010-09-23 15:59:01, DEBUG, pwm.ContextManager, successfully initialized 
default log4j config at log level TRACE

...

INFO: Server startup in 3114 ms
2010-09-23 16:01:02, INFO , pwm.AuthenticationFilter, {26,qtest2} successful 
ssl authentication for cn=qtest2,ou=OUR-OU,o=OUR-O (287ms) 
[xxx.xxx.xxx.xxx/NAM-proxy.mycompany.com]

Original comment by stefan.e...@gmail.com on 23 Sep 2010 at 8:08

GoogleCodeExporter commented 9 years ago
I'm still unclear what the role of the <RETURN_URL> string is.  

I tried this URL set in the IDM user app "Forgotten Password Link" setting:

http://172.17.2.91:8080/pwm/public/ForgottenPassword?logoutURL=http%3A%2F%2F172.
17.2.91%3A8080%2FIDM%2Fjsps%2Flogin%2FLogin.jsp&forwardURL=http%3A%2F%2F172.17.2
.91%3A8080%2FIDM%2Fjsps%2Flogin%2FLogin.jsp

Which produced this pwm trace:

2010-09-24 20:17:25,019 INFO  [STDOUT] (http-0.0.0.0-8080-9) 2010-09-24 
20:17:25, TRACE, pwm.SessionFilter, {h} POST request for: 
/pwm/public/ForgottenPassword [172.17.2.1]
  logoutURL='http://172.17.2.91:8080/IDM/jsps/login/Login.jsp'
  forwardURL='http://172.17.2.91:8080/IDM/jsps/login/Login.jsp'
  rtnaddr='http://172.17.2.91:8080/IDM'
2010-09-24 20:17:25,020 INFO  [STDOUT] (http-0.0.0.0-8080-9) 2010-09-24 
20:17:25, TRACE, pwm.SessionFilter, {h} decoded value for forwardURL to 
http://172.17.2.91:8080/IDM/jsps/login/Login.jsp [172.17.2.1]
2010-09-24 20:17:25,020 INFO  [STDOUT] (http-0.0.0.0-8080-9) 2010-09-24 
20:17:25, DEBUG, pwm.SessionFilter, {h} forwardURL parameter detected in 
request, setting session forward url to 
http://172.17.2.91:8080/IDM/jsps/login/Login.jsp [172.17.2.1]
2010-09-24 20:17:25,021 INFO  [STDOUT] (http-0.0.0.0-8080-9) 2010-09-24 
20:17:25, TRACE, pwm.SessionFilter, {h} decoded value for logoutURL to 
http://172.17.2.91:8080/IDM/jsps/login/Login.jsp [172.17.2.1]
2010-09-24 20:17:25,025 INFO  [STDOUT] (http-0.0.0.0-8080-9) 2010-09-24 
20:17:25, DEBUG, pwm.SessionFilter, {h} logoutURL parameter detected in 
request, setting session logout url to 
http://172.17.2.91:8080/IDM/jsps/login/Login.jsp [172.17.2.1]

Seems to have picked up the logoutURL/forwardURL normally.  It's POSTing 
instead of GETing, but PWM treats POST/GET the same.  The UserApp added rtnaddr 
parameter is ignored. You can also see the updated session values for 
logoutURL/fowardURL at the /pwm/private/userinfo.jsp page.

What am I missing?

Original comment by jrivard on 24 Sep 2010 at 8:21

GoogleCodeExporter commented 9 years ago
From the Novell Access Manager 3.1 SP2 documentation, Identity Server guide:

3.4.1 Using a Password Expiration Service

URL Parameters
When you are defining the URL for the password service on the Contracts page, 
the following optional tags can be used in the parameter definitions of the 
URL. You need to use parameter names that are understood by the service you 
have selected to use. The Identity Server does not need to understand these 
parameters, but the password expiration service needs to understand them.

The table below lists a few common ones. Your service might or might not use 
these, and might require others.

Parameter
 Description

<USERID> 
 Provides the DN of the user with a password that is expired or expiring.

<STOREID> 
 Provides the name of the user store that authenticated the user before redirecting the user to the password expiration service.

<RETURN_URL> 
 Provides the URL at the Identity Server to which the user can be redirected after the password service completes.

action=expire 
 Causes the password expiration service to behave as though the user’s password policy is set to allow the user to reset the password even though the user’s policy might be set to show the user a hint. The user sees the page to create a new password rather than seeing a hint for an existing password.

Original comment by stefan.e...@gmail.com on 29 Oct 2010 at 6:46

GoogleCodeExporter commented 9 years ago
Sorry, I meant to add that <RETURN_URL> is a special keyword you intruct the 
NAM Identity Server's contract... such that when a user logs in against that 
resource and their password is expired, it will send the user the configured 
Password Expiration servlet URL -- and if this "<RETURN_URL>" keyword is 
included, then NAM will substitute into the Password URL the value of the 
location the end-user was trying to access prior to being interrupted because 
their password expired.

So this is what will tell something like PWM how to get back to where the user 
wanted to originally go before they were sent over to PWM (or whatever password 
expiration service), once the user has completed changing their password.

Original comment by stefan.e...@gmail.com on 29 Oct 2010 at 6:51

GoogleCodeExporter commented 9 years ago
We've also had problems with the same thing.

We discovered that the function debugHttpRequest (in Helper.java ) 
parses/outputs the correct logoutURL and passwordExpired values, but in 
SessionFilter.java the post-data is lost in the subsequent GET "redirect" that 
is enforced by PWM (because according to PWM there is no valid session at this 
point).

We ended up with a quick & dirty fix to copy the key parameters that Access 
Manager sends in the POST request. It is also very important to URL encode 
these parameters again as the <RETURN_URL> often includes a query string of 
it's own that is truncated if it is not re-encoded. The patch against 1.5.2 is 
attached. I doubt the patch is acceptable as-is but is there a more elegant 
solution to this?

Working:
2010-12-17 13:40:58, pwm.EventManager, {35} http session created
2010-12-17 13:40:58, pwm.SessionFilter, {35} GET request for: 
/pwm/private/ChangePassword [10.52.1.167/s1096.global.domain]
  logoutURL='http://www.google.com'
  passwordExpired=***removed***
2010-12-17 13:40:58, pwm.SessionFilter, {35} session has not been validated, 
redirecting with verification key to 
http://10.52.1.167/pwm/private/ChangePassword?passwordExpired=true&logoutURL=htt
p://www.google.com&session_verificiation_key=dzeHx5uxu2JTZXSzDmvyVfUeZl9hXqOEf89
270d812cf458f19a [10.52.1.167/s1096.global.domain]
2010-12-17 13:40:58, pwm.SessionFilter, {35} GET request for: 
/pwm/private/ChangePassword [10.52.1.167/s1096.global.domain]
  logoutURL='http://www.google.com'
  passwordExpired=***removed***
  session_verificiation_key='dzeHx5uxu2JTZXSzDmvyVfUeZl9hXqOEf89270d812cf458f19a'
2010-12-17 13:40:58, pwm.SessionFilter, {35} session validated, redirecting to 
original request url: 
http://10.52.1.167/pwm/private/ChangePassword?passwordExpired=true&logoutURL=htt
p://www.google.com [10.52.1.167/s1096.global.domain]
2010-12-17 13:40:58, pwm.SessionFilter, {35} GET request for: 
/pwm/private/ChangePassword [10.52.1.167/s1096.global.domain]
  logoutURL='http://www.google.com'
  passwordExpired=***removed***
2010-12-17 13:40:58, pwm.SessionFilter, {35} decoded value for logoutURL to 
http://www.google.com [10.52.1.167/s1096.global.domain]
2010-12-17 13:40:58, pwm.SessionFilter, {35} logoutURL parameter detected in 
request, setting session logout url to http://www.google.com 
[10.52.1.167/s1096.global.domain]
2010-12-17 13:40:58, pwm.AuthenticationFilter, {35} user requested resource 
requiring authentication (/pwm/private/ChangePassword), but is not 
authenticated; redirecting to LoginServlet [10.52.1.167/s1096.global.domain]

Failed:
2010-12-17 13:20:16, pwm.EventManager, {31} http session created
2010-12-17 13:20:20, pwm.SessionFilter, {31} POST request for: 
/pwm/private/ChangePassword [10.52.4.40]
  logoutURL='http://www.google.com'
  passwordExpired=***removed***
2010-12-17 13:20:20, pwm.SessionFilter, {31} session has not been validated, 
redirecting with verification key to 
http://10.52.1.167/pwm/private/ChangePassword?session_verificiation_key=EvjxxqK6
UPagj3yWE7QKB382BNtuIf4bdcb0f0c612cf445fdac [10.52.4.40]
2010-12-17 13:20:25, pwm.SessionFilter, {31} GET request for: 
/pwm/private/ChangePassword [10.52.4.40]
  session_verificiation_key='EvjxxqK6UPagj3yWE7QKB382BNtuIf4bdcb0f0c612cf445fdac'
2010-12-17 13:20:25, pwm.SessionFilter, {31} session validated, redirecting to 
original request url: http://10.52.1.167/pwm/private/ChangePassword [10.52.4.40]
2010-12-17 13:20:30, pwm.SessionFilter, {31} GET request for: 
/pwm/private/ChangePassword (no params) [10.52.4.40]
2010-12-17 13:20:30, pwm.AuthenticationFilter, {31} user requested resource 
requiring authentication (/pwm/private/ChangePassword), but is not 
authenticated; redirecting to LoginServlet [10.52.4.40]

Original comment by oner...@gmail.com on 3 Feb 2011 at 1:38

Attachments:

GoogleCodeExporter commented 9 years ago
This is still a problem for us today on the latest PWM 1.6.0 code using NAM 3.1 
SP4. Any chance of it being fixed?

Original comment by stefan.e...@gmail.com on 16 Nov 2011 at 1:48

GoogleCodeExporter commented 9 years ago
From my point of view, this seems like a defect in NAM where it isn't 
URLEncoding the query string.  I have a NAM environment now to expierement so 
I'll explore this soon.

Original comment by jrivard on 17 Nov 2011 at 4:22

GoogleCodeExporter commented 9 years ago
Additionally, another aproach I've used with NAM is to _ignore_ the password 
expiration URL configuration setting altogether, and use a JSP scriptlet on the 
NAM login page to redirect _all_ traffic to PWM and then back to the original 
NAM URL.  The return URL can be properly encoded by the scriptlet.

This approach lets pwm catch expired passwords, pre-expired passwords and 
handle password warnings

Add the following to the nidp/login.jsp somewhere in between the <form> 
sections:

<%
// set these parameters as appropriate for your environment
final String pwmURL = "http://app1.mynam.org/pwm";
final String pwmCommand = "checkAll"; // could be "checkExpire", 
"checkResponses", "checkProfile" or "checkAll", see pwm documentation
final boolean debugMode = true;
String ctarget = null;

// do not modify the below code unless you know what you are doing.
String currentTarget = (String)request.getAttribute("target");
if (debugMode) {
out.write("<p>Current target: " + currentTarget + "</p>");
out.write("<p>Current ctarget: " + request.getAttribute("ctarget") + "</p>");
}
if (currentTarget != null && !currentTarget.contains(pwmURL)) {
final StringBuilder newURL = new StringBuilder();
newURL.append(pwmURL);
newURL.append("/private/CommandServlet");
newURL.append("?processAction=");
newURL.append(pwmCommand);
newURL.append("&forwardURL=");
newURL.append(java.net.URLEncoder.encode(currentTarget,"UTF-8"));
//request.setAttribute("target",null);
//session.setAttribute("target",);
ctarget = newURL.toString();
if (debugMode) {
out.write("<p>New target set to: " + newURL.toString() + "</p>");
}
} else if (debugMode) {
out.write("<p>Target already redirected to PWM, was not modified.</p>");
}
%>
<% if (ctarget != null) { %>
            <input type="hidden" name="ctarget" value="<%=ctarget%>">
<% } %>

Original comment by jrivard on 17 Nov 2011 at 5:43

GoogleCodeExporter commented 9 years ago
Hi Jason... haev you had a chance to experiment here with your NAM setup, as 
you mentioned in Comment 10?

Original comment by stefan.e...@gmail.com on 30 Nov 2011 at 10:21

GoogleCodeExporter commented 9 years ago
SVN revision 300 has a fix to accept POST values during session validation.

Original comment by jrivard on 30 Nov 2011 at 10:34

GoogleCodeExporter commented 9 years ago
In answer to comment 12, I've checked in the change to accept POST variables as 
NAM seems to do to the passsword expiration servlet URL.   For earlier 
versions, disabling session validation (in advanced) also fixes the problem.

However, I still can't see the point of setting the return URL.  It won't add 
force-Auth param to the return url, and trying to configure it to do that seems 
to break the forgotten password link altogether.  And even if it does work, the 
user has to retype username and password anyway, so I don't see the difference 
between logging them off anyway.

Original comment by jrivard on 30 Nov 2011 at 10:37

GoogleCodeExporter commented 9 years ago
Thanks, Jason.. I look forward to giving this a try at your next build release.

Original comment by stefan.e...@gmail.com on 1 Dec 2011 at 3:19

GoogleCodeExporter commented 9 years ago
Closing as outdated issue.  I think this has long been resolved, please open a 
new issue if this still a problem

Original comment by jrivard on 28 May 2013 at 3:46