Skip to main content

How to perform Authorization in Java with Apache Shiro

Authorization in Shiro can be handled in four ways.
  • Programmatically - You can perform authorization checks in your java code with structures like if and else blocks.
  • JDK annotations - You can attach an authorization annotation to your Java methods
  • JSP/GSP TagLibs - You can control jsp or gsp page output based on roles and permissions

Programmatic Authorization

Checking for permissions and roles, programmatically in your Java code is the traditional way of handling authorization. Here's how you can perform a permission check or role check in Shiro.

Role Check

This is an example of how you do a role check programmatically in your application. We want to check if a user has the administrator role and if they do, then we'll show a special button, otherwise we won't show it.
First we get access to the current user, the Subject. Then we pass the adminstrator to the Subject's .hasRole() method. It will return TRUE or FALSE.
//get the current Subject
Subject currentUser =

if (currentUser.hasRole(“administrator”)) {
    //show a special button‏
} else {
    //don’t show the button?)‏
Now a role based check is quick and easy to implement but it has a major drawback. It is implicit.
What if you just want to add, remove, or redefine a role later? You'll have to crack open your source code and change all your role checks to reflect the change in your security model. You'll have to shut down the application, crack open the code, test it, and then restart it everytime.
In very simple applications this is probably good enough but for larger apps this can be a major problem throughout the life of your application and drive a large maintenance cost for your software.

Permission Check

This is an example of how you do security checks by permission. We want to check if a user has permission to print to laserjet3000n and if they do, then we'll show a print button, otherwise we won't show it. This is an example of an instance level permission or instance level authorization.
Again, first you get access to the current user, the Subject. Then you construct a Permission object or an instance that represents an action on a resource. In this case, the instance is named printerPermission, the resource is laserjet3000n, and the action is print. Then we pass printerPermission to the Subject's .isPermitted() method. It will return true or false.
Subject currentUser =

Permission printPermission = 
new PrinterPermission(“laserjet3000n”,“print”);

If (currentUser.isPermitted(printPermission)) {
    //do one thing (show the print button?)‏
} else {
    //don’t show the button?

Permission Check (String-based)

You can also a permission check using a simple string instead of a permission class.
So, if you don't want to implement our permission interface then you just pass in a String. In this example, we pass the .isPermitted() method a string, printer:print:LaserJet4400n
String perm = “printer:print:laserjet4400n”;

    //show the print button?
} else {
    //don’t show the button?
You can construct the permission string the way you want so long as your Realm knows how to work with it. In this example we use Shiro's optional permission syntax, WildCardPermissions. WildCardPermissions are powerful and intuitive. If you'd like to learn more about them then check out the Permissions Documentation.
With string-based permission checks, you get the same functionality as the example before. The benefit is that you are not forced to implement a permission interface and you can construct the permission via a simple string. The downside is that you don't have type safety and if you needed more complicated permission capabilitues that are outside the scope of what this represents, you're going to want to implement your own permission objects based on the permission interface.

Annotation Authorization

If you don't want to do code level authorization checks, then you can use Java Annotations as well. Shiro offers a number of Java annotations that allow you to annotate methods.

Enabling Annotation Support

Before you can use Java annotations, you'll need to enable AOP support in your application. There are a number of different AOP frameworks so, unfortunately, there is no standard way to enable AOP in an application.
For AspectJ, you can review our AspectJ sample application.
For Spring, you can look into our Spring Integration documentation.
For Guice, you can look into our Guice Integration documentation.

Permission Check

In this example, we want to check that a user has the account:create permission before they can invoke the openAccount method. If they do, then the method is called as expected, and if they don't, then an exception is thrown.
Like programmatic checks, you can use the Permission objects or the simple string methods with this annotation.
//Will throw an AuthorizationException if none
//of the caller’s roles imply the Account 
//'create' permission\u000B
public void openAccount( Account acct ) { 
    //create the account

Role Check

In this example, we want to check that a user has the teller role before they can invoke the openAccount method. If they do, then the method is called as expected, and if they don't, then an exception is thrown.
//Throws an AuthorizationException if the caller
//doesn’t have the ‘teller’ role:

@RequiresRoles( “teller” )
public void openAccount( Account acct ) { 
    //do something in here that only a teller
    //should do

JSP TagLib Authorization

For JSP/GSP based web applications, Shiro also offers a tag library for you to use.
In this example, we're going to show users with the users:manage permission a link to the Manage Users page. If they do not have the permission, then we'll show them a nice message.
First, we'll need to add the Shiro taglib to our web application. Next, we add the <shiro:hasPermission> tag with a check for users:manage. Within the <shiro:hasPermission> tags we will place the code we want to execute if the user has the permission we're checking for. If we want to take an action if the user lacks the permission, then we need to also add the <shiro:lacksPermission> tag, again checking for users:manage. And any code we want to excute if the user lacks the permission will need to be placed within the <shiro:lacksPermission> tags.
<%@ taglib prefix=“shiro” uri= %>
    <shiro:hasPermission name=“users:manage”>
        <a href=“manageUsers.jsp”>
            Click here to manage users
    <shiro:lacksPermission name=“users:manage”>
        No user management for you!
Of course, there also tags for checking roles and other user data and states.
For more information on JSP/GSP Tags please check out the JSP Tag Library and for more information on integration your application in your web application, please read the Web Integration Documentation


Popular posts from this blog

Stretch a row if data overflows in jasper reports

It is very common that some columns of the report need to stretch to show all the content in that column. But  if you just specify the property " stretch with overflow' to that column(we called text field in jasper report world) , it will just stretch that column and won't change other columns, so the row could be ridiculous. Haven't find the solution from internet yet. So I just review the properties in iReport one by one and find two useful properties(the bold highlighted in example below) which resolve the problems.   example:
<band height="20" splitType="Stretch"> <textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="true"> <reportElement stretchType="RelativeToTallestObject" mode="Opaque" x="192" y="0" width="183" height="20"/> <box leftPadding="2"> <pen lineWidth="0.25"/> …

JasperReports - Configuration Reference

Live - solving the jasper report out of memory and high cpu usage problems

I still can not find the solution. So I summary all the things and tell my boss about it. If any one knows the solution, please let me know.

Symptom: 1.The JVM became Out of memory when creating big consumption report 2.Those JRTemplateElement-instances is still there occupied even if I logged out the system
Reason:         1. There is a large number of JRTemplateElement-instances cached in the memory 2.The clearobjects() method in ReportThread class has not been triggered when logging out
Action I tried:      About the Virtualizer: 1.Replacing the JRSwapFileVirtualizer with JRFileVirtualizer 2.Not use any FileVirtualizer for cache the report in the hard disk Result: The japserreport still creating the a large number of JRTemplateElement-instances in the memory     About the work around below,      I tried: item 3(in below work around list) – result: it helps to reduce  the size of the JRTemplateElement Object                Item 4,5 – result : it helps a lot to reduce the number of  JRTemplateE…