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.
 

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

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


six − 5 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
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.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close