[Lada-commits] [PATCH] Change openID authentication to a filter
Wald Commits
scm-commit at wald.intevation.org
Wed Feb 25 16:56:58 CET 2015
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1424879772 -3600
# Branch openid
# Node ID 8e3f57e2f4af5eb8eb52189153bb72195a0713b0
# Parent 04e254571b8a0bb147a66204fad92867b8038279
Change openID authentication to a filter.
Currently authentication works only once as we don't store
session information and repeated try to authenticate will use
the same nonce.
diff -r 04e254571b8a -r 8e3f57e2f4af pom.xml
--- a/pom.xml Wed Feb 25 16:03:35 2015 +0100
+++ b/pom.xml Wed Feb 25 16:56:12 2015 +0100
@@ -60,7 +60,11 @@
<groupId>org.jboss.spec.javax.json</groupId>
<artifactId>jboss-json-api_1.0_spec</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>org.jboss.spec.javax.servlet</groupId>
+ <artifactId>jboss-servlet-api_3.0_spec</artifactId>
+ <version>1.0.2.Final</version>
+ </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
diff -r 04e254571b8a -r 8e3f57e2f4af src/main/java/de/intevation/lada/rest/ProbeService.java
--- a/src/main/java/de/intevation/lada/rest/ProbeService.java Wed Feb 25 16:03:35 2015 +0100
+++ b/src/main/java/de/intevation/lada/rest/ProbeService.java Wed Feb 25 16:56:12 2015 +0100
@@ -67,7 +67,7 @@
/* The authentication module.*/
@Inject
- @AuthenticationConfig(type=AuthenticationType.OPENID)
+ @AuthenticationConfig(type=AuthenticationType.NONE)
private Authentication authentication;
/* The authorization module.*/
diff -r 04e254571b8a -r 8e3f57e2f4af src/main/java/de/intevation/lada/util/auth/OpenIDAuthentication.java
--- a/src/main/java/de/intevation/lada/util/auth/OpenIDAuthentication.java Wed Feb 25 16:03:35 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-/* Copyright (C) 2015 by Bundesamt fuer Strahlenschutz
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU GPL (v>=3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out
- * the documentation coming with IMIS-Labordaten-Application for details.
- */
-package de.intevation.lada.util.auth;
-
-import java.util.Map;
-import java.util.List;
-import java.util.LinkedHashMap;
-import java.net.URLDecoder;
-
-import javax.inject.Inject;
-import javax.ejb.Stateless;
-import javax.ws.rs.core.HttpHeaders;
-
-import de.intevation.lada.util.annotation.AuthenticationConfig;
-
-import org.openid4java.association.AssociationSessionType;
-import org.openid4java.association.AssociationException;
-import org.openid4java.consumer.ConsumerManager;
-import org.openid4java.consumer.ConsumerException;
-import org.openid4java.consumer.InMemoryConsumerAssociationStore;
-import org.openid4java.consumer.InMemoryNonceVerifier;
-import org.openid4java.message.ParameterList;
-import org.openid4java.consumer.VerificationResult;
-import org.openid4java.discovery.DiscoveryInformation;
-import org.openid4java.discovery.Identifier;
-import org.openid4java.discovery.DiscoveryException;
-import org.openid4java.message.MessageException;
-import org.openid4java.message.AuthRequest;
-
-import org.apache.log4j.Logger;
-
-public class OpenIDAuthentication implements Authentication {
-
- /** The name of the header field used to transport OpenID parameters.*/
- private static final String OID_HEADER_FIELD= "X-OPENID-PARAMS";
-
- /** The identity provider we accept here. */
- private static final String IDENTITY_PROVIDER =
- "http://localhost:8087/account";
-
- /** This is currently a faked dummy */
- private static final String RETURN_URL =
- "http://localhost:8086/consumer-servlet/consumer?is_return=true";
-
- private static final Logger logger =
- Logger.getLogger(OpenIDAuthentication.class);
-
- private ConsumerManager manager;
-
- private Map<String,String> idParams;
-
- boolean discoveryDone = false;
-
- private DiscoveryInformation discovered;
-
- private boolean discoverServer() {
- /* Perform discovery on the configured IDENTITY_PROVIDER */
- List discoveries = null;
- try {
- discoveries = manager.discover(IDENTITY_PROVIDER);
- } catch (DiscoveryException e) {
- logger.debug("Discovery failed: " + e.getMessage());
- return false;
- }
-
- if (discoveries == null || discoveries.isEmpty()) {
- logger.error(
- "Failed discovery step. OpenID provider unavailable?");
- return false;
- }
-
- /* Add association for the discovered information */
- discovered = manager.associate(discoveries);
-
- /* Validate the parameters. */
- logger.debug("After discovery.");
- try {
- AuthRequest authReq = manager.authenticate(discovered, RETURN_URL);
- logger.debug("Authenticate with: " + authReq.getDestinationUrl(true));
- } catch (MessageException e) {
- logger.debug("Failed to create the Authentication request: " +
- e.getMessage());
- } catch (ConsumerException e) {
- logger.debug("Error in consumer manager: " +
- e.getMessage());
- }
- logger.debug("After authenticate.");
- return true;
- }
-
- public OpenIDAuthentication() {
- manager = new ConsumerManager();
- /* TODO: Check for alternative configs. */
- manager.setAssociations(new InMemoryConsumerAssociationStore());
- manager.setNonceVerifier(new InMemoryNonceVerifier(50000));
- manager.setMinAssocSessEnc(AssociationSessionType.DH_SHA256);
- discoveryDone = discoverServer();
- }
-
- /** Split up the OpenID response query provided in the header.
- *
- * @param responseQuery The query provided in the header field.
- * @return The query as ParameterList or null on error.
- */
- private ParameterList splitParams(String responseQuery) {
- Map<String, String> queryMap =
- new LinkedHashMap<String, String>();
- final String[] pairs = responseQuery.split("&");
- for (String pair : pairs) {
- final int idx = pair.indexOf("=");
- if (idx <= 0) {
- logger.debug("Invalid query.");
- return null;
- }
- try {
- final String key = URLDecoder.decode(
- pair.substring(0, idx), "UTF-8");
-
- if (queryMap.containsKey(key)) {
- logger.debug("Invalid query. Duplicate key: " + key);
- return null;
- }
- final String value = URLDecoder.decode(
- pair.substring(idx + 1), "UTF-8");
- queryMap.put(key, value);
- } catch (java.io.UnsupportedEncodingException e) {
- logger.error("UTF-8 unkown?!");
- return null;
- }
- }
- if (queryMap.isEmpty()) {
- logger.debug("Empty query.");
- return null;
- }
- return new ParameterList(queryMap);
- }
-
- private boolean checkOpenIDHeader(HttpHeaders headers) {
- /* First check if there are is anything provided */
- List<String> oidParamString = headers.getRequestHeader(
- OID_HEADER_FIELD);
- if (oidParamString == null) {
- logger.debug("Header " + OID_HEADER_FIELD + " not provided.");
- return false;
- }
- if (oidParamString.size() != 1) {
- logger.debug("Found " + oidParamString.size() + " openid headers.");
- return false;
- }
-
- /* Parse the parameters. Do it first to avoid a useless discovery. */
- ParameterList oidParams = splitParams(oidParamString.get(0));
- if (oidParams == null) {
- return false;
- }
-
- VerificationResult verification = null;
- try {
- verification = manager.verify(RETURN_URL, oidParams, discovered);
- } catch (MessageException e) {
- logger.debug("Verification failed: " + e.getMessage());
- return false;
- } catch (DiscoveryException e) {
- logger.debug("Verification discovery exception: " + e.getMessage());
- return false;
- } catch (AssociationException e) {
- logger.debug("Verification assoc exception: " + e.getMessage());
- return false;
- }
-
-
- /* See what could be verified */
- Identifier verified = verification.getVerifiedId();
- if (verified == null) {
- logger.debug("Failed to verify Identity information: " +
- verification.getStatusMsg());
- return false;
- }
-
- logger.debug("Verified user: " + verified);
-
- return true;
- }
-
- @Override
- public boolean isAuthenticated(HttpHeaders headers) {
- if (!discoveryDone) {
- discoveryDone = discoverServer();
- }
- if (!discoveryDone) {
- return false;
- }
- if (checkOpenIDHeader(headers)) {
- /** Successfully authenticated. */
- return true;
- } else {
-
- return false;
- }
- }
-}
diff -r 04e254571b8a -r 8e3f57e2f4af src/main/java/de/intevation/lada/util/auth/OpenIDFilter.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/de/intevation/lada/util/auth/OpenIDFilter.java Wed Feb 25 16:56:12 2015 +0100
@@ -0,0 +1,222 @@
+/* Copyright (C) 2015 by Bundesamt fuer Strahlenschutz
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU GPL (v>=3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out
+ * the documentation coming with IMIS-Labordaten-Application for details.
+ */
+
+package de.intevation.lada.util.auth;
+
+import org.apache.log4j.Logger;
+
+import java.util.Map;
+import java.util.List;
+import java.util.LinkedHashMap;
+import java.net.URLDecoder;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.openid4java.association.AssociationSessionType;
+import org.openid4java.association.AssociationException;
+import org.openid4java.consumer.ConsumerManager;
+import org.openid4java.consumer.ConsumerException;
+import org.openid4java.consumer.InMemoryConsumerAssociationStore;
+import org.openid4java.consumer.InMemoryNonceVerifier;
+import org.openid4java.message.ParameterList;
+import org.openid4java.consumer.VerificationResult;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.discovery.Identifier;
+import org.openid4java.discovery.DiscoveryException;
+import org.openid4java.message.MessageException;
+import org.openid4java.message.AuthRequest;
+
+/** ServletFilter used for OpenID authentification. */
+ at WebFilter("/*")
+public class OpenIDFilter implements Filter
+{
+ private static Logger logger = Logger.getLogger(OpenIDFilter.class);
+
+ private ConsumerManager manager;
+
+ /* This should be moved into a map <server->discovered>
+ * as we currently only supporting one server this is static. */
+ boolean discoveryDone = false;
+ private DiscoveryInformation discovered;
+ private String authRequestURL;
+
+ /** TODO: get this from config. */
+ /** The name of the header field used to transport OpenID parameters.*/
+ private static final String OID_HEADER_FIELD= "X-OPENID-PARAMS";
+
+ /** The identity provider we accept here. */
+ private static final String IDENTITY_PROVIDER =
+ "http://localhost:8087/account";
+
+ /** This is currently a faked dummy */
+ private static final String RETURN_URL =
+ "http://localhost:8086/consumer-servlet/consumer?is_return=true";
+
+ private boolean discoverServer() {
+ /* Perform discovery on the configured IDENTITY_PROVIDER */
+ List discoveries = null;
+ try {
+ discoveries = manager.discover(IDENTITY_PROVIDER);
+ } catch (DiscoveryException e) {
+ logger.debug("Discovery failed: " + e.getMessage());
+ return false;
+ }
+
+ if (discoveries == null || discoveries.isEmpty()) {
+ logger.error(
+ "Failed discovery step. OpenID provider unavailable?");
+ return false;
+ }
+
+ /* Add association for the discovered information */
+ discovered = manager.associate(discoveries);
+
+ /* Validate the parameters. */
+ logger.debug("After discovery.");
+ try {
+ AuthRequest authReq = manager.authenticate(discovered, RETURN_URL);
+ authRequestURL = authReq.getDestinationUrl(true);
+ logger.debug("Authenticate with: " + authRequestURL);
+ } catch (MessageException e) {
+ logger.debug("Failed to create the Authentication request: " +
+ e.getMessage());
+ } catch (ConsumerException e) {
+ logger.debug("Error in consumer manager: " +
+ e.getMessage());
+ }
+ return true;
+ }
+
+ /** Split up the OpenID response query provided in the header.
+ *
+ * @param responseQuery The query provided in the header field.
+ * @return The query as ParameterList or null on error.
+ */
+ private ParameterList splitParams(String responseQuery) {
+ Map<String, String> queryMap =
+ new LinkedHashMap<String, String>();
+ final String[] pairs = responseQuery.split("&");
+ for (String pair : pairs) {
+ final int idx = pair.indexOf("=");
+ if (idx <= 0) {
+ logger.debug("Invalid query.");
+ return null;
+ }
+ try {
+ final String key = URLDecoder.decode(
+ pair.substring(0, idx), "UTF-8");
+
+ if (queryMap.containsKey(key)) {
+ logger.debug("Invalid query. Duplicate key: " + key);
+ return null;
+ }
+ final String value = URLDecoder.decode(
+ pair.substring(idx + 1), "UTF-8");
+ queryMap.put(key, value);
+ } catch (java.io.UnsupportedEncodingException e) {
+ logger.error("UTF-8 unkown?!");
+ return null;
+ }
+ }
+ if (queryMap.isEmpty()) {
+ logger.debug("Empty query.");
+ return null;
+ }
+ return new ParameterList(queryMap);
+ }
+
+ private boolean checkOpenIDHeader(ServletRequest req) {
+
+ HttpServletRequest hReq = (HttpServletRequest) req;
+ /* First check if the header is provided at all */
+ String oidParamString = hReq.getHeader(OID_HEADER_FIELD);
+
+ if (oidParamString == null) {
+ logger.debug("Header " + OID_HEADER_FIELD + " not provided.");
+ return false;
+ }
+
+ /* Parse the parameters to a map for openid4j */
+ ParameterList oidParams = splitParams(oidParamString);
+ if (oidParams == null) {
+ return false;
+ }
+
+ /* Verify against the discovered server. */
+ VerificationResult verification = null;
+ try {
+ verification = manager.verify(RETURN_URL, oidParams, discovered);
+ } catch (MessageException e) {
+ logger.debug("Verification failed: " + e.getMessage());
+ return false;
+ } catch (DiscoveryException e) {
+ logger.debug("Verification discovery exception: " + e.getMessage());
+ return false;
+ } catch (AssociationException e) {
+ logger.debug("Verification assoc exception: " + e.getMessage());
+ return false;
+ }
+
+ /* See what could be verified */
+ Identifier verified = verification.getVerifiedId();
+ if (verified == null) {
+ logger.debug("Failed to verify Identity information: " +
+ verification.getStatusMsg());
+ return false;
+ }
+
+ logger.debug("Verified user: " + verified);
+
+ return true;
+ }
+
+ @Override
+ public void init(FilterConfig config)
+ throws ServletException
+ {
+ manager = new ConsumerManager();
+ /* TODO: Check for alternative configs. */
+ manager.setAssociations(new InMemoryConsumerAssociationStore());
+ manager.setNonceVerifier(new InMemoryNonceVerifier(50000));
+ manager.setMinAssocSessEnc(AssociationSessionType.DH_SHA256);
+ discoveryDone = discoverServer();
+ }
+
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
+ throws IOException, ServletException
+ {
+ if (!discoveryDone) {
+ discoveryDone = discoverServer();
+ }
+ if (discoveryDone && checkOpenIDHeader(req)) {
+ /** Successfully authenticated. */
+ chain.doFilter(req, resp);
+ }
+ ((HttpServletResponse) resp).sendError(401, "{\"success\":false,\"message\":\"699\",\"data\":" +
+ "\"" + authRequestURL + "\",\"errors\":{},\"warnings\":{}," +
+ "\"readonly\":false,\"totalCount\":0}");
+ }
+ @Override
+ public void destroy()
+ {
+ }
+};
More information about the Lada-commits
mailing list