Index: /trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 4728)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 4729)
@@ -4,5 +4,7 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.io.BufferedReader;
 import java.io.DataOutputStream;
+import java.io.InputStreamReader;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -17,4 +19,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import oauth.signpost.OAuth;
@@ -41,4 +45,10 @@
     private boolean canceled;
     private HttpURLConnection connection;
+
+    private class SessionId {
+        String id;
+        String token;
+        String userName;
+    }
 
     /**
@@ -192,5 +202,22 @@
     }
 
-    protected String extractOsmSession(HttpURLConnection connection) {
+    protected String extractToken(HttpURLConnection connection) {
+        try {
+            BufferedReader r = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            String c;
+            Pattern p = Pattern.compile(".*authenticity_token.*value=\"([^\"]+)\".*");
+            while((c = r.readLine()) != null) {
+                Matcher m = p.matcher(c);
+                if(m.find()) {
+                    return m.group(1);
+                }
+            }
+        } catch (IOException e) {
+            return null;
+        }
+        return null;
+    }
+
+    protected SessionId extractOsmSession(HttpURLConnection connection) {
         List<String> setCookies = connection.getHeaderFields().get("Set-Cookie");
         if (setCookies == null)
@@ -209,7 +236,14 @@
                     continue;
                 }
-                if (kv[0].equals("_osm_session"))
+                if (kv[0].equals("_osm_session")) {
                     // osm session cookie found
-                    return kv[1];
+                    String token = extractToken(connection);
+                    if(token == null)
+                        return null;
+                    SessionId si = new SessionId();
+                    si.id = kv[1];
+                    si.token = token;
+                    return si;
+                }
             }
         }
@@ -274,8 +308,8 @@
      * a cookie.
      *
-     * @return the session ID
+     * @return the session ID structure
      * @throws OsmOAuthAuthorizationException thrown if something went wrong
      */
-    protected String fetchOsmWebsiteSessionId() throws OsmOAuthAuthorizationException {
+    protected SessionId fetchOsmWebsiteSessionId() throws OsmOAuthAuthorizationException {
         try {
             StringBuilder sb = new StringBuilder();
@@ -290,5 +324,5 @@
             setHttpRequestParameters(connection);
             connection.connect();
-            String sessionId = extractOsmSession(connection);
+            SessionId sessionId = extractOsmSession(connection);
             if (sessionId == null)
                 throw new OsmOAuthAuthorizationException(tr("OSM website did not return a session cookie in response to ''{0}'',", url.toString()));
@@ -303,5 +337,35 @@
     }
 
-    protected void authenticateOsmSession(String sessionId, String userName, String password) throws OsmLoginFailedException {
+    /**
+     * Submits a request to the OSM website for a OAuth form. The OSM website replies a session token in
+     * a hidden parameter.
+     *
+     * @throws OsmOAuthAuthorizationException thrown if something went wrong
+     */
+    protected void fetchOAuthToken(SessionId sessionId, OAuthToken requestToken) throws OsmOAuthAuthorizationException {
+        try {
+            URL url = new URL(getAuthoriseUrl(requestToken));
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+            }
+            connection.setRequestMethod("GET");
+            connection.setDoInput(true);
+            connection.setDoOutput(false);
+            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId.id + "; _osm_username=" + sessionId.userName);
+            setHttpRequestParameters(connection);
+            connection.connect();
+            sessionId.token = extractToken(connection);
+            if (sessionId.token == null)
+                throw new OsmOAuthAuthorizationException(tr("OSM website did not return a session cookie in response to ''{0}'',", url.toString()));
+        } catch(IOException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        } finally {
+            synchronized(this) {
+                connection = null;
+            }
+        }
+    }
+
+    protected void authenticateOsmSession(SessionId sessionId, String userName, String password) throws OsmLoginFailedException {
         DataOutputStream dout = null;
         try {
@@ -320,4 +384,5 @@
             parameters.put("referer", "/");
             parameters.put("commit", "Login");
+            parameters.put("authenticity_token", sessionId.token);
 
             String request = buildPostRequest(parameters);
@@ -325,5 +390,5 @@
             connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
             connection.setRequestProperty("Content-Length", Integer.toString(request.length()));
-            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId);
+            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId.id);
             // make sure we can catch 302 Moved Temporarily below
             connection.setInstanceFollowRedirects(false);
@@ -360,5 +425,5 @@
     }
 
-    protected void logoutOsmSession(String sessionId) throws OsmOAuthAuthorizationException {
+    protected void logoutOsmSession(SessionId sessionId) throws OsmOAuthAuthorizationException {
         try {
             URL url = new URL(buildOsmLogoutUrl());
@@ -382,8 +447,10 @@
     }
 
-    protected void sendAuthorisationRequest(String sessionId, OAuthToken requestToken, OsmPrivileges privileges) throws OsmOAuthAuthorizationException {
+    protected void sendAuthorisationRequest(SessionId sessionId, OAuthToken requestToken, OsmPrivileges privileges) throws OsmOAuthAuthorizationException {
         Map<String, String> parameters = new HashMap<String, String>();
+        fetchOAuthToken(sessionId, requestToken);
         parameters.put("oauth_token", requestToken.getKey());
         parameters.put("oauth_callback", "");
+        parameters.put("authenticity_token", sessionId.token);
         if (privileges.isAllowWriteApi()) {
             parameters.put("allow_write_api", "yes");
@@ -417,5 +484,5 @@
             connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
             connection.setRequestProperty("Content-Length", Integer.toString(request.length()));
-            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId);
+            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId.id + "; _osm_username=" + sessionId.userName);
             connection.setInstanceFollowRedirects(false);
             setHttpRequestParameters(connection);
@@ -480,5 +547,6 @@
             monitor.setTicksCount(4);
             monitor.indeterminateSubTask(tr("Initializing a session at the OSM website..."));
-            String sessionId = fetchOsmWebsiteSessionId();
+            SessionId sessionId = fetchOsmWebsiteSessionId();
+            sessionId.userName = osmUserName;
             if (canceled)
                 throw new OsmTransferCanceledException();
