You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/09/06 23:20:40 UTC
svn commit: r440877 - in
/incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet:
./ SignedResponseFilter.java
Author: jmsnell
Date: Wed Sep 6 14:20:40 2006
New Revision: 440877
URL: http://svn.apache.org/viewvc?view=rev&rev=440877
Log:
Adding a HTTP Servlet Filter implementation that will add an XML Digital Signature to
served Abdera documents
Added:
incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet/
incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet/SignedResponseFilter.java
Added: incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet/SignedResponseFilter.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet/SignedResponseFilter.java?view=auto&rev=440877
==============================================================================
--- incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet/SignedResponseFilter.java (added)
+++ incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/servlet/SignedResponseFilter.java Wed Sep 6 14:20:40 2006
@@ -0,0 +1,235 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.security.util.servlet;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.Parser;
+import org.apache.abdera.security.AbderaSecurity;
+import org.apache.abdera.security.SecurityException;
+import org.apache.abdera.security.Signature;
+import org.apache.abdera.security.SignatureOptions;
+
+/**
+ * <p>This HTTP Servlet Filter will add an XML Digital Signature to Abdera documents</p>
+ * <pre>
+ * <filter>
+ * <filter-name>signing filter</filter-name>
+ * <filter-class>org.apache.abdera.security.util.servlet.SignedResponseFilter</filter-class>
+ * <init-param>
+ * <param-name>org.apache.abdera.security.util.servlet.Keystore</param-name>
+ * <param-value>/key.jks</param-value>
+ * </init-param>
+ * <init-param>
+ * <param-name>org.apache.abdera.security.util.servlet.KeystorePassword</param-name>
+ * <param-value>testing</param-value>
+ * </init-param>
+ * <init-param>
+ * <param-name>org.apache.abdera.security.util.servlet.PrivateKeyAlias</param-name>
+ * <param-value>James</param-value>
+ * </init-param>
+ * <init-param>
+ * <param-name>org.apache.abdera.security.util.servlet.PrivateKeyPassword</param-name>
+ * <param-value>testing</param-value>
+ * </init-param>
+ * <init-param>
+ * <param-name>org.apache.abdera.security.util.servlet.CertificateAlias</param-name>
+ * <param-value>James</param-value>
+ * </init-param>
+ * </filter>
+ * <filter-mapping id="signing-filter">
+ * <filter-name>signing filter</filter-name>
+ * <servlet-name>Abdera</servlet-name>
+ * </filter-mapping>
+ * </pre>
+ */
+public class SignedResponseFilter
+ implements Filter {
+
+ private static final String KEYSTORE = "org.apache.abdera.security.util.servlet.Keystore";
+ private static final String STOREPASS = "org.apache.abdera.security.util.servlet.KeystorePassword";
+ private static final String KEY = "org.apache.abdera.security.util.servlet.PrivateKeyAlias";
+ private static final String KEYPASS = "org.apache.abdera.security.util.servlet.PrivateKeyPassword";
+ private static final String CERT = "org.apache.abdera.security.util.servlet.CertificateAlias";
+
+ private static final String keystoreType = "JKS";
+
+ private Abdera abdera = null;
+ private AbderaSecurity security = null;
+ private String keystoreFile = null;
+ private String keystorePass = null;
+ private String privateKeyAlias = null;
+ private String privateKeyPass = null;
+ private String certificateAlias = null;
+ private PrivateKey signingKey = null;
+ private X509Certificate cert = null;
+
+ public void init(
+ FilterConfig config)
+ throws ServletException {
+ keystoreFile = config.getInitParameter(KEYSTORE);
+ keystorePass = config.getInitParameter(STOREPASS);
+ privateKeyAlias = config.getInitParameter(KEY);
+ privateKeyPass = config.getInitParameter(KEYPASS);
+ certificateAlias = config.getInitParameter(CERT);
+ abdera = new Abdera();
+ security = new AbderaSecurity(abdera);
+
+ try {
+ KeyStore ks = KeyStore.getInstance(keystoreType);
+ InputStream in = SignedResponseFilter.class.getResourceAsStream(keystoreFile);
+ ks.load(in, keystorePass.toCharArray());
+ signingKey =
+ (PrivateKey) ks.getKey(
+ privateKeyAlias,
+ privateKeyPass.toCharArray());
+ cert =
+ (X509Certificate) ks.getCertificate(
+ certificateAlias);
+ } catch (Exception e) {}
+ }
+
+ public void destroy() {}
+
+ public void doFilter(
+ ServletRequest request,
+ ServletResponse response,
+ FilterChain chain)
+ throws IOException,
+ ServletException {
+
+ BufferingResponseWrapper wrapper =
+ new BufferingResponseWrapper(
+ (HttpServletResponse)response);
+
+ chain.doFilter(request, wrapper);
+
+ try {
+ Document<Element> doc = getDocument(wrapper);
+ if (doc != null) {
+ doc = sign(doc);
+ doc.writeTo(response.getOutputStream());
+ }
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+ private Document<Element> sign(Document<Element> doc) throws SecurityException {
+ if (signingKey == null || cert == null) return doc; // pass through
+ Signature sig = security.getSignature();
+ SignatureOptions options = sig.getDefaultSignatureOptions();
+ options.setCertificate(cert);
+ options.setSigningKey(signingKey);
+ Element element = doc.getRoot();
+ element = sig.sign(element, options);
+ return element.getDocument();
+ }
+
+ private Document<Element> getDocument(BufferingResponseWrapper wrapper) {
+ Reader rdr = wrapper.getReader();
+ InputStream in = wrapper.getInputStream();
+ Parser parser = abdera.getParser();
+ if (rdr != null)
+ return parser.parse(rdr);
+ if (in != null)
+ return parser.parse(in);
+ return null;
+ }
+
+ static class BufferingResponseWrapper
+ extends HttpServletResponseWrapper {
+
+ CharArrayWriter output = null;
+ ByteArrayOutputStream outStream = null;
+
+ BufferingResponseWrapper(HttpServletResponse response) {
+ super(response);
+ }
+
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ if (outStream != null) throw new IllegalStateException();
+ if (output == null) output = new CharArrayWriter();
+ return new PrintWriter(output);
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (output != null) throw new IllegalStateException();
+ if (outStream == null) outStream = new ByteArrayOutputStream();
+ return new BufferingServletOutputStream(outStream);
+ }
+
+ public Reader getReader() {
+ if (output == null) return null;
+ return new CharArrayReader(output.toCharArray());
+ }
+
+ public InputStream getInputStream() {
+ if (outStream == null) return null;
+ return new ByteArrayInputStream(outStream.toByteArray());
+ }
+ }
+
+ static class BufferingServletOutputStream
+ extends ServletOutputStream {
+
+ ByteArrayOutputStream out = null;
+
+ BufferingServletOutputStream(ByteArrayOutputStream out) {
+ this.out = out;
+ }
+
+ public void write(int b) throws IOException {
+ out.write(b);
+ }
+
+ public void write(byte[] b) throws IOException {
+ out.write(b);
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ out.write(b, off, len);
+ }
+
+ }
+}