Idan Fridman

About Idan Fridman

Idan is Software engineer with experience in Server side technologies. Idan is responsible for various infrastructure models in the software industry(Telecommunications, Finance).

Authentication and Authorization as an open source solution service

Designing a centralized service for all user data by implementing authentication and authorization (a&a) mechanism. I’ll share my experience and finalize conclusions for a solution.

The design includes the clients (Web applications) and the server (a&a center).

Terminology:

 
 
 

1. Authentication:

Authentication is the mechanism whereby systems may securely identify their users. Answering the question “Who is the User?” Authentication also includes SSO (Single sign on). A mechanism which giving the users the ability to sign-on once and get ‘free pass’ to all participating resources without an additional sign’s.

2. Authorization:

Authorization is the process of verifying if the user has role/permission to access certain resources or sections.
Answering the question: Is user X authorized to access resource/Operation Y?

3. Secured clients:

Usually the a&a mechanism working against secured client frameworks: Spring security, Apache Shiro, Wicket Authentication and so on. I will review these later on that post.

Main subjects to consider:

  1. Authentication server
  2. Secured web clients framework
  3. Authorization responsibilities

Full solution providers:

In my research I came across full solution providers:

  • Open AM ( known as OpenSSO) –  They claim to be an open source project. But after a little while you find out that it’s indeed an open source but not for a commercial use. You need to pay big amount of $$$ for having their a&a package.
  • Crowd – By Atlassian. Seems like a fast, good and very cheap solution. But we still heading into a completely commercial open source solution. This one didn’t fit our needs as well.

Secured Clients:

  • Spring Security:  Very popular and widely used. Spring Security demands lots of xml configurations when you want to have more than just a basic setup.
  • Additionally if you need to support permissions (and not just roles), Spring security doesn’t support it out of the box.

  • Apache Shiro: – Great product. Very straight forward configuration and permissions support out of the box.
  • The problem is that Shiro’s community still considered small and the project is pretty new.

Solution:

  1. Authentication server:

    I came across CAS (Central Authentication Serivce) -  great and completely open source project. CAS provides SSO solutions and supports popular protocols such as SAML, OPENID, Auth.

    So if we integrate CAS with an LDAP server (To hold our users’ information) we achieve our authentication model (and having SSO out of the box).

    CAS is based on Spring and very easy to extend in case we want to make custom changes. You can download the source code easily and custom it the way you want it.

    CAS configuration is pretty easy and well documented.

  2. Secured clients framework:

    I chose Spring Security. Three reasons:

    1. The web application is a Spring based.
    2. Popular and the community behind is more than enough.
    3. Integrates perfectly with CAS.

    * I mention that Spring security lack of permissions. But there’s a workaround. Short example can be found here: http://en.tekstenuitleg.net/blog/spring-security-with-roles-and-rights

    So far we have Spring Security, Cas, and LDAP (OpenLdap) server.

  3. Authorization responsibilities:

    That one might be tricky depends on your project requirements. You could configure your authorization flow in two ways:

    1. Centralized authorization:

      CAS support attributes. That means you could add additional attributes (roles/permissions) to the returning response (via SAML it’s pretty straightforward).

      You could actually choose and configure from which source to pull the additional attributes (Database, Ldap, Active Directory and more).

      That’s a very neat and elegant solution –  one central which able to deliver on request the authentication and the authorization roles/permissions per user.

    2. Decentralize authorization:

      You could configure Spring Security by extending the UserDetails interface. And then let each application to control the authorization logic after a successful authentication.

      * There is an open debate whether each web client application should be responsible for its authorization logic or centralized it (As I described at Point No. 1).

    I suggest to determine the right attitude by your project requirements use cases.

We finished by having a completely a&a open source solution for commercial use.
 

Related Whitepaper:

Best Practices for Secure Software Development

Best practices for all organizations that would like to produce more secure applications!

As part of the software development process, security professionals must make choices about where to invest their budget and staff resources to ensure that homegrown applications are as secure as possible. ESG research found organizations that are considered security leaders tend to make different choices than other firms.

Get it Now!  

One Response to "Authentication and Authorization as an open source solution service"

  1. ibrahim says:

    i have problem in this code

    /*
    * To change this template, choose Tools | Templates
    * and open the template in the editor.
    */
    package streamciphera51;

    /**
    *
    * @author rashed
    */

    package com.myapp.util.security.crypt2;
    import java.security.MessageDigest;

    import java.security.NoSuchAlgorithmException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.BitSet;
    import java.util.List;
    import java.util.Random;

    import java.util.Vector;
    import renderable;

    public final class StreamCipherA51 {

    private final ShiftRegister[] registers;
    private final List registersList;

    public StreamCipherA51() {
    registers = new ShiftRegister[] {
    new ShiftRegister(19, new int[] { 18, 17, 16, 13 }, 8),
    new ShiftRegister(22, new int[] { 21, 20 }, 10),
    new ShiftRegister(23, new int[] { 22, 21, 20, 7 }, 10) };

    registersList = Arrays.asList(registers);
    }

    public void clearAll() {
    for (ShiftRegister shiftRegister : registers)
    shiftRegister.clear();
    }

    @SuppressWarnings(“unused”)
    private synchronized void init(byte[] cipherPassword) {
    BitSet bytesBits = null;

    eachByteOfPassword: for (int i = 0; i < cipherPassword.length; i++) {
    bytesBits = CryptUtils.byteToBitSet(cipherPassword[i]);

    eachBitOfPasswordByte: for (int j = 0; j < 8; j++) {
    final boolean bit = bytesBits.get(i);

    eachRegister: for (ShiftRegister register : registers)
    register.shift(bit ^ register.getFeedBack());
    }
    }

    hundredTimes: for (int i = 0; i < 100; i++)
    eachRegister: for (ShiftRegister register : registers)
    register.shift(register.getFeedBack());
    }

    private boolean shiftRegisters(List regs2shift) {
    boolean firstLoop = true;
    boolean retval = false;

    for (ShiftRegister var : regs2shift)
    if (firstLoop) {
    firstLoop = false;
    retval = var.shift();
    } else
    retval ^= var.shift();

    return retval;
    }

    /**the majority of the registers with the same shiftcontrolflag is being shifted*/
    private boolean shiftNextBit() {
    List maybeShifted = new ArrayList(
    3);

    for (ShiftRegister r : registers)
    if (r.getShiftFlag())
    maybeShifted.add(r);

    int size = maybeShifted.size();
    switch (size) {

    case 0: /*shift all*/
    case 3: /*shift all*/
    return shiftRegisters(Arrays.asList(registers));

    case 1: { /*shift only others*/
    List all = new ArrayList(2);
    all.addAll(registersList);
    all.removeAll(maybeShifted);

    return shiftRegisters(all);
    }

    case 2: { /*shift maybeShifted only*/
    return shiftRegisters(maybeShifted);
    }
    } throw new RuntimeException(
    “number of registers bigger than 3 !”);
    }

    private BitSet tempBitSet1 = null;
    private BitSet tempBitSet2 = null;

    /**bitwise xor of plainbyte and cipherbyte*/
    byte cipherNextByte(byte input) {
    tempBitSet1 = CryptUtils.byteToBitSet(input);
    tempBitSet2 = new BitSet();

    for (int i = 0; i < 8; i++)
    tempBitSet2.set(i, shiftNextBit());

    for (int i = 0; i < 8; i++)
    tempBitSet1.set(i, tempBitSet2.get(i) ^ tempBitSet1.get(i));

    return CryptUtils.bitSetToByte(tempBitSet1);
    }

    int cipherNextInt(int input) {
    BitSet bs = CryptUtils.byteToBitSet(CryptUtils.intToByte(input));

    for (int i = 0; i < 8; i++)
    bs.set(i, shiftNextBit() ^ bs.get(i));

    return CryptUtils.bitSetToInt(bs);
    }

    public void init(String password) {
    clearAll();

    MessageDigest md;
    try {/*generate a sha1-byte[] from the password to init registers with*/
    md = MessageDigest.getInstance("SHA1");
    } catch (NoSuchAlgorithmException ex) {
    throw new RuntimeException(ex);
    }

    byte[] registerInitBytes = md.digest(password.getBytes());
    init(registerInitBytes);
    }

    public static void main(String args) {

    StreamCipherA51 a51 = new StreamCipherA51();
    com.myapp.util.security.crypt.StreamCipherA51 referenecA51 = newcom.myapp.util.security.crypt.StreamCipherA51();
    referenecA51.init("secr3t");

    int len = 5;

    byte[] barrOrigin = new byte[len];
    byte[] barrCryptd = new byte[len];
    byte[] barrEncryp = new byte[len];
    byte[] barrCryptd2 = new byte[len];
    byte[] barrEncryp2 = new byte[len];

    new Random().nextBytes(barrOrigin);

    System.out.println("barrOrigin :"
    + CryptUtils.byteArrToBinString(barrOrigin));

    a51.init("secr3t");
    for (int i = 0; i < len; i++)
    barrCryptd[i] = a51.cipherNextByte(barrOrigin[i]);

    System.out.println("barrCryptd :"
    + CryptUtils.byteArrToBinString(barrCryptd));

    a51.init("secr3t");
    for (int i = 0; i < len; i++)
    barrEncryp[i] = a51.cipherNextByte(barrCryptd[i]);

    System.out.println("barrEncryp :" + CryptUtils.byteArrToBinString(barrEncryp));

    System.out.println("———————————-");

    System.out.println("barrOrigin :"
    + CryptUtils.byteArrToBinString(barrOrigin));

    referenecA51.init("secr3t");
    for (int i = 0; i < len; i++)
    barrCryptd2[i] = referenecA51.cipherNextByte(barrOrigin[i]);

    System.out.println("barrCryptd2:"
    + CryptUtils.byteArrToBinString(barrCryptd2));
    referenecA51.init("secr3t");
    for (int i = 0; i < len; i++)
    barrEncryp2[i] = referenecA51
    .cipherNextByte(barrCryptd2[i]);

    System.out.println("barrEncryp2:"+ CryptUtils.byteArrToBinString(barrEncryp2));
    }

    }

Leave a Reply


seven × = 42



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books
Get tutored by the Geeks! JCG Academy is a fact... Join Now
Hello. Add your message here.