Quick Introduction to Apache Shiro

Please note that this article is not going to cover all the aspects of Apache Shiro or even all the features. This can be used as a “Quick Glance at Apache Shiro for Java Programmers” or as a quick catch up.

What is Apache Shiro?

  • Shiro is a Java security framework which is intended to be used in client applications which can be web application or even stand alone application.
  • Shiro APIs implements JAAS (Java Authentication and Authorization Service) features and enhance the usage.It enables authentication, authorization, cryptography, and session management within an application.
  • Shiro does not provide SSO service out of the box at the moment.

Though this can be used in both Java web applications and alone applications, I am going to brief following Topics with considering only usage in Java web applications.

  1. Framework Basics
  2. Security Implementation
  3. Framework Limitations

1.Framework Basics

There are 3 key concepts you have to think about if you are using Apache Shiro

  • Subject
  • Security Manager
  • Realm

Subject <=> the currently executing user

  • Shiro is entirely built around Subject. And all functionality of an application is represented and secured based on a per-user basis. i.e Subject.
  • Subjects can be maintained across threads (Threading and Concurrency).
  • Developer can access ‘Subject’ anywhere in code which allows security operations to occur anywhere.

import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;

Subject currentUser = SecurityUtils.getSubject();

Security Manager

  • Counterpart of subject: actually handles security behind the scene.
  • ‘Shiro Servlet’ Filter can be specified in web.xml of a web application and that will set up the SecurityManager instance.
  • This instance would be a singleton for an application. By default configured via an ini(can be configured with POJO-compatible configuration mechanisms).

Example Filter

<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>
org.apache.shiro.web.servlet.IniShiroFilter
</filter-class>
<!– no init-param means load the INI config from classpath:shiro.ini –>

</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Descriptive shiro.ini

# =======================
# Shiro INI configuration
# =======================
[main]
# Objects and their properties are defined here,
# Such as the securityManager, Realms and anything
# else needed to build the SecurityManager

[users]
# The ‘users’ section is for simple deployments
# when you only need a small number of statically-defined
# set of User accounts.

[roles]
# The ‘roles’ section is for simple deployments
# when you only need a small number of statically-defined
# roles.

[urls]
# The ‘urls’ section is used for url-based security
# in web applications. We’ll discuss this section in the
# Web documentation

Realms

  • bridge between Shiro and application’s security data. Such as user accounts (LDAP or User Data Base) to perform authentication and authorization.
  • One or more realms can be configured for an application.

Example LDAP configuration defined in shiro.ini

[main]
ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm.userDnTemplate = uid={0},ou=users,dc=yourdc,dc=com
ldapRealm.contextFactory.url = ldap://ldapHost:389
ldapRealm.contextFactory.authenticationMechanism = DIGEST-MD5

 

2.Security Implementation

Authentication Handling

AuthenticationToken token = new UsernamePasswordToken(username, password);//Acquire submitted principals and credentials

Subject currentUser = SecurityUtils.getSubject();//Get the current Subject

//Login
currentUser.login(token);//Login

Access Control

if ( subject.hasRole(“administrator”) ) //check role
if ( subject.isPermitted(“user:create”) ) //check permission
if ( subject.isPermitted(“user:delete:jsmith”) ) //check instance permission

Session Handling

  • Capable of handling both Usual Http Sessions and Shiro’s native sessions which are capable of Shiro features.

Session session = subject.getSession();
session.getAttribute(“key”, someValue);
Date start = session.getStartTimestamp();
Date timestamp = session.getLastAccessTime();
session.setTimeout(millis);

Content Filtering in JSP

  • There is a set of Shiro specific tag set

<shiro:hasRole name=”admin”> | <a href=”admin/index.jsp” >Admin Area</a></shiro:hasRole>

3.Framework limitations

  • Does not deal with Virtual Machine level security.
  • No Realm Write Operations.(i.e cannot create new accounts)

Here are some useful links if you want to get in to Apache Shiro.

How did I fix Ubuntu + McAfee Issue

Let me start with the story, Before couple of months back this issue was noticed in my office in which there is a hybrid environment with vulnerable Windows and Ubuntu. IT policies wanted an an anti-virus on Ubuntu and they had already purchased McAfee. After installing McAfee on Ubuntu we noticed that if we install, uninstall or reconfigure other software using apt-* ,synaptic or software center which crashes the machine ; it will not not open any program and if you reboot at that time it will unusable at all.
At that time I was not in the scene and my fellow engineers and McAfee had identified why machine was crashing. It is because McAfee installs some loaders in to /lib folder which loaders abuse soname conversions like this.

ishan@iambanwela:~$ ls -l /lib | grep ld-
lrwxrwxrwx  1 root root     25 Feb 20 12:16 ld-linux.so.2 -> i386-linux-gnu/ld-2.15.so
lrwxrwxrwx  1 root root     41 Feb 15 17:13 ld-mfert.so.2 -> /opt/McAfee/runtime/2.0/lib/ld-linux.so.2
lrwxrwxrwx  1 root root     41 Feb 15 17:05 ld-mfert.so.2.old -> /opt/McAfee/runtime/2.0/lib/ld-linux.so.2
lrwxrwxrwx  1 root root     38 Feb 15 17:06 ld-nails.so.2 -> /opt/NAI/LinuxShield/lib/ld-linux.so.2

if you use synaptic, software center, apt-get or apt-* machine will be crashed and will not boot again. In the same way if you manually run ldconfig this happens. For to explain the issue I installed some software. So that I boot the machine with a live CD,mount the HDD and it was like this

ubuntu@ubuntu:~$ cd /media/bde36629-6bdf-402e-9d2b-eec66e76b672/lib
ubuntu@ubuntu:/media/bde36629-6bdf-402e-9d2b-eec66e76b672/lib$ ls -l |grep ld-
lrwxrwxrwx  1 root root     13 Feb 20 16:26 ld-linux.so.2 -> ld-nails.so.2
lrwxrwxrwx  1 root root     41 Feb 15 17:13 ld-mfert.so.2 -> /opt/McAfee/runtime/2.0/lib/ld-linux.so.2
lrwxrwxrwx  1 root root     41 Feb 15 17:05 ld-mfert.so.2.old -> /opt/McAfee/runtime/2.0/lib/ld-linux.so.2
lrwxrwxrwx  1 root root     38 Feb 15 17:06 ld-nails.so.2 -> /opt/NAI/LinuxShield/lib/ld-linux.so.2

probably you might understood the problem now and you can simply fix this using

$sudo ln -snf i386-linux-gnu/ld-2.15.so ld-linux.so.2

since this is occurred after run ldconfig I looked in to ldconfig script as well as where does it come from. ldconfig comes with libc-bin package and libc-bin comes with glibc and it is compiled from eglibc package which I downloaded here for Ubuntu 12.04.

Inside eglibc_2.15.orig.tar.gz package in eglibc-2.15/elf folder ldconfig.c can be found. In ldconfig.c file I found that dynamic linker is also considered as shared library and which looks for “ld-” and load.

/* Does this file look like a shared library or is it a hwcap
subdirectory?  The dynamic linker is also considered as
shared library.  */
if (((strncmp (direntry->d_name, “lib”, 3) != 0
&& strncmp (direntry->d_name, “ld-“, 3) != 0)
|| strstr (direntry->d_name, “.so”) == NULL)
&& (
#ifdef _DIRENT_HAVE_D_TYPE
direntry->d_type == DT_REG ||
#endif
!is_hwcap_platform (direntry->d_name)))
continue;

size_t len = strlen (direntry->d_name);

now I know the logic of dynamic linker. In this stage I got 2 paths to solve this
1.Change ldconfig.c and recompile and install(but obviously we will break conventions and this might disable future updates of ld-2.15.so )
2.Change ldconfig script which executes ldonfig.real

so I tried 2nd option first.
The last line of /sbin/ldconfig script was

exec /sbin/ldconfig.real “$@”

so that I removed exec and put a line to create the broken link so that it was like this

/sbin/ldconfig.real “$@”
cd /sbin/
sudo ln -snf i386-linux-gnu/ld-2.15.so ld-linux.so.2

This worked for me and I tried 1st option also.
I edited (direntry->d_name, “ld-“, 3) != 0 to look for not only “ld-” but also for “ld-2” like this (direntry->d_name, “ld-2”, 4) != 0 and compiled.

Compilation was little bit tricky, it took some time to fix dependencies with configure script, make and make install. In READ ME of eglibc warned; this might make your machine very unstable…!
But after some time I installed it and worked still that machine did not crash.

For my company I recommended to edit ldconfig script.

Here McAfee has stated the issue

https://kc.mcafee.com/corporate/index?page=content&id=KB76919

and here in Launchpad, Ubuntu(Canonical) has rejected the bug

https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/915995