public class StreamUtils {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+ /*
+ * APACHE COMMONS IO (inspired)
+ */
+
/** @return the number of bytes */
public static Long copy(InputStream in, OutputStream out)
throws IOException {
}
}
- private StreamUtils() {
+ /*
+ * APACHE COMMONS CODEC (forked)
+ */
+ /**
+ * Used to build output as Hex
+ */
+ private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ /**
+ * Used to build output as Hex
+ */
+ private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ /**
+ * Converts an array of bytes into a String representing the hexadecimal
+ * values of each byte in order. The returned String will be double the
+ * length of the passed array, as it takes two characters to represent any
+ * given byte.
+ *
+ * @param data
+ * a byte[] to convert to Hex characters
+ * @return A String containing hexadecimal characters
+ * @since 1.4
+ */
+ public static String encodeHexString(byte[] data) {
+ return new String(encodeHex(data));
+ }
+
+ /**
+ * Converts an array of bytes into an array of characters representing the
+ * hexadecimal values of each byte in order. The returned array will be
+ * double the length of the passed array, as it takes two characters to
+ * represent any given byte.
+ *
+ * @param data
+ * a byte[] to convert to Hex characters
+ * @return A char[] containing hexadecimal characters
+ */
+ public static char[] encodeHex(byte[] data) {
+ return encodeHex(data, true);
+ }
+
+ /**
+ * Converts an array of bytes into an array of characters representing the
+ * hexadecimal values of each byte in order. The returned array will be
+ * double the length of the passed array, as it takes two characters to
+ * represent any given byte.
+ *
+ * @param data
+ * a byte[] to convert to Hex characters
+ * @param toLowerCase
+ * <code>true</code> converts to lowercase, <code>false</code> to
+ * uppercase
+ * @return A char[] containing hexadecimal characters
+ * @since 1.4
+ */
+ public static char[] encodeHex(byte[] data, boolean toLowerCase) {
+ return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
+ }
+
+ /**
+ * Converts an array of bytes into an array of characters representing the
+ * hexadecimal values of each byte in order. The returned array will be
+ * double the length of the passed array, as it takes two characters to
+ * represent any given byte.
+ *
+ * @param data
+ * a byte[] to convert to Hex characters
+ * @param toDigits
+ * the output alphabet
+ * @return A char[] containing hexadecimal characters
+ * @since 1.4
+ */
+ protected static char[] encodeHex(byte[] data, char[] toDigits) {
+ int l = data.length;
+ char[] out = new char[l << 1];
+ // two characters form the hex value.
+ for (int i = 0, j = 0; i < l; i++) {
+ out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
+ out[j++] = toDigits[0x0F & data[i]];
+ }
+ return out;
}
}
private final Cipher ecipher;
private final Cipher dcipher;
+ /**
+ * This is up to the caller to clear the passed array. Neither copy of nor
+ * reference to the passed array is kept
+ */
public PasswordBasedEncryption(char[] password) {
this(password, DEFAULT_SALT_8, DEFAULT_IV_16);
}
+ /**
+ * This is up to the caller to clear the passed array. Neither copies of nor
+ * references to the passed arrays are kept
+ */
public PasswordBasedEncryption(char[] password, byte[] passwordSalt,
byte[] initializationVector) {
try {
--- /dev/null
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * 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 org.argeo.util.security;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.argeo.ArgeoException;
+import org.argeo.StreamUtils;
+
+/** Utilities around cryptographic digests */
+public class DigestUtils {
+ private static Boolean debug = true;
+ // TODO: make it writable
+ private final static Integer byteBufferCapacity = 100 * 1024;// 100 KB
+
+ public static String digest(String algorithm, InputStream in) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance(algorithm);
+ // ReadableByteChannel channel = Channels.newChannel(in);
+ // ByteBuffer bb = ByteBuffer.allocateDirect(byteBufferCapacity);
+ // while (channel.read(bb) > 0)
+ // digest.update(bb);
+ byte[] buffer = new byte[byteBufferCapacity];
+ int read = 0;
+ while ((read = in.read(buffer)) > 0) {
+ digest.update(buffer, 0, read);
+ }
+
+ byte[] checksum = digest.digest();
+ String res = StreamUtils.encodeHexString(checksum);
+ return res;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot digest with algorithm "
+ + algorithm, e);
+ } finally {
+ StreamUtils.closeQuietly(in);
+ }
+ }
+
+ public static String digest(String algorithm, File file) {
+ FileInputStream fis = null;
+ FileChannel fc = null;
+ try {
+ fis = new FileInputStream(file);
+ fc = fis.getChannel();
+
+ // Get the file's size and then map it into memory
+ int sz = (int) fc.size();
+ ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
+ return digest(algorithm, bb);
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot digest " + file
+ + " with algorithm " + algorithm, e);
+ } finally {
+ StreamUtils.closeQuietly(fis);
+ if (fc.isOpen())
+ try {
+ fc.close();
+ } catch (IOException e) {
+ // silent
+ }
+ }
+ }
+
+ protected static String digest(String algorithm, ByteBuffer bb) {
+ long begin = System.currentTimeMillis();
+ try {
+ MessageDigest digest = MessageDigest.getInstance(algorithm);
+ digest.update(bb);
+ byte[] checksum = digest.digest();
+ String res = StreamUtils.encodeHexString(checksum);
+ long end = System.currentTimeMillis();
+ if (debug)
+ System.out.println((end - begin) + " ms / "
+ + ((end - begin) / 1000) + " s");
+ return res;
+ } catch (NoSuchAlgorithmException e) {
+ throw new ArgeoException("Cannot digest with algorithm "
+ + algorithm, e);
+ }
+ }
+
+ public static void main(String[] args) {
+ File file;
+ if (args.length > 0)
+ file = new File(args[0]);
+ else {
+ System.err.println("Usage: <file> [<algorithm>]"
+ + " (see http://java.sun.com/j2se/1.5.0/"
+ + "docs/guide/security/CryptoSpec.html#AppA)");
+ return;
+ }
+
+ if (args.length > 1) {
+ String algorithm = args[1];
+ System.out.println(digest(algorithm, file));
+ } else {
+ String algorithm = "MD5";
+ System.out.println(algorithm + ": " + digest(algorithm, file));
+ algorithm = "SHA";
+ System.out.println(algorithm + ": " + digest(algorithm, file));
+ algorithm = "SHA-256";
+ System.out.println(algorithm + ": " + digest(algorithm, file));
+ algorithm = "SHA-512";
+ System.out.println(algorithm + ": " + digest(algorithm, file));
+ }
+ }
+
+}
log4j.logger.org.apache.directory.server=ERROR
log4j.logger.org.apache.jackrabbit.core.query.lucene=ERROR
+log4j.logger.org.springframework.security.context=DEBUG
+
## Appenders
# console is set to be a ConsoleAppender.
log4j.appender.console=org.apache.log4j.ConsoleAppender
<bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
<property name="providers">
<list>
- <ref bean="anonymousAuthenticationProvider" />
<ref bean="authByAdapterProvider" />
+<!-- <ref bean="preAuthAuthenticationProvider" /> -->
+ <ref bean="anonymousAuthenticationProvider" />
+ <ref bean="rememberMeAuthenticationProvider" />
<ref bean="ldapAuthenticationProvider" />
</list>
</property>
<property name="key" value="${argeo.security.systemKey}" />
</bean>
+<!-- <bean id="preAuthAuthenticationProvider" -->
+<!-- class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider"> -->
+<!-- <description><![CDATA[Pre-authentication]]></description> -->
+<!-- </bean> -->
+
<bean id="anonymousAuthenticationProvider"
class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
<description><![CDATA[Anonymous authentication]]></description>
<property name="key" value="${argeo.security.systemKey}" />
</bean>
+ <bean id="rememberMeAuthenticationProvider"
+ class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
+ <description><![CDATA[Remember me authentication]]></description>
+ <property name="key" value="${argeo.security.systemKey}" />
+ </bean>
+
<!-- Internal authentication, used by during the general authentication
initialization himself, in order to prevent the following dependency cycle:
Repository.login() <= AuthenticationManager <= LdapAuthenticationProvider
--- /dev/null
+<html>
+<head></head>
+<body>
+<center>
+<table height="100%">
+<tr>
+ <td style="vertical-align:middle">
+ <a
+ style="font-family:sans-serif;color:#0066CC;text-decoration:none;"
+ href="node"
+ title="Click to log in"
+ >Login...</a>
+ </td>
+</tr>
+</table>
+</center>
+</body>
+</html>
\ No newline at end of file
+++ /dev/null
-<html>
-<head></head>
-<body>
-<center>
-<table height="100%">
-<tr>
- <td style="vertical-align:middle">
- <a
- style="font-family:sans-serif;color:#0066CC;text-decoration:none;"
- href="javascript:location.reload(true);"
- title="Click to log in"
- >Login...</a>
- </td>
-</tr>
-</table>
-</center>
-</body>
-</html>
\ No newline at end of file
--- /dev/null
+<html>
+<head></head>
+<body>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<html>
+<head></head>
+<body>
+<center>
+<table height="100%">
+<tr>
+ <td style="vertical-align:middle">
+ <a
+ style="font-family:sans-serif;color:#0066CC;text-decoration:none;"
+ href="javascript:location.reload(true);"
+ title="Click to log in"
+ >Login...</a>
+ </td>
+</tr>
+</table>
+</center>
+</body>
+</html>
\ No newline at end of file
class="org.argeo.security.ui.rap.AnonymousEntryPoint"
parameter="publicWebUi">
</entrypoint>
+ <entrypoint
+ id="org.argeo.security.ui.rap.logoutEntryPoint"
+ class="org.argeo.security.ui.rap.LogoutEntryPoint"
+ parameter="logout">
+ </entrypoint>
+ <entrypoint
+ id="org.argeo.security.ui.rap.nullEntryPoint"
+ class="org.argeo.security.ui.rap.NullEntryPoint"
+ parameter="null">
+ </entrypoint>
</extension>
<extension
defaultEntrypointId="org.argeo.security.ui.rap.secureEntryPoint"
title="Argeo Web UI"
favicon="branding/favicon.ico"
- body="branding/public.html">
+ body="branding/login.html">
+ </branding>
+ <branding
+ id="org.argeo.security.ui.rap.branding"
+ servletName="ui"
+ defaultEntrypointId="org.argeo.security.ui.rap.secureEntryPoint"
+ title="Argeo Web UI"
+ favicon="branding/favicon.ico"
+ body="branding/login.html">
+ </branding>
+ <branding
+ id="org.argeo.security.ui.rap.branding"
+ servletName="basicauth"
+ defaultEntrypointId="org.argeo.security.ui.rap.secureEntryPoint"
+ title="Argeo Web UI"
+ favicon="branding/favicon.ico"
+ body="branding/login.html">
</branding>
<branding
id="org.argeo.security.ui.rap.branding"
favicon="branding/favicon.ico"
body="branding/public.html">
</branding>
+ <branding
+ id="org.argeo.security.ui.rap.branding"
+ servletName="logout"
+ defaultEntrypointId="org.argeo.security.ui.rap.logoutEntryPoint"
+ title="Argeo Logout"
+ favicon="branding/favicon.ico"
+ body="branding/afterLogout.html">
+ </branding>
+ <!-- we need a servlet with thios name j_spring_security_logout for the logout filter -->
+ <branding
+ id="org.argeo.security.ui.rap.branding"
+ servletName="j_spring_security_logout"
+ defaultEntrypointId="org.argeo.security.ui.rap.nullEntryPoint"
+ title="Argeo Logout"
+ favicon="branding/favicon.ico"
+ body="branding/empty.html">
+ </branding>
</extension>
<extension
--- /dev/null
+package org.argeo.security.ui.rap;
+
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.rwt.RWT;
+import org.eclipse.rwt.lifecycle.IEntryPoint;
+import org.eclipse.ui.PlatformUI;
+import org.springframework.security.context.SecurityContextHolder;
+
+/**
+ * RAP entry point which logs out the currently authenticated user
+ */
+public class LogoutEntryPoint implements IEntryPoint {
+ private final static Log log = LogFactory.getLog(LogoutEntryPoint.class);
+
+ /**
+ * From org.springframework.security.context.
+ * HttpSessionContextIntegrationFilter
+ */
+ protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
+
+ @Override
+ public int createUI() {
+ // create display
+ PlatformUI.createDisplay();
+
+ final ILoginContext loginContext = SecureRapActivator
+ .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
+ try {
+ loginContext.logout();
+ } catch (LoginException e) {
+ e.printStackTrace();
+ }
+
+ RWT.getRequest().getSession()
+ .removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
+ SecurityContextHolder.clearContext();
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+
+ if (log.isDebugEnabled())
+ log.debug("Logged out session " + RWT.getSessionStore().getId());
+ return 0;
+ }
+}
--- /dev/null
+package org.argeo.security.ui.rap;
+
+import org.eclipse.rwt.lifecycle.IEntryPoint;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * RAP entry point which does doesing except creating the display
+ */
+public class NullEntryPoint implements IEntryPoint {
+ @Override
+ public int createUI() {
+ // create display
+ PlatformUI.createDisplay();
+ return 0;
+ }
+}
package org.argeo.security.ui.rap;
import org.argeo.security.ui.commands.OpenHomePerspective;
-import org.argeo.security.ui.rap.commands.UserMenu;
import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.jface.action.ICoolBarManager;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.springframework.security.BadCredentialsException;
+import org.springframework.security.context.SecurityContext;
+import org.springframework.security.context.SecurityContextHolder;
/**
* RAP entry point with login capabilities. Once the user has been
public class SecureEntryPoint implements IEntryPoint {
private final static Log log = LogFactory.getLog(SecureEntryPoint.class);
+ /**
+ * From org.springframework.security.context.
+ * HttpSessionContextIntegrationFilter
+ */
+ protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
+
/**
* How many seconds to wait before invalidating the session if the user has
* not yet logged in.
// around too long
RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
+ HttpServletRequest httpRequest = RWT.getRequest();
+ HttpSession httpSession = httpRequest.getSession();
+ Object contextFromSessionObject = httpSession
+ .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
+ if (contextFromSessionObject != null)
+ SecurityContextHolder
+ .setContext((SecurityContext) contextFromSessionObject);
+
if (log.isDebugEnabled())
log.debug("THREAD=" + Thread.currentThread().getId()
- + ", sessionStore=" + RWT.getSessionStore().getId());
+ + ", sessionStore=" + RWT.getSessionStore().getId()
+ + ", remote user=" + httpRequest.getRemoteUser());
// create display
final Display display = PlatformUI.createDisplay();
try {
loginContext.login();
subject = loginContext.getSubject();
+
+ if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)
+ httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
+ SecurityContextHolder.getContext());
+
+ // Once the user is logged in, she can have a longer session
+ // timeout
+ RWT.getRequest().getSession()
+ .setMaxInactiveInterval(sessionTimeout);
+ if (log.isDebugEnabled())
+ log.debug("Authenticated " + subject);
} catch (LoginException e) {
BadCredentialsException bce = wasCausedByBadCredentials(e);
if (bce != null) {
}
}
- // Once the user is logged in, she can have a longer session timeout
- RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
- if (log.isDebugEnabled())
- log.debug("Authenticated " + subject);
-
final String username = subject.getPrincipals().iterator().next()
.getName();
// Logout callback when the display is disposed
/** Provides base method for executing code with system authorization. */
public abstract class AbstractSystemExecution {
+ static {
+ // Forces Spring Security to use inheritable strategy
+ // FIXME find a better place for forcing spring security mode
+ // doesn't work for the time besing
+// if (System.getProperty(SecurityContextHolder.SYSTEM_PROPERTY) == null)
+// SecurityContextHolder
+// .setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
+ }
+
private final static Log log = LogFactory
.getLog(AbstractSystemExecution.class);
private AuthenticationManager authenticationManager;
private String systemAuthenticationKey;
/** Whether the current thread was authenticated by this component. */
- private ThreadLocal<Boolean> authenticatedBySelf = new ThreadLocal<Boolean>() {
+ private InheritableThreadLocal<Boolean> authenticatedBySelf = new InheritableThreadLocal<Boolean>() {
protected Boolean initialValue() {
return false;
}
return;
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication currentAuth = securityContext.getAuthentication();
- if (currentAuth != null)
+ if (currentAuth != null){
throw new ArgeoException(
"System execution on an already authenticated thread: "
+ currentAuth + ", THREAD="
+ Thread.currentThread().getId());
-
+ }
Subject subject = Subject.getSubject(AccessController.getContext());
if (subject != null
&& !subject.getPrincipals(Authentication.class).isEmpty())
}
}
- /** Whether the current thread was authenticated by this component. */
+ /**
+ * Whether the current thread was authenticated by this component or a
+ * parent thread.
+ */
protected Boolean isAuthenticatedBySelf() {
return authenticatedBySelf.get();
}
--- /dev/null
+package org.argeo.security.jcr.rememberme;
+
+import java.util.Date;
+
+import org.springframework.security.ui.rememberme.PersistentRememberMeToken;
+import org.springframework.security.ui.rememberme.PersistentTokenRepository;
+
+public class JcrPersistentTokenRepository implements PersistentTokenRepository {
+
+ public void createNewToken(PersistentRememberMeToken token) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void updateToken(String series, String tokenValue, Date lastUsed) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public PersistentRememberMeToken getTokenForSeries(String seriesId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void removeUserTokens(String username) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
<bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
- <sec:filter-chain pattern="/**"
- filters="httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,anonymousProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor" />
+ <sec:filter-chain pattern="/webdav/**"
+ filters="session,basic,rememberMe,anonymous,exception,interceptor" />
+ <sec:filter-chain pattern="/remoting/**"
+ filters="session,basic,rememberMe,anonymous,exception,interceptor" />
+ <sec:filter-chain pattern="/public/**"
+ filters="session,anonymous,exception,interceptorPublic" />
+ <sec:filter-chain pattern="/pub/**"
+ filters="session,anonymous,exception,interceptorPublic" />
+ <sec:filter-chain pattern="/j_spring_security_logout"
+ filters="session,logout,exception" />
</sec:filter-chain-map>
</bean>
<!-- The actual authorization checks (called last, but first here for ease
of configuration) -->
- <bean id="filterInvocationInterceptor" parent="filterInvocationInterceptorTemplate">
+ <bean id="interceptor" parent="filterInvocationInterceptorTemplate">
+ <property name="objectDefinitionSource">
+ <value>
+ PATTERN_TYPE_APACHE_ANT
+ /*/*/*/**=ROLE_USER,ROLE_ADMIN
+ /**=ROLE_ANONYMOUS
+ </value>
+ </property>
+ </bean>
+ <bean id="interceptorPublic" parent="filterInvocationInterceptorTemplate">
<property name="objectDefinitionSource">
<value>
- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
- /public/**=IS_AUTHENTICATED_ANONYMOUSLY
- /*/*/*/**=ROLE_USER
/**=IS_AUTHENTICATED_ANONYMOUSLY
</value>
- <!-- <value> -->
- <!-- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON -->
- <!-- PATTERN_TYPE_APACHE_ANT -->
- <!-- /config/**=ROLE_ADMINISTRATOR -->
- <!-- /**=IS_AUTHENTICATED_ANONYMOUSLY -->
- <!-- </value> -->
</property>
</bean>
<!-- Integrates the authentication information in the http sessions -->
- <bean id="httpSessionContextIntegrationFilter"
+ <bean id="session"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
- <property name="allowSessionCreation" value="true" />
+ <property name="allowSessionCreation" value="false" />
</bean>
<!-- Processes logouts, removing both session informations and the remember-me
cookie from the browser -->
- <bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
- <constructor-arg value="/web/" />
+ <bean id="logout" class="org.springframework.security.ui.logout.LogoutFilter">
+ <constructor-arg value="/webdav/node/main" />
<!-- URL redirected to after logout -->
<constructor-arg>
<list>
</constructor-arg>
</bean>
- <!-- Double check, this may not be necessary -->
- <bean id="securityContextHolderAwareRequestFilter"
- class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter" />
-
<!-- Use the remember me cookie to authenticate -->
- <bean id="rememberMeProcessingFilter"
+ <bean id="rememberMe"
class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="rememberMeServices" ref="rememberMeServices" />
class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService" />
<property name="key" value="${argeo.security.systemKey}" />
+ <property name="tokenValiditySeconds" value="${argeo.jcr.webapp.rememberMeValidity}" />
+ <property name="alwaysRemember" value="true" />
</bean>
<!-- Basic authentication -->
- <bean id="basicProcessingFilter"
+ <bean id="basic"
class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
<property name="authenticationManager">
<ref bean="authenticationManager" />
</bean>
<!-- If everything else failed, anonymous authentication -->
- <bean id="anonymousProcessingFilter"
+ <bean id="anonymous"
class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="${argeo.security.systemKey}" />
<property name="userAttribute" value="anonymous,ROLE_ANONYMOUS" />
</bean>
<!-- Reacts to security related exceptions -->
- <bean id="exceptionTranslationFilter"
+ <bean id="exception"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<ref bean="basicProcessingFilterEntryPoint" />
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:security="http://www.springframework.org/schema/security"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
-
- <security:http>
- <security:intercept-url pattern="/remoting/*"
- access="ROLE_USER,ROLE_ADMIN,ROLE_ANONYMOUS" />
- <security:intercept-url pattern="/*/node/*/**"
- access="ROLE_USER,ROLE_ADMIN" />
- <security:intercept-url pattern="/**"
- access="ROLE_USER,ROLE_ADMIN,ROLE_ANONYMOUS" />
- <security:http-basic />
- <security:anonymous username="anonymous" />
- </security:http>
-
- <!-- LDAP -->
- <security:ldap-authentication-provider
- user-dn-pattern="uid={0},ou=People" group-search-base="ou=Roles"
- group-search-filter="(member={0})" user-details-class="inetOrgPerson" />
- <!-- <security:password-compare> -->
- <!-- <security:password-encoder hash="{ssha}" > -->
- <!-- <security:salt-source system-wide="test"/> -->
- <!-- </security:password-encoder> -->
- <!-- </security:password-compare> -->
- <!-- </security:ldap-authentication-provider> -->
- <security:ldap-server url="ldap://localhost:10389/dc=demo,dc=argeo,dc=org" />
-
-</beans>
\ No newline at end of file
<url-pattern>/remoting/*</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>remoting</servlet-name>
+ <url-pattern>/pub/*</url-pattern>
+ </servlet-mapping>
+
<!-- XML remoting
<servlet>
<servlet-name>xmlremoting</servlet-name>
<servlet-mapping>
<servlet-name>webdav</servlet-name>
- <url-pattern>/public/webdav/*</url-pattern>
+ <url-pattern>/public/*</url-pattern>
</servlet-mapping>
<!-- JCR-MANAGER servlet
argeo.security.systemKey=argeo
+
+argeo.jcr.webapp.rememberMeValidity=3600
\ No newline at end of file
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<import resource="osgi.xml" />
-<!-- <import resource="security.xml" />-->
+ <import resource="security-filters.xml" />
+ <!-- <import resource="security.xml" /> -->
+
+ <bean
+ class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
+ <property name="locations">
+ <value>osgibundle:rap-webapp.properties</value>
+ </property>
+ </bean>
</beans>
\ No newline at end of file
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">\r
\r
- <reference id="_authenticationManager"\r
+ <reference id="authenticationManager"\r
interface="org.springframework.security.AuthenticationManager" />\r
+ <reference id="userDetailsService"\r
+ interface="org.springframework.security.userdetails.UserDetailsService" />\r
</beans:beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
+
+ <bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
+ <sec:filter-chain-map path-type="ant">
+ <sec:filter-chain pattern="/ui"
+ filters="session,basic,rememberMe,exception,interceptor" />
+ <sec:filter-chain pattern="/basicauth"
+ filters="session,basic,exception,interceptor" />
+ <sec:filter-chain pattern="/node" filters="session" />
+ <sec:filter-chain pattern="/public"
+ filters="session,anonymous,exception,interceptorPublic" />
+ <sec:filter-chain pattern="/j_spring_security_logout"
+ filters="session,logout,exception" />
+ </sec:filter-chain-map>
+ </bean>
+
+ <!-- The actual authorization checks (called last, but first here for ease
+ of configuration) -->
+ <bean id="interceptor" parent="filterInvocationInterceptorTemplate">
+ <property name="objectDefinitionSource">
+ <value>
+ PATTERN_TYPE_APACHE_ANT
+ /**=ROLE_USER,ROLE_ADMIN
+ </value>
+ </property>
+ </bean>
+ <bean id="interceptorPublic" parent="filterInvocationInterceptorTemplate">
+ <property name="objectDefinitionSource">
+ <value>
+ PATTERN_TYPE_APACHE_ANT
+ /**=IS_AUTHENTICATED_ANONYMOUSLY
+ </value>
+ </property>
+ </bean>
+
+ <!-- Integrates the authentication information in the http sessions -->
+ <bean id="session"
+ class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
+ <property name="allowSessionCreation" value="true" />
+ </bean>
+
+ <!-- Processes logouts, removing both session informations and the remember-me
+ cookie from the browser -->
+ <bean id="logout" class="org.springframework.security.ui.logout.LogoutFilter">
+ <constructor-arg value="/logout" />
+ <constructor-arg>
+ <list>
+ <ref bean="rememberMeServices" />
+ <bean
+ class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />
+ </list>
+ </constructor-arg>
+ </bean>
+
+ <!-- Use the remember me cookie to authenticate -->
+ <bean id="rememberMe"
+ class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
+ <property name="authenticationManager" ref="authenticationManager" />
+ <property name="rememberMeServices" ref="rememberMeServices" />
+ </bean>
+
+ <bean id="rememberMeServices"
+ class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
+ <property name="userDetailsService" ref="userDetailsService" />
+ <property name="key" value="${argeo.security.systemKey}" />
+ <property name="alwaysRemember" value="true" />
+ </bean>
+
+ <!-- Basic authentication -->
+ <bean id="basic"
+ class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
+ <property name="authenticationManager">
+ <ref bean="authenticationManager" />
+ </property>
+ <property name="authenticationEntryPoint">
+ <ref local="basicProcessingFilterEntryPoint" />
+ </property>
+ <property name="rememberMeServices" ref="rememberMeServices" />
+ </bean>
+
+ <!-- Activate basic auth when needed -->
+ <bean id="basicProcessingFilterEntryPoint"
+ class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
+ <property name="realmName">
+ <value>Argeo</value>
+ </property>
+ </bean>
+
+ <!-- If everything else failed, anonymous authentication -->
+ <bean id="anonymous"
+ class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
+ <property name="key" value="${argeo.security.systemKey}" />
+ <property name="userAttribute" value="anonymous,ROLE_ANONYMOUS" />
+ </bean>
+
+ <!-- Reacts to security related exceptions -->
+ <bean id="exception"
+ class="org.springframework.security.ui.ExceptionTranslationFilter">
+ <property name="authenticationEntryPoint">
+ <ref bean="basicProcessingFilterEntryPoint" />
+ </property>
+ <property name="accessDeniedHandler">
+ <bean class="org.springframework.security.ui.AccessDeniedHandlerImpl">
+ <property name="errorPage" value="/error" />
+ </bean>
+ </property>
+ </bean>
+
+ <!-- Template for authorization checks -->
+ <bean id="filterInvocationInterceptorTemplate" abstract="true"
+ class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
+ <property name="authenticationManager" ref="authenticationManager" />
+ <property name="accessDecisionManager">
+ <bean class="org.springframework.security.vote.AffirmativeBased">
+ <property name="allowIfAllAbstainDecisions" value="false" />
+ <property name="decisionVoters">
+ <list>
+ <bean class="org.springframework.security.vote.RoleVoter" />
+ <bean class="org.springframework.security.vote.AuthenticatedVoter" />
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:security="http://www.springframework.org/schema/security"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
-
- <security:http>
- <security:form-login login-page="/rap?startup=secureWebUi" />
- <security:intercept-url pattern="/**"
- access="ROLE_USER,ROLE_ADMIN,ROLE_ANONYMOUS" />
- </security:http>
-</beans>
\ No newline at end of file
</servlet-mapping>
<!-- Security -->
-<!-- <filter>-->
-<!-- <filter-name>springSecurityFilterChain</filter-name>-->
-<!-- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>-->
-<!-- </filter>-->
+ <filter>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+ </filter>
<!---->
-<!-- <filter-mapping>-->
-<!-- <filter-name>springSecurityFilterChain</filter-name>-->
-<!-- <url-pattern>/*</url-pattern>-->
-<!-- </filter-mapping>-->
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/ui</url-pattern>
+ </filter-mapping>
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/basicauth</url-pattern>
+ </filter-mapping>
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/none</url-pattern>
+ </filter-mapping>
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/public</url-pattern>
+ </filter-mapping>
</web-app>
<Web-ContextPath>org.argeo.rap.webapp</Web-ContextPath>
<Import-Package>
*,
+
+ org.springframework.beans.factory.config,
+
org.eclipse.equinox.http.servlet,
org.springframework.osgi.web.context.support,
org.springframework.security,
+ org.springframework.security.context,
+ org.springframework.security.intercept.web,
+ org.springframework.security.providers.anonymous,
+ org.springframework.security.ui,
+ org.springframework.security.ui.basicauth,
+ org.springframework.security.ui.logout,
+ org.springframework.security.ui.rememberme,
org.springframework.security.ui.webapp,
+ org.springframework.security.userdetails,
+ org.springframework.security.util,
+ org.springframework.security.vote,
+ org.springframework.security.wrapper,
org.springframework.web.context,
org.springframework.web.filter,
org.springframework.web.servlet,
org.springframework.web.servlet.handler,
- org.springframework.web.servlet.mvc
- </Import-Package>
+ org.springframework.web.servlet.mvc,
+
+
+ </Import-Package>
</instructions>
</configuration>
</plugin>
--- /dev/null
+argeo.security.systemKey=argeo