FileDocCategorySizeDatePackage
BlowfishAuthenticationController.javaAPI DocApache Lucene 2.1.09755Wed Feb 14 10:46:06 GMT 2007org.apache.lucene.gdata.server.authentication

BlowfishAuthenticationController

public class BlowfishAuthenticationController extends Object implements AuthenticationController
A {@link org.apache.lucene.gdata.server.authentication.AuthenticationController} implmentation using a Blowfish algorithmn to en/decrpyt the authentification token. The Blowfish algorithmn enables a stateless authetication of the client. The token contains all information to authenticate the client on possible other hosts.

The token contains the first 32 bit of the client ip (e.g. 192.168.0), account name, {@link org.apache.lucene.gdata.data.GDataAccount.AccountRole} and the cration time as a timestamp. The timestamp will be checked on every subsequent request. If the timestamp plus the configured timeout is less than the current time the client has to reauthenticate again.

The auth token returned by the {@link BlowfishAuthenticationController#authenticatAccount(GDataAccount, String)} method is a BASE64 encoded string.

see
javax.crypto.Cipher
see
sun.misc.BASE64Encoder
see
sun.misc.BASE64Decoder
author
Simon Willnauer

Fields Summary
private static final Log
LOG
private static final String
ALG
private static final String
TOKEN_LIMITER
private static final String
ENCODING
private Cipher
deCrypt
private Cipher
enCrypt
private int
minuteOffset
private long
milisecondOffset
private BASE64Encoder
encoder
private BASE64Decoder
decoder
private ReentrantLock
lock
private String
key
Constructors Summary
Methods Summary
public java.lang.StringauthenticatAccount(org.apache.lucene.gdata.data.GDataAccount account, java.lang.String requestIp)

see
org.apache.lucene.gdata.server.authentication.AuthenticationController#authenticatAccount(org.apache.lucene.gdata.data.GDataAccount, java.lang.String)

        try {
            String passIp = requestIp.substring(0, requestIp.lastIndexOf('."));
            String role = Integer.toString(account.getRolesAsInt());

            return calculateAuthToken(passIp, role, account.getName());
        } catch (Exception e) {
            throw new AuthenticatorException("Can not authenticat account -- "
                    + e.getMessage(), e);

        }
    
public booleanauthenticateToken(java.lang.String token, java.lang.String requestIp, org.apache.lucene.gdata.data.GDataAccount.AccountRole role, java.lang.String accountName)

see
org.apache.lucene.gdata.server.authentication.AuthenticationController#authenticateToken(java.lang.String, java.lang.String, org.apache.lucene.gdata.data.GDataAccount.AccountRole, java.lang.String)

        if (LOG.isInfoEnabled())
            LOG.info("authenticate Token " + token + " for requestIp: "
                    + requestIp);
        if (token == null || requestIp == null)
            return false;
        String passIp = requestIp.substring(0, requestIp.lastIndexOf('."));
        String authString = null;
        try {
            authString = deCryptAuthToken(token);
        } catch (Exception e) {
            throw new AuthenticatorException("Can not decrypt token -- "
                    + e.getMessage(), e);
        }
        if (authString == null)
            return false;
        try {
            StringTokenizer tokenizer = new StringTokenizer(authString,
                    TOKEN_LIMITER);
            if (!tokenizer.nextToken().equals(passIp))
                return false;
            String tempAccountName = tokenizer.nextToken();
            int intRole = Integer.parseInt(tokenizer.nextToken());
            /*
             * Authentication goes either for a account role or a account. For
             * entry manipulation the account name will be retrieved by the
             * feedId otherwise it will be null If it is null the authentication
             * goes against the account role
             */
            if (tempAccountName == null
                    || (!tempAccountName.equals(accountName) && !GDataAccount
                            .isInRole(intRole, role)))
                return false;
            long timeout = Long.parseLong(tokenizer.nextToken());

            return (timeout + this.milisecondOffset) > System
                    .currentTimeMillis();
        } catch (Exception e) {
            LOG.error("Error occured while encrypting token " + e.getMessage(),
                    e);
            return false;
        }

    
protected java.lang.StringcalculateAuthToken(java.lang.String ipAddress, java.lang.String role, java.lang.String accountName)

        StringBuilder builder = new StringBuilder();
        builder.append(ipAddress).append(TOKEN_LIMITER);
        builder.append(accountName).append(TOKEN_LIMITER);
        builder.append(role).append(TOKEN_LIMITER);
        builder.append(System.currentTimeMillis());

        this.lock.lock();
        try {
            byte[] toencode = builder.toString().getBytes(ENCODING);
            byte[] result = this.enCrypt.doFinal(toencode);
            return this.encoder.encode(result);
        } finally {
            this.lock.unlock();

        }

    
private voidcalculateTimeOffset()

        this.milisecondOffset = this.minuteOffset * 60 * 1000;
    
protected java.lang.StringdeCryptAuthToken(java.lang.String authToken)

        this.lock.lock();
        try {
            byte[] input = this.decoder.decodeBuffer(authToken);
            byte[] result = this.deCrypt.doFinal(input);
            return new String(result, ENCODING);
        } finally {
            this.lock.unlock();
        }

    
public voiddestroy()

see
org.apache.lucene.gdata.server.registry.ServerComponent#destroy()

        //
    
public java.lang.StringgetKey()

return
Returns the key.

        return this.key;
    
public intgetLoginTimeout()

return
Returns the minuteOffset.

        return this.minuteOffset;
    
public voidinitialize()

see
org.apache.lucene.gdata.server.authentication.AuthenticationController#initialize()


           
       
        if (this.key == null)
            throw new IllegalArgumentException("Auth key must not be null");
        if (this.key.length() < 5 || this.key.length() > 16)
            throw new IllegalArgumentException(
                    "Auth key length must be greater than 4 and less than 17");

        try {
            Provider sunJce = new com.sun.crypto.provider.SunJCE();
            Security.addProvider(sunJce);
            KeyGenerator kgen = KeyGenerator.getInstance(ALG);
            kgen.init(448); // 448 Bit^M
            byte[] raw = this.key.getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, ALG);
            this.deCrypt = Cipher.getInstance(ALG);
            this.enCrypt = Cipher.getInstance(ALG);
            this.deCrypt.init(Cipher.DECRYPT_MODE, skeySpec);
            this.enCrypt.init(Cipher.ENCRYPT_MODE, skeySpec);
        } catch (Exception e) {
            throw new AuthenticatorException(
                    "Can't initialize BlowfishAuthenticationController -- "
                            + e.getMessage(), e);

        }
        calculateTimeOffset();
    
public voidsetKey(java.lang.String key)

param
key The key to set.

        this.key = key;
    
public voidsetLoginTimeout(int minuteOffset)

param
minuteOffset The minuteOffset to set.

        this.minuteOffset = minuteOffset;
        calculateTimeOffset();