Apache Shiro

Java Security Framework

Joe Chou

Outline

What is Shiro

Main ideas of Shiro

Try It Yourself

    - An INI Realm

    - My Customize Realm

    - Some Defined Realms

    - Shiro in Webapp

    - Integrate with Spring MVC

Today's Target

Understand what is Shiro

Understand how to use Shiro in my project

What is Shiro

Google Translate says...四郎

WTF

or it probably is...白

or not

The most possible is 

Castle / 城 in Japanese

If you were a king,

what can a castle do for you?

To claim a land as my realm. Everyone has to obey my law!!

 

To ensure my people's security.

 

To protect a king from enemies.

 

 

Remember AOE?

Also,

that's what Shiro do for you

And you are the king.

Main ideas of Shiro

Realm

Principal

Authorization

Authentication

Subject

A Realm is...

A scope which defines a set of principals to make users obey.

It can be applied on one or more applications.

A Principal is...

A set of rules to determine what a user can do in this realm.

A Subject is...

A session which represents a user who is now using your application.

Modules

shiro-core

The basic kernel of shiro framework.

shiro-web

Supporting of webapps.

shiro-aspectj

Supporting of Shiro AOP annotations.

shiro-spring

Integration with Spring framework.

shiro-ehcache

Supporting of Shiro cache based on Ehcache.

shiro-quartz

Supporting of Shiro session validation scheduling based on Quartz.

Try It Yourself

Time to get started!

Before starting...

We need

    JDK 1.5+,

    Maven 2.2+,

    Spring Tool Suite,

    Git plug-in,

    and GitHub account.

clone: https://github.com/dontpkme/ShiroSample.git

An INI Realm

At first, you need the core module

  <dependency>
  	<groupId>org.apache.shiro</groupId>
  	<artifactId>shiro-core</artifactId>
  	<version>1.2.3</version>
  </dependency>

The default way to setup Shiro using .ini file

[users]
Joe = joe, warrior
Asip = asip, ranger
Kirin = kirin, swordman, fighter
Jimmy = jimmy, archer
Study = study, mage
Newbie = newbie


[roles]
warrior = melee:*
ranger = melee:stab, dodge
swordman = melee:slash, parry
fighter = melee:punch, dodge
archer = shoot
mage = "cast:fireball,blizzard", heal

Sample code snippets

Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);

Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
currentUser.login(token);

if(currentUser.hasRole("user"))
    System.out.println("you are a user");

if(currentUser.isPermitted("edit"))
    System.out.println("you can edit");

Try it in branch <ini-realm>

My Customize Realm

The default way to setup Shiro using .ini file

[main]
myRealm = realm.CustomizeRealm

Sample code snippets

public class CustomizeRealm extends AuthorizingRealm {

    protected SimpleAccount getAccount(String username) {
        SimpleAccount account = new SimpleAccount(username, pwdTable.get(username), getName());
        ArrayList<String> userRoles = userRoleTable.get(username);
        for(String role: userRoles) {
        	account.addRole(role);
        	account.addStringPermissions(rolePermTable.get(role));
        }
        return account;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
        throws AuthenticationException {
    	UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        return getAccount(upToken.getUsername());
    }

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) getAvailablePrincipal(principals);
        return getAccount(username);
    }
}

Try it in branch <my-customize-realm>

Some Defined Realms

For LDAP

  • ActiveDirectoryRealm
  • JndiLdapRealm

For CAS

  • CasRealm

For DB

  • JdbcRealm

Shiro in Webapp

You need the web module

<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-web</artifactId>
	<version>1.2.3</version>
</dependency>
<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

add Shiro Listener into web.xml

// Factory<SecurityManager> factory = new IniSecurityManagerFactory("/shiro.ini");
// SecurityManager securityManager = factory.getInstance();
// SecurityUtils.setSecurityManager(securityManager);

and you don't need this now

this will be handled by listener

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

add Shiro Filter into web.xml

Set Shiro Filter in shiro.ini

[urls]
/logout.jsp = logout
/index.jsp = authc
/ = authc
/admin/** = roles[GM]

More Filters can use..

Shiro's Taglib

to check permission or role in JSP page

<shiro:lacksRole name="warrior">
Guild Keeper: "You are not a warrior, Get out."
</shiro:lacksRole>

<shiro:hasRole name="warrior">
Guild Keeper: "You are a warrior, welcome!"
</shiro:hasRole>
<shiro:hasPermission name="melee:punch">
Gate Keeper: "You know how to punch. You must be a warrior or a fighter!"
</shiro:hasPermission>

<shiro:lacksPermission name="melee:punch">
Gate Keeper: "You don't know how to punch. Get out!"
</shiro:lacksPermission>

Try it in branch <shiro-in-webpp>

Integrate with Spring MVC

Work In Progress

That's all

Reference

Shiro

By dontpkme