Author: rvesse
Date: Thu Jun 27 19:21:33 2013
New Revision: 1497509
URL: http://svn.apache.org/r1497509
Log:
Unified and extensible authentication framework for Atlas (JENA-480)
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractCredentialsAuthenticator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractScopedAuthenticator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/HttpAuthenticator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/PreemptiveBasicAuthenticator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ScopedAuthenticator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ServiceAuthenticator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/SimpleAuthenticator.java
Modified:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
Modified:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java?rev=1497509&r1=1497508&r2=1497509&view=diff
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
(original)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/HttpException.java
Thu Jun 27 19:21:33 2013
@@ -18,10 +18,32 @@
package org.apache.jena.atlas.web;
-public class HttpException extends RuntimeException
-{
- public HttpException() {}
- public HttpException(String message) { super(message) ;
}
- public HttpException(Throwable cause) { super(cause) ; }
- public HttpException(String message, Throwable cause) { super(message,
cause) ;}
+/**
+ * Class of HTTP Exceptions from Atlas code
+ *
+ */
+public class HttpException extends RuntimeException {
+ private static final long serialVersionUID = -7224224620679594095L;
+ private int responseCode = -1;
+
+ public HttpException(int responseCode, String statusLine) {
+ super(responseCode + " - " + statusLine);
+ this.responseCode = responseCode;
+ }
+
+ public HttpException(String message) {
+ super(message);
+ }
+
+ public HttpException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Gets the response code, may be -1 if unknown
+ * @return Response Code if known, -1 otherwise
+ */
+ public int getResponseCode() {
+ return this.responseCode;
+ }
}
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractCredentialsAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractCredentialsAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractCredentialsAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractCredentialsAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.AbstractHttpClient;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * Abstract authenticator that uses user name and password credentials
+ *
+ */
+public abstract class AbstractCredentialsAuthenticator implements
HttpAuthenticator {
+
+ @Override
+ public final void apply(AbstractHttpClient client, HttpContext context,
URI target) {
+ // TODO Should we allow a user name without a password (or vice versa)?
+ if (!this.hasUserName(target) || !this.hasPassword(target)) return;
+
+ // Be careful to scope credentials to the specific URI so that
HttpClient won't try
+ // and send them to other servers
+ HttpHost host = new HttpHost(target.getHost(), target.getPort());
+ CredentialsProvider provider = new BasicCredentialsProvider();
+
+ String user = this.getUserName(target);
+ provider.setCredentials(new AuthScope(host), new
UsernamePasswordCredentials(user, new String(this.getPassword(target))));
+
+ client.setCredentialsProvider(provider);
+ }
+
+ /**
+ * Gets whether there is a user name available for the target URI
+ * @param target Target
+ * @return True if a user name is available, false otherwise
+ */
+ protected abstract boolean hasUserName(URI target);
+
+ /**
+ * Gets the user name for the target URI
+ * @param target Target
+ * @return User name or null if none available
+ */
+ protected abstract String getUserName(URI target);
+
+ /**
+ * Gets whether there is a password available for the target URI
+ * @param target Target
+ * @return True if a password is available, false otherwise
+ */
+ protected abstract boolean hasPassword(URI target);
+
+ /**
+ * Gets the password for the target URI
+ * @param target Target
+ * @return Password or null if none available
+ */
+ protected abstract char[] getPassword(URI target);
+
+}
\ No newline at end of file
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractScopedAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractScopedAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractScopedAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/AbstractScopedAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+
+/**
+ * An abstract helper for authenticators which scope credentials to URIs
+ */
+public abstract class AbstractScopedAuthenticator extends
AbstractCredentialsAuthenticator {
+
+ @Override
+ protected boolean hasUserName(URI target) {
+ return this.getUserName(target) != null;
+ }
+
+ @Override
+ protected boolean hasPassword(URI target) {
+ return this.getPassword(target) != null;
+ }
+
+}
\ No newline at end of file
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/HttpAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/HttpAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/HttpAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/HttpAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.AbstractHttpClient;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * Interface for classes that are able to apply some form of authentication to
a
+ * {@link HttpClient} instance. Provides a unified mechanism for applying
+ * authentication that is agnostic of the actual authentication mechanism being
+ * used.
+ *
+ */
+public interface HttpAuthenticator {
+
+ /**
+ * Applies any necessary authentication methods to the given HTTP Client
+ * <p>
+ * The {@code target} parameter indicates the URI to which the request is
+ * being made and so may be used by an authenticator to determine whether
it
+ * actually needs to apply any authentication or to scope authentication
+ * appropriately.
+ * </p>
+ *
+ * @param client
+ * HTTP Client
+ * @param httpContext
+ * HTTP Context
+ * @param target
+ * Target URI to which code wants to authenticate
+ */
+ public void apply(AbstractHttpClient client, HttpContext httpContext, URI
target);
+}
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/PreemptiveBasicAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/PreemptiveBasicAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/PreemptiveBasicAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/PreemptiveBasicAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+
+import org.apache.http.HttpHost;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.AbstractHttpClient;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * A decorator for other authenticators that may be used to enable preemptive
+ * basic authentication. Note that preemptive basic authentication is less
+ * secure because it can expose credentials to servers that do not require
them.
+ *
+ */
+public class PreemptiveBasicAuthenticator implements HttpAuthenticator {
+
+ private HttpAuthenticator authenticator;
+
+ /**
+ * Creates a new decorator over the given authenticator
+ * @param authenticator Authenticator to decorate
+ */
+ public PreemptiveBasicAuthenticator(HttpAuthenticator authenticator) {
+ if (authenticator == null) throw new IllegalArgumentException("Must
provide an authenticator to decorate");
+ this.authenticator = authenticator;
+ }
+
+ @Override
+ public void apply(AbstractHttpClient client, HttpContext httpContext, URI
target) {
+ this.authenticator.apply(client, httpContext, target);
+
+ // Enable preemptive basic authentication
+ AuthCache authCache = new BasicAuthCache();
+ BasicScheme basicAuth = new BasicScheme();
+ authCache.put(new HttpHost(target.getHost(), target.getPort()),
basicAuth);
+ httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
+ }
+
+}
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ScopedAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ScopedAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ScopedAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ScopedAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jena.atlas.lib.Pair;
+
+/**
+ * A credentials based authenticator where credentials are scoped to URIs. This
+ * allows for a single authenticator to present different credentials to
+ * different URIs as appropriate.
+ *
+ */
+public class ScopedAuthenticator extends AbstractScopedAuthenticator {
+
+ private Map<URI, Pair<String, char[]>> credentials = new HashMap<URI,
Pair<String, char[]>>();
+
+ /**
+ * Creates an authenticator with credentials for the given URI
+ * @param target URI
+ * @param username User name
+ * @param password Password
+ */
+ public ScopedAuthenticator(URI target, String username, char[] password) {
+ if (target == null) throw new IllegalArgumentException("Target URI
cannot be null");
+ this.credentials.put(target, Pair.create(username, password));
+ }
+
+ /**
+ * Creates an authenticator with a set of credentials for URIs
+ * @param credentials Credentials
+ */
+ public ScopedAuthenticator(Map<URI, Pair<String, char[]>> credentials) {
+ this.credentials.putAll(credentials);
+ }
+
+ /**
+ * Adds/Overwrites credentials for a given URI
+ * @param target Target
+ * @param username User name
+ * @param password Password
+ */
+ public void addCredentials(URI target, String username, char[] password) {
+ if (target == null) throw new IllegalArgumentException("Target URI
cannot be null");
+ this.credentials.put(target, Pair.create(username, password));
+ }
+
+ @Override
+ protected String getUserName(URI target) {
+ Pair<String, char[]> p = this.credentials.get(target);
+ return p != null ? p.getLeft() : null;
+ }
+
+ @Override
+ protected char[] getPassword(URI target) {
+ Pair<String, char[]> p = this.credentials.get(target);
+ return p != null ? p.getRight() : null;
+ }
+
+}
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ServiceAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ServiceAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ServiceAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/ServiceAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+import java.util.Map;
+
+import com.hp.hpl.jena.query.ARQ;
+import com.hp.hpl.jena.sparql.engine.http.Service;
+import com.hp.hpl.jena.sparql.util.Context;
+
+/**
+ * A HTTP authenticator which selects credentials based upon service context
+ * found in the provided {@link Context}. May also optionally use fallback
+ * credentials for URIs for which authentication has not been explicitly
+ * configured.
+ *
+ */
+public class ServiceAuthenticator extends AbstractScopedAuthenticator {
+
+ private Context context;
+ private String username;
+ private char[] password;
+
+ /**
+ * Creates new authenticator using the standard ARQ context
+ */
+ public ServiceAuthenticator() {
+ this(ARQ.getContext(), null, null);
+ }
+
+ /**
+ * Creates a new authenticator using the standard ARQ context, the provided
+ * credentials are used as fallback if the context contains no registered
+ * credentials for a target URI
+ *
+ * @param username
+ * Fallback user name
+ * @param password
+ * Fallback password
+ */
+ public ServiceAuthenticator(String username, char[] password) {
+ this(ARQ.getContext(), username, password);
+ }
+
+ /**
+ * Creates a new authenticator using the given context
+ *
+ * @param context
+ * Context
+ */
+ public ServiceAuthenticator(Context context) {
+ this(context, null, null);
+ }
+
+ /**
+ * Creates a new authenticator using the given context, the provided
+ * credentials are used as fallback if the context contains no registered
+ * credentials for a target URI
+ *
+ * @param context
+ * Context
+ * @param username
+ * Fallback user name
+ * @param password
+ * Fallback password
+ */
+ public ServiceAuthenticator(Context context, String username, char[]
password) {
+ this.context = context;
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ public String getUserName(URI target) {
+ if (this.context != null) {
+
+ @SuppressWarnings("unchecked")
+ Map<String, Context> serviceContextMap = (Map<String, Context>)
this.context.get(Service.serviceContext);
+ if (serviceContextMap != null &&
serviceContextMap.containsKey(Service.serviceContext)) {
+ // Try to obtain Context for target URI
+ Context serviceContext =
serviceContextMap.get(target.toString());
+ if (serviceContext != null) {
+ // Service Context exists for target URI
+ return serviceContext.getAsString(Service.queryAuthUser);
+ }
+ }
+ }
+ // Use fallback user name
+ return this.username;
+ }
+
+ @Override
+ public char[] getPassword(URI target) {
+ if (this.context != null) {
+
+ @SuppressWarnings("unchecked")
+ Map<String, Context> serviceContextMap = (Map<String, Context>)
this.context.get(Service.serviceContext);
+ if (serviceContextMap != null &&
serviceContextMap.containsKey(Service.serviceContext)) {
+ // Try to obtain Context for target URI
+ Context serviceContext =
serviceContextMap.get(target.toString());
+ if (serviceContext != null) {
+ // Service Context exists for target URI
+ String pwd =
serviceContext.getAsString(Service.queryAuthPwd);
+ return pwd != null ? pwd.toCharArray() : null;
+ }
+ }
+ }
+ // User fallback password
+ return this.password;
+ }
+}
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/SimpleAuthenticator.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/SimpleAuthenticator.java?rev=1497509&view=auto
==============================================================================
---
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/SimpleAuthenticator.java
(added)
+++
jena/trunk/jena-arq/src/main/java/org/apache/jena/atlas/web/auth/SimpleAuthenticator.java
Thu Jun 27 19:21:33 2013
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.jena.atlas.web.auth;
+
+import java.net.URI;
+
+/**
+ * A HTTP Authenticator which provides authentication via user name and
password
+ * combinations, can in principal be used to authenticate with any of the HTTP
+ * authentication schemes that HTTP Client supports
+ * <p>
+ * This authenticator will presents the given credentials to any server, it is
+ * typically more secure to use the {@link ScopedAuthenticator} instead.
+ * </p>
+ *
+ */
+public class SimpleAuthenticator extends AbstractCredentialsAuthenticator {
+
+ String username;
+ char[] password;
+
+ /**
+ * Creates a new authenticator
+ *
+ * @param username
+ * Username
+ * @param password
+ * Password
+ */
+ public SimpleAuthenticator(String username, char[] password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ protected boolean hasUserName(URI target) {
+ return this.username != null;
+ }
+
+ @Override
+ protected String getUserName(URI target) {
+ return this.username;
+ }
+
+ @Override
+ protected boolean hasPassword(URI target) {
+ return this.password != null;
+ }
+
+ @Override
+ protected char[] getPassword(URI target) {
+ return this.password;
+ }
+
+}