Upgrade OpenID provider dyuproject to 1.1.1

This version contains built-in support for Google Account discovery,
so we don't need to hack it ourselves anymore.

Unfortunately the authentication approach used by RelyingParty assumes
you want to do an HTTP redirect to start the authentication.  Instead
Gerrit2 wants to send JSON to the client with the redirect URL.  We
must therefore code a little bit more on our side to ensure the user
manager has saved its cookie.

The library now also includes a utility map to create a URL encoded
string; we use this rather than StringBuilder append calls to build
up any URL which contains query parameters.

I'm specifically not using the SReg support in the library as it does
a request for additional properties we aren't too interested in, like
the user's gender.  Instead we just keep our own implementation of the
SReg extension.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-01-19 12:10:35 -08:00
parent f4ab8d2f95
commit e0888d9c19
4 changed files with 35 additions and 92 deletions

View File

@@ -15,29 +15,33 @@
package com.google.gerrit.server;
import com.dyuproject.openid.OpenIdUser;
import com.dyuproject.openid.OpenIdUserManager;
import com.dyuproject.openid.RelyingParty;
import com.dyuproject.openid.manager.CookieBasedUserManager;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
public class GerritOpenIdUserManager extends OpenIdUserManager {
public class GerritOpenIdUserManager extends CookieBasedUserManager {
public GerritOpenIdUserManager() {
final int age = 2 * 60/* seconds */;
setCookieName("gerrit_openid");
setSecretKey("gerrit_openid");
setMaxAge(120);
setMaxAge(age);
setLoginTimeout(age);
setEncrypted(true);
}
@Override
public void init(Properties properties) {
}
@Override
public OpenIdUser getUser(final HttpServletRequest request)
throws IOException {
if (request.getParameter(RelyingParty.DEFAULT_PARAMETER) != null) {
if (request.getParameter(RelyingParty.DEFAULT_IDENTIFIER_PARAMETER) != null) {
return null;
}
return super.getUser(request);

View File

@@ -1,54 +0,0 @@
// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server;
import com.google.gerrit.client.openid.OpenIdUtil;
import com.dyuproject.openid.Discovery;
import com.dyuproject.openid.OpenIdContext;
import com.dyuproject.openid.OpenIdUser;
import java.util.HashMap;
import java.util.Map;
/** Discovery support for Google Accounts and other standard OpenID providers */
public class GoogleAccountDiscovery implements Discovery {
/** OpenID discovery end-point for Google Accounts */
public static final String GOOGLE_ACCOUNT = OpenIdUtil.URL_GOOGLE;
private final Discovery base;
public GoogleAccountDiscovery(final Discovery base) {
this.base = base;
}
public OpenIdUser discover(final String claimedId, final OpenIdContext context)
throws Exception {
if (GOOGLE_ACCOUNT.equals(claimedId)
|| claimedId.startsWith(GOOGLE_ACCOUNT + "?")) {
// TODO We shouldn't hard-code the XRDS discovery result.
//
final Map<String, String> m = new HashMap<String, String>();
m.put("ci", claimedId);
m.put("os", "https://www.google.com/accounts/o8/ud");
final OpenIdUser u = new OpenIdUser();
u.fromJSON(m);
return u;
}
return base.discover(claimedId, context);
}
}

View File

@@ -39,8 +39,8 @@ import com.dyuproject.openid.OpenIdContext;
import com.dyuproject.openid.OpenIdUser;
import com.dyuproject.openid.RelyingParty;
import com.dyuproject.openid.SimpleHttpConnector;
import com.dyuproject.openid.UrlEncodedParameterMap;
import org.mortbay.util.UrlEncoded;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -90,7 +90,7 @@ public class OpenIdLoginServlet extends HttpServlet {
try {
final OpenIdContext context = new OpenIdContext();
context.setAssociation(new DiffieHellmanAssociation());
context.setDiscovery(new GoogleAccountDiscovery(new DefaultDiscovery()));
context.setDiscovery(new DefaultDiscovery());
context.setHttpConnector(new SimpleHttpConnector());
relyingParty = new RelyingParty(context, new GerritOpenIdUserManager());
} catch (Throwable e) {
@@ -195,7 +195,8 @@ public class OpenIdLoginServlet extends HttpServlet {
return;
}
if (!relyingParty.associate(user, req, rsp)) {
if (!relyingParty.getOpenIdContext().getAssociation().associate(user,
relyingParty.getOpenIdContext())) {
// Failed association. Try again.
//
callback(req, rsp, SignInResult.CANCEL);
@@ -205,32 +206,35 @@ public class OpenIdLoginServlet extends HttpServlet {
// Authenticate user through his/her OpenID provider
//
final String realm = serverUrl(req);
final StringBuilder retTo = new StringBuilder(req.getRequestURL());
final UrlEncodedParameterMap retTo =
new UrlEncodedParameterMap(req.getRequestURL().toString());
save(retTo, req, OpenIdUtil.P_SIGNIN_CB);
save(retTo, req, OpenIdUtil.P_SIGNIN_MODE);
save(retTo, req, OpenIdUtil.P_REMEMBERID);
final StringBuilder auth;
final UrlEncodedParameterMap auth;
auth = RelyingParty.getAuthUrlBuffer(user, realm, realm, retTo.toString());
append(auth, "openid.ns.ext1", AX_SCHEMA);
auth = RelyingParty.getAuthUrlMap(user, realm, realm, retTo.toString());
auth.put("openid.ns.ext1", AX_SCHEMA);
final String ext1 = "openid.ext1.";
append(auth, ext1 + "mode", "fetch_request");
append(auth, ext1 + "type.fname", "http://example.com/schema/fullname");
append(auth, ext1 + "type.email", "http://schema.openid.net/contact/email");
append(auth, ext1 + "required", "email");
append(auth, ext1 + "if_available", "fname");
auth.put(ext1 + "mode", "fetch_request");
auth.put(ext1 + "type.fname", "http://example.com/schema/fullname");
auth.put(ext1 + "type.email", "http://schema.openid.net/contact/email");
auth.put(ext1 + "required", "email");
auth.put(ext1 + "if_available", "fname");
append(auth, "openid.sreg.optional", "fullname,email");
append(auth, "openid.ns.sreg", "http://openid.net/extensions/sreg/1.1");
auth.put("openid.sreg.optional", "fullname,email");
auth.put("openid.ns.sreg", "http://openid.net/extensions/sreg/1.1");
relyingParty.getOpenIdUserManager().saveUser(user, req, rsp);
sendJson(req, rsp, new DiscoveryResult(true, auth.toString()), req
.getParameter(OpenIdUtil.P_DISCOVERY_CB));
}
private static void save(StringBuilder b, HttpServletRequest r, String n) {
private static void save(UrlEncodedParameterMap b, HttpServletRequest r,
String n) {
final String v = r.getParameter(n);
if (v != null) {
append(b, n, v);
b.put(n, v);
}
}
@@ -285,14 +289,15 @@ public class OpenIdLoginServlet extends HttpServlet {
c.setMaxAge(server.getSessionAge());
rsp.addCookie(c);
final StringBuilder me = new StringBuilder(req.getRequestURL());
append(me, Constants.OPENID_MODE, GMODE_CHKCOOKIE);
append(me, Gerrit.ACCOUNT_COOKIE, tok);
final UrlEncodedParameterMap me =
new UrlEncodedParameterMap(req.getRequestURL().toString());
me.put(Constants.OPENID_MODE, GMODE_CHKCOOKIE);
me.put(Gerrit.ACCOUNT_COOKIE, tok);
save(me, req, OpenIdUtil.P_SIGNIN_CB);
save(me, req, OpenIdUtil.P_SIGNIN_MODE);
if ("on".equals(req.getParameter(OpenIdUtil.P_REMEMBERID))) {
final String ident = saveLastId(req, rsp, user.getIdentity());
append(me, OpenIdUtil.LASTID_COOKIE, ident);
me.put(OpenIdUtil.LASTID_COOKIE, ident);
save(me, req, OpenIdUtil.P_REMEMBERID);
} else {
c = new Cookie(OpenIdUtil.LASTID_COOKIE, "");
@@ -564,7 +569,7 @@ public class OpenIdLoginServlet extends HttpServlet {
// We're not in an OpenID transaction so try to clear out the
// OpenID management cookie.
//
relyingParty.getOpenIdUserManager().invalidate(rsp);
relyingParty.getOpenIdUserManager().invalidate(req, rsp);
final String cb = req.getParameter(OpenIdUtil.P_SIGNIN_CB);
if (cb != null && cb.startsWith("history:")) {
@@ -641,16 +646,4 @@ public class OpenIdLoginServlet extends HttpServlet {
final int s = uri.lastIndexOf('/');
return s >= 0 ? uri.substring(0, s + 1) : uri;
}
private static void append(final StringBuilder buffer, final String name,
final String value) {
if (buffer.indexOf("?") >= 0) {
buffer.append('&');
} else {
buffer.append('?');
}
buffer.append(name);
buffer.append('=');
buffer.append(UrlEncoded.encodeString(value));
}
}