Thursday, 5 June 2014

Apache Shiro-Part I -Basic Introduction

Apache Shiro:

Introduction

Apache Shiro is an easy to use Java security framework. Shiro's predecessor was JSecurity which was submitted to Apache software Foundation in 2008. It provides robust functionalities associated with security in application ranging from smallest mobile application to largest web and enterprise applications. In short it handles the security related challenges to the following facets.


  • Authentication
  • Authorization
  • Cryptography
  • Session Management
  • Web Integration


Authentication

It is a process of verifying users identity based on some kinds of proofs or identity that a system can understand and trust. Almost everything that is executing in system is based on the current user of an application which is known as subject in Shiro.  It has a built in Remember Me feature that provides an ability to remember the users once they return to an application.

Authorization

It is mechanism of providing access control for a particular user. It determines what resources of an application can be granted to a particular user. For ex- is the current user is able to view financial transactions of the organization? Based on varying needs of an application, the authorization in shiro can be granted based on their roles and permissions associated with them. The permission and roles can be configured in variety of sources like Database, text based configuration file, LDAP etc. It provides support for wildcard permissions that helps to model fine grained access policies to an application. Furthermore authorization can be done based on AOP, JDK 1.5 annotations and JSP tag library.

Cryptography

Cryptography is a technique of protecting an information through an undesired access by hiding it or converting the data into non-understandable format. Shiro majorly focuses on 2 ways of cryptograph: Ciphers – that encrypt data like email with public and private key and Hashes- that irreversibly encrypts data like security password using message digests algorithms such as md5, SHA,SHA-256  etc.


Shiro Architecture


The above diagram shows the basic functional mechanism of Shiro embedded application. The application code will be integrated with shiro based security mechanism. In order to achieve it, the application needs to invoke the subject which will identity the interacting user to an application. Next the subject will communicate with the security manager that manages all the security related operations for the user. It is an umbrella object that references many internal security related components. The security manager in turn will communicate with configured realms in chain to verify the credentials associated with the subject/current user. Basically Realm acts as a bridge between shiro and application security data. It’s a security related data access object. The  below diagram shows its detailed aspects.



Fig: The detailed components of Shiro Architecture

Let’s look at basic example on implementation of Apache shiro.

Step1: Create a simple maven project and add the following dependencies:


    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Step 2: Create shiro.ini file in /resources folder of your project and add the below configuration.


[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
guest = guest123, basic

# -----------------------------------------------------------------------------
# Roles with assigned permissions
# 
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
basic = read


As shown in above configuration file tag [users] is enlisting all the users with their current passwords and associated roles. Tag [roles] will specify what permission can be granted for the particular user.  A wildcard * simply indicates that the current user  having particular  role is granted all the permissions.  

Step3:  Now we have defined configuration file, so we are set to write a sample code and execute it.


/**
 * A simple application showing how to use Shiro
 * *
 */
public class HelloShiro{

    private static final transient Logger log = LoggerFactory.getLogger(HelloShiro.class);

    public static void main(String[] args) {

        // Use the shiro.ini file at the root of the classpath
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
   SecurityUtils.setSecurityManager(securityManager);


        // get the currently executing user:
        Subject currentUser = SecurityUtils.getSubject();

        // Do some stuff with a Session (no need for a web or EJB container!!!)
        Session session = currentUser.getSession();
        session.setAttribute("apiKey", "xyewldie");
        String value = (String) session.getAttribute("apiKey");
        if (value.equals("apiKey ")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }

        // login the current user so we can check against roles and permissions:
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("root", "secret");
            token.setRememberMe(true);
            try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition 
            }
        }

        //Current user principal (in this case, a username):
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");

        //test a role:
        if (currentUser.hasRole("admin")) {
            log.info("Welcome Admin!");
        } else {
            log.info("Sorry! You are not administrator");
        }

        //test a typed permission (not instance-level)
        if (currentUser.isPermitted("read")) {
            log.info("You are allowed to read information");
        } else {
            log.info("Sorry, you can’t read information..");
        }

        //all done - log out!
        currentUser.logout();

        System.exit(0);
    }
}



Thats all from my sides !! Please wait for my next successive article on shiro partII .Till than enjoy up !! Cheers ..!!










No comments:

Post a Comment