http://git-wip-us.apache.org/repos/asf/shiro-site/blob/ddea166c/authorization.html
----------------------------------------------------------------------
diff --git a/authorization.html b/authorization.html
deleted file mode 100644
index d5cea21..0000000
--- a/authorization.html
+++ /dev/null
@@ -1,650 +0,0 @@
-<h1><a name="Authorization-ApacheShiroAuthorization"></a>Apache Shiro
Authorization</h1>
-<div class="toc">
-<ul><li><a href="#Authorization-ElementsofAuthorization">Elements of
Authorization</a></li><ul><li><a
href="#Authorization-Permissions">Permissions</a></li><ul><li><a
href="#Authorization-PermissionGranularity">Permission
Granularity</a></li></ul><li><a
href="#Authorization-Roles">Roles</a></li><li><a
href="#Authorization-Users">Users</a></li></ul><li><a
href="#Authorization-AuthorizingSubjects">Authorizing
Subjects</a></li><ul><li><a
href="#Authorization-ProgrammaticAuthorization">Programmatic
Authorization</a></li><ul><li><a
href="#Authorization-RoleBasedAuthorization">Role-Based
Authorization</a></li><ul><li><a href="#Authorization-RoleChecks">Role
Checks</a></li><li><a href="#Authorization-RoleAssertions">Role
Assertions</a></li></ul><li><a
href="#Authorization-PermissionBasedAuthorization">Permission-Based
Authorization</a></li><ul><li><a
href="#Authorization-PermissionChecks">Permission Checks</a></li><ul><li><a
href="#Authorization-ObjectbasedPermissionChecks">Object-based Pe
rmission Checks</a></li><li><a
href="#Authorization-Stringbasedpermissionchecks">String-based permission
checks</a></li></ul><li><a
href="#Authorization-PermissionAssertions">Permission
Assertions</a></li></ul></ul><li><a
href="#Authorization-AnnotationbasedAuthorization">Annotation-based
Authorization</a></li><ul><li><a
href="#Authorization-Configuration">Configuration</a></li><li><a
href="#Authorization-The%7B%7BRequiresAuthentication%7D%7Dannotation">The
<tt>RequiresAuthentication</tt> annotation</a></li><li><a
href="#Authorization-The%7B%7BRequiresGuest%7D%7Dannotation">The
<tt>RequiresGuest</tt> annotation</a></li><li><a
href="#Authorization-The%7B%7BRequiresPermissions%7D%7Dannotation">The
<tt>RequiresPermissions</tt> annotation</a></li><li><a
href="#Authorization-The%7B%7BRequiresRoles%7D%7Dpermission">The
<tt>RequiresRoles</tt> permission</a></li><li><a
href="#Authorization-The%7B%7BRequiresUser%7D%7Dannotation">The
<tt>RequiresUser</tt> annotation</a></li></ul><li><a href="
#Authorization-JSPTagLibAuthorization">JSP TagLib
Authorization</a></li></ul><li><a
href="#Authorization-AuthorizationSequence">Authorization
Sequence</a></li><ul><li><a
href="#Authorization-%7B%7BModularRealmAuthorizer%7D%7D">
<tt>ModularRealmAuthorizer</tt></a></li><ul><li><a
href="#Authorization-RealmAuthorizationOrder">Realm Authorization
Order</a></li><li><a
href="#Authorization-Configuringaglobal%7B%7BPermissionResolver%7D%7D">Configuring
a global <tt>PermissionResolver</tt></a></li><li><a
href="#Authorization-Configuringaglobal%7B%7BRolePermissionResolver%7D%7D">Configuring
a global <tt>RolePermissionResolver</tt></a></li></ul><li><a
href="#Authorization-CustomAuthorizer">Custom
Authorizer</a></li></ul></ul></div>
-
-<p><span class="image-wrap" style="display: block; text-align: center"><img
src="assets/images/ShiroFeatures_Authorization.png" style="border: 0px solid
black"></span></p>
-
-<p>Authorization, also known as <em>access control</em>, is the process of
managing access to resources. In other words, controlling <em>who</em> has
access to <em>what</em> in an application.</p>
-
-<p>Examples of authorization checks are: Is the user allowed to look at this
webpage, edit this data, view this button, or print to this printer? Those are
all decisions determining what a user has access to.</p>
-
-<h2><a name="Authorization-ElementsofAuthorization"></a>Elements of
Authorization</h2>
-
-<p>Authorization has three core elements that we reference quite a bit in
Shiro: permissions, roles, and users. </p>
-
-<h3><a name="Authorization-Permissions"></a>Permissions</h3>
-
-<p>Permissions in Apache Shiro represent the most atomic element of a security
policy. They are fundamentally statements about behavior and represent
explicitly what can be done in an application. A well-formed permission
statement essentially describes resources and what actions are possible when a
<tt>Subject</tt> interacts with those resources.</p>
-
-<p>Some examples of permission statements:</p>
-
-<ul><li>Open a file</li><li>View the '/user/list' web page</li><li>Print
documents</li><li>Delete the 'jsmith' user</li></ul>
-
-
-<p>Most resources will support the typical CRUD (create, read, update, delete)
actions, but any action that makes sense for a particular resource type is ok.
The fundamental idea is that permission statements at a minimum are based on
<em>Resources</em> and <em>Actions</em>.</p>
-
-<p>When looking at permissions, probably the most important thing to realize
is that permission statements have no representation of <em>who</em> can
perform the represented behavior. They are only statements of <em>what</em>
can be done in an application.</p>
-
-<div class="panelMacro"><table class="infoMacro"><colgroup span="1"><col
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1"
valign="top"><img align="middle"
src="https://cwiki.apache.org/confluence/images/icons/emoticons/information.gif"
width="16" height="16" alt="" border="0"></td><td colspan="1"
rowspan="1"><b>Permissions represent behavior only</b><br
clear="none">Permission statements reflect behavior (actions associated with
resource types) <em>only</em>. They do not reflect <em>who</em> is able to
perform such behavior.</td></tr></table></div>
-
-<p>Defining <em>who</em> (users) is allowed to do <em>what</em> (permissions)
is an exercise of assigning permissions to users in some way. This is always
done by the application's data model and can vary greatly across
applications.</p>
-
-<p>For example, permissions can be grouped in a Role and that Role could be
associated with one or more User objects. Or some applications can have a Group
of users and a Group can be assigned a Role, which by transitive association
would mean that all the Users in that Group are implicitly granted the
permissions in the Role.</p>
-
-<p>There are many variations for how permissions could be granted to users -
the application determines how to model this based on the application
requirements.</p>
-
-<p>We'll cover how Shiro determines if a <tt>Subject</tt> is permitted to do
something or not later.</p>
-
-<h4><a name="Authorization-PermissionGranularity"></a>Permission
Granularity</h4>
-
-<p>The permission examples above all specify actions (open, read, delete, etc)
on a resource type (door, file, customer, etc). In some cases, they even
specify very fine-grained <em>instance-level</em> behavior - for example,
'delete' (action) the 'user' (resource type) with username 'jsmith' (instance
identifier). In Shiro, you have the ability to define exactly how granular
those statements can be.</p>
-
-<p>We cover permission granularity and 'levels' of permission statements in
much more detail in Shiro's <a href="permissions.html"
title="Permissions">Permissions Documentation</a>.</p>
-
-<h3><a name="Authorization-Roles"></a>Roles</h3>
-
-<p>A Role is a named entity that typically represents a set of behaviors or
responsibilities. Those behaviors translate to things you can or can't do with
a software application. Roles are typically assigned to user accounts, so by
association, users can 'do' the things attributed to various roles.</p>
-
-<p>There are effectively two types of Roles, and Shiro supports both
concepts:</p>
-
-<ul><li><b>Implicit Roles</b>: Most people use roles as an <em>implicit</em>
construct: where your application <em>implies</em> a set of behaviors (i.e.
permissions) based on a role name only. With implicit roles, there is nothing
at the software level that says "role X is allowed to perform behavior A, B and
C". Behavior is implied by a name alone.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-<div class="panelMacro"><table class="noteMacro"><colgroup span="1"><col
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1"
valign="top"><img align="middle"
src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif"
width="16" height="16" alt="" border="0"></td><td colspan="1"
rowspan="1"><b>Potentially Brittle Security</b><br clear="none">While the
simpler and most common approach, implicit roles potentially impose a lot of
software maintenance and management problems.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-For example, what if you just want to add or remove a role, or redefine a
role's behavior later? You'll have to go back into your source code and change
all your role checks to reflect the change in your security model, every time
such a change is required! Not to mention the operational costs this would
incur (re-test, go through QA, shut down the app, upgrade the software with the
new role checks, restart the app, etc).
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-This is probably ok for very simple applications (e.g. maybe there is an
'admin' role and 'everyone else'). But for more complicated or configurable
applications, this can be a major major problem throughout the life of your
application and drive a large maintenance cost for your
software.</td></tr></table></div>
-<p><br clear="none" class="atl-forced-newline"></p></li><li><b>Excplict
Roles</b>: An explicit role however is essentially a named collection of actual
permission statements. In this form, the application (and Shiro) knows
<em>exactly</em> what it means to have a particular role or not. Because it is
known the <em>exact</em> behavior that can be performed or not, there is no
guessing or implying what a particular role can or can not do.</li></ul>
-
-
-<p>The Shiro team advocates using permissions and explicit roles instead of
the older implicit approach. You will have much greater control over your
application's security experience.</p>
-
-<div class="panelMacro"><table class="tipMacro"><colgroup span="1"><col
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1"
valign="top"><img align="middle"
src="https://cwiki.apache.org/confluence/images/icons/emoticons/check.gif"
width="16" height="16" alt="" border="0"></td><td colspan="1"
rowspan="1"><b>Resource-Based Access Control</b><br clear="none">Be sure to
read Les Hazlewood's article, <a class="external-link"
href="http://www.katasoft.com/blog/2011/05/09/new-rbac-resource-based-access-control"
rel="nofollow">The New RBAC: Resource-Based Access Control</a>, which covers
in-depth the benefits of using permissions and explicit roles (and their
positive impact on source code) instead of the older implicit role
approach.</td></tr></table></div>
-
-<h3><a name="Authorization-Users"></a>Users</h3>
-
-<p>A user essentially is the 'who' of an application. As we've covered
previously however, the <tt>Subject</tt> is really Shiro's 'User' concept.</p>
-
-<p>Users (Subjects) are allowed to perform certain actions in your application
through their association with roles or direct permissions. Your application's
data model defines exactly how a <tt>Subject</tt> is allowed to do something or
not.</p>
-
-<p>For example, in your data model, perhaps you have an actual <tt>User</tt>
class and you assign permissions directly to <tt>User</tt> instances. Or maybe
you assign permissions only to <tt>Roles</tt> directly, and then assign Roles
to <tt>Users</tt>, so by association, <tt>Users</tt> transitively 'have' the
permissions assigned to their roles. Or you could represent these things with
a 'Group' concept. It is up to you - use what makes sense for your
application.</p>
-
-<p>Your data model defines exactly how authorization will function. Shiro
relies on a <a href="realm.html" title="Realm">Realm</a> implementation to
translate your data model association details into a format Shiro understands.
We'll cover how Realms do this a little later.</p>
-
-<div class="panelMacro"><table class="infoMacro"><colgroup span="1"><col
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1"
valign="top"><img align="middle"
src="https://cwiki.apache.org/confluence/images/icons/emoticons/information.gif"
width="16" height="16" alt="" border="0"></td><td colspan="1"
rowspan="1">Ultimately, your <a href="realm.html" title="Realm">Realm</a>
implementation is what communicates with your data source (RDBMS, LDAP, etc).
So your realm is what will tell Shiro whether or not roles or permissions
exist. You have full control over how your authorization model is structured
and defined.</td></tr></table></div>
-
-<h2><a name="Authorization-AuthorizingSubjects"></a>Authorizing Subjects</h2>
-
-<p>Performing authorization in Shiro can be done in 3 ways:</p>
-
-<ul><li>Programmatically - You can perform authorization checks in your java
code with structures like <tt>if</tt> and <tt>else</tt> blocks.</li><li>JDK
annotations - You can attach an authorization annotation to your Java
methods</li><li>JSP/GSP TagLibs - You can control JSP or GSP page output based
on roles and permissions</li></ul>
-
-
-<h3><a name="Authorization-ProgrammaticAuthorization"></a>Programmatic
Authorization</h3>
-
-<p>Probably the easiest and most common way to perform authorization is to
programatically interact with the current <tt>Subject</tt> instance
directly.</p>
-
-<h4><a name="Authorization-RoleBasedAuthorization"></a>Role-Based
Authorization</h4>
-
-<p>If you want to control access based on simpler/traditional implicit role
names, you can execute role checks:</p>
-
-<h5><a name="Authorization-RoleChecks"></a>Role Checks</h5>
-
-<p>If you want to simply check to see if the current <tt>Subject</tt> has a
role or not, you can call the variant <tt>hasRole*</tt> methods on the
<tt>Subject</tt> instance.</p>
-
-<p>For example, to see if a <tt>Subject</tt> has a particular (single) role,
you can call the <tt>subject.</tt> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#hasRole(java.lang.String)">hasRole(roleName)</a></tt>
method, and react accordingly:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
-
-<span class="code-keyword">if</span> (currentUser.hasRole(<span
class="code-quote">"administrator"</span>)) {
- <span class="code-comment">//show the admin button
-</span>} <span class="code-keyword">else</span> {
- <span class="code-comment">//don't show the button? Grey it out?
-</span>}
-</pre>
-</div></div>
-
-<p>There are few role-oriented <tt>Subject</tt> methods you can call,
depending on your needs:</p>
-
-<p>
-</p><div class="table-wrap">
-
-<table class="confluenceTable" id="TBL1365578679389"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"> Subject Method </th><th
colspan="1" rowspan="1" class="confluenceTh"> Description </th></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#hasRole(java.lang.String)">hasRole(String
roleName)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
Returns <tt>true</tt> if the <tt>Subject</tt> is assigned the specified role,
<tt>false</tt> otherwise. </td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#hasRoles(java.util.List)">hasRoles(List<String>
roleNames)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
Returns a array of <tt>hasRole</tt> results corresponding to the indices in the
method argument. Useful as a performance enhancemen
t if many role checks need to be performed (e.g. when customizing a complex
view) </td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#hasAllRoles(java.util.Collection)">hasAllRoles(Collection<String>
roleNames)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
Returns <tt>true</tt> if the <tt>Subject</tt> is assigned <em>all</em> of the
specified roles, <tt>false</tt> otherwise. </td></tr></tbody></table>
-</div>
-
-<script type="text/javascript"> <!--
-//Copyright(c)2005,2010 Bob Swift and other contributors. All rights reserved.
-function getElementInnerText(element){var str="";for(var
i=0;i<element.childNodes.length;i++){switch(element.childNodes.item(i).nodeType){case
1:str+=getElementInnerText(element.childNodes.item(i));break;case
3:str+=element.childNodes.item(i).nodeValue;break;}}return str;}
-function
trimSafe(v){return((v==undefined)||(v==null))?"":v.Trim();}String.prototype.Trim=new
Function("return this.replace(/^\\s+|\\s+$/g,'')");
-function compareNumber(v1,v2){if(isNaN(v2)){if(isNaN(v1))return
0;return-1;}if(v1<v2)return-1;if(v1==v2)return 0;return 1;}
-function
compareSeparatedNumber(v1,v2){for(i=0;(i<v1.length)&&(i<v2.length);i++){var
result=compareNumber(parseInt(v1[i]),parseInt(v2[i]));if(result!=0)return
result;}if(v1.length<v2.length)return-1;if(v2.length<v1.length)return 1;return
0;}
-function sortByCell(sortCell,firstDataRowIndex,footingCount){var
compareFunction;var
valueParser;compareFunction=compareNumber;if(sortCell.columnType=="I"){valueParser=function(value){return
parseInt(getElementInnerText(value));};}else
if(sortCell.columnType=="F"){valueParser=function(value){return
parseFloat(getElementInnerText(value));};}else
if(sortCell.columnType=="C"){valueParser=function(value){return
parseFloat(getElementInnerText(value).replace(/[^\d\.\,\-]*([\d\.\,\-*]*).*/,'$1'));};}else
if(sortCell.columnType.charAt(0)=='D'){if(Date.parseString){valueParser=function(value){var
date=Date.parseString(trimSafe(getElementInnerText(value)),sortCell.columnType.substring(1));return((date==null)?NaN:date.getTime());};}else{valueParser=function(value){return
Date.parse(getElementInnerText(value));};}}else
if((sortCell.columnType=="/")||(sortCell.columnType==".")||(sortCell.columnType=="-")||(sortCell.columnType==":")){compareFunction=compareSeparatedNumber;valueParser=function(val
ue){return getElementInnerText(value).split(sortCell.columnType);};}else
if(sortCell.columnType=="A"){valueParser=function(value){return
0;};}else{compareFunction=function(v1,v2){if(v1<v2)return-1;if(v1==v2)return
0;return 1;};valueParser=function(value){return
trimSafe(getElementInnerText(value)).toUpperCase();};}var
headRowCount=(sortCell.sortTable.tHead==null)?0:sortCell.sortTable.tHead.rows.length;firstDataRowIndex=firstDataRowIndex-headRowCount;var
table=sortCell.sortTable.tBodies[0];var
rowCount=table.rows.length-firstDataRowIndex-footingCount;var
map=Array(rowCount);var values=Array(rowCount);var
compareTest=(sortCell.sortDescending?-1:1);sortCell.sortDescending=!sortCell.sortDescending;var
firstCell=(((sortCell.sortTable.tHead==null)||(sortCell.sortTable.tHead.rows.length==0))?table.rows[0].cells[sortCell.columnIndex]:sortCell.sortTable.tHead.rows[0].cells[sortCell.columnIndex]);if((firstCell!=null)&&(firstCell.sortTable!=null)&&(firstCell.sortTable!=undefined)&&(firstCell.s
ortTable.sortImage!=null)&&(firstCell.sortTable.sortImage!=undefined)){firstCell.sortTable.sortImage.setAttribute("src",firstCell.sortDescending?firstCell.sortTable.sortAttributeDescending:firstCell.sortTable.sortAttributeAscending);firstCell.appendChild(firstCell.sortTable.sortImage);}var
i;for(i=0;i<rowCount;i++){map[i]=sortCell.sortFirstTime?i:(rowCount-1-i);var
row=table.rows[i+firstDataRowIndex];var
cellValue=row.cells[sortCell.columnIndex];values[i]=valueParser(cellValue);}sortCell.sortFirstTime=false;var
didSwap;do{didSwap=false;for(i=0;i<rowCount-1;i++){if(compareFunction(values[map[i]],values[map[i+1]])==compareTest){saveIndex=map[i];map[i]=map[i+1];map[i+1]=saveIndex;didSwap=true;}}}while(didSwap);var
tableRows=new
Array();for(i=0;i<rowCount+footingCount;i++){tableRows.push(table.rows[i+firstDataRowIndex]);}for(i=0;i<rowCount+footingCount;i++){table.removeChild(tableRows[i]);}for(i=0;i<rowCount;i++){var
row=tableRows[map[i]];table.appendChild(row);if(row.autoNumber){row.ce
lls[0].innerHTML=i+1;}}for(i=0;i<footingCount;i++){table.appendChild(tableRows[i+rowCount]);}}
-function
enableSortOnCell(cell,columnIndex,table,columnTypes,customize){cell.style.cursor="pointer";cell.sortTable=table;cell.sortFirstTime=true;cell.sortDescending=false;cell.columnIndex=(customize.autoNumber?(columnIndex+1):columnIndex);if(columnIndex==-1){cell.columnType="I";}else{cell.columnType=(columnTypes&&columnTypes[columnIndex])?columnTypes[columnIndex]:"S";}if(cell.columnType!="X"){cell.onmouseover=function(){this.saveTitle=this.getAttribute('title');this.setAttribute('title',customize.sortTip+"
"+((this.saveTitle!=null)&&(this.saveTitle!=undefined)?this.saveTitle:''));};cell.onmouseout=function(){this.setAttribute('title',this.saveTitle);};cell.onclick=function(){sortByCell(this,customize.firstDataRowIndex,customize.footingCount);};}else{cell.columnType=cell.columnType.substring(1);}}
-function sumColumn(table,index,firstDataRowIndex,columnType){var
total=0;for(var i=firstDataRowIndex;i<table.rows.length;i++){var
cell=table.rows[i].cells[index];var
value;if(cell){if(columnType=='C'){value=parseFloat(getElementInnerText(cell).replace(/[^\d\.\,\-]*([\d\.\,\-*]*).*/,'$1'))}else{value=parseFloat(getElementInnerText(cell));}if(!isNaN(value)){total=total+value;}}}return
total;}
-function appendTotalRow(table,columnTypes,firstDataRowIndex){var
row=document.createElement('tr');var table=table.tBodies[0];var
columnCount=(0<table.rows.length)?table.rows[table.rows.length-1].cells.length:0;for(var
columnIndex=0;columnIndex<columnCount;columnIndex++){var
column=document.createElement('th');column.className='confluenceTh';column.innerHTML=(columnIndex<columnTypes.length&&((columnTypes[columnIndex]=='I')||(columnTypes[columnIndex]=='F')||(columnTypes[columnIndex]=='C')))?sumColumn(table,columnIndex,firstDataRowIndex,columnTypes[columnIndex]):'';row.appendChild(column);}table.appendChild(row);}
-function handleRow(table,row,rowIndex,customize){var
columnCount=row.cells.length;for(var
i=0;i<columnCount;i++){if(customize.enableSorting&&(rowIndex<=customize.lastClickableRow)){enableSortOnCell(row.cells[i],i,table,customize.columnTypes,customize);}if((rowIndex==0)&&(customize.sortColumn!='')&&(customize.sortCell==null)&&(((i+1).toString()==customize.sortColumn)||(trimSafe(getElementInnerText(row.cells[i]))==customize.sortColumn)||(trimSafe(row.cells[i].getAttribute('title'))==customize.sortColumn))){customize.sortCell=row.cells[i];}if(customize.firstDataRowIndex<=rowIndex){if((customize.columnTypes[i]=="I")||(customize.columnTypes[i]=="F")||(customize.columnTypes[i]=="C")){row.cells[i].style.textAlign="right";}}if(customize.columnTypes[i]=="H"){row.cells[i].style.display="none";}if(customize.enableHeadingAttributes||(customize.firstDataRowIndex<=rowIndex)){if(i<customize.attrList.length){for(var
j=0;j<customize.attrList[i].length;j++){var
attr=customize.attrList[i][j].Trim().sp
lit("=");if(1<attr.length){var aName=attr[0].Trim();var
aValue=attr[1].Trim();if((aName.toLowerCase()=="style")&&(2<aValue.length)){if((aValue.charAt(0)=='"')){aValue=aValue.substring(1,aValue.length-1);}row.cells[i].style.cssText=aValue;}else{row.cells[i].setAttribute(aName,aValue);}}}}}}if(customize.autoNumber){var
column=document.createElement(!customize.autoNumberSort||(rowIndex<customize.firstDataRowIndex)?'th':'td');column.className=(!customize.autoNumberSort||(rowIndex<customize.firstDataRowIndex)?'confluenceTh':'confluenceTd');column.innerHTML=((rowIndex<customize.firstDataRowIndex)||(customize.totalRowCount-customize.firstDataRowIndex-customize.footingCount<rowIndex)?'':customize.dataRowCount++);column.setAttribute('align','right');row.autoNumber=!customize.autoNumberSort;row.insertBefore(column,row.cells[0]);if(customize.enableSorting&&customize.autoNumberSort&&(rowIndex<=customize.lastClickableRow)){enableSortOnCell(column,-1,table,null,customize);}}if((customize.highligh
tColor!="")&&(customize.firstDataRowIndex<=rowIndex)){row.onmouseover=function(){this.tableHighLightRowColor=this.bgColor;this.bgColor=customize.highlightColor;};row.onmouseout=function(){this.bgColor=this.tableHighLightRowColor;this.tableHighLightRowColor=null;};}}
-function
customizeMacroTable(tableId,columnTypes,firstDataRowIndex,highlightColor,enableSorting,sortTip,sortColumn,sortDescending,autoNumber,autoNumberSort,enableHeadingAttributes,footingCount,autoTotal,iconLocation){var
customize=new
Object;customize.columnTypes=columnTypes;customize.firstDataRowIndex=firstDataRowIndex;customize.highlightColor=highlightColor;customize.enableSorting=enableSorting;customize.sortTip=sortTip;customize.sortColumn=sortColumn;customize.sortDescending=sortDescending;customize.autoNumber=autoNumber;customize.autoNumberSort=autoNumberSort;customize.enableHeadingAttributes=enableHeadingAttributes;customize.footingCount=footingCount;customize.autoTotal=autoTotal;customize.iconLocation=iconLocation;var
table=(typeof(tableId)=="string")?document.getElementById(tableId):null;if(table){if(customize.autoTotal){appendTotalRow(table,customize.columnTypes,customize.firstDataRowIndex);customize.footingCount++;}if(customize.iconLocation!=""){table.sortAttributeAscending
=contextPath+customize.iconLocation+"down.gif";table.sortAttributeDescending=contextPath+customize.iconLocation+"up.gif";table.sortImage=document.createElement("IMG");}customize.lastClickableRow=customize.firstDataRowIndex-1;if(customize.lastClickableRow<0){customize.lastClickableRow=0;}customize.sortCell=null;customize.dataRowCount=1;var
colAttrs=columnAttributes.split(",");customize.attrList=Array(colAttrs.length);for(var
i=0;i<colAttrs.length;i++){customize.attrList[i]=colAttrs[i].Trim().split(";;");}var
rowIndex=0;var headRowCount=(table.tHead==null)?0:table.tHead.rows.length;var
footRowCount=(table.tFoot==null)?0:table.tFoot.rows.length;var
bodyRowCount=table.tBodies[0].rows.length;customize.totalRowCount=headRowCount+footRowCount+bodyRowCount;for(var
i=0;i<headRowCount;i++){var
row=table.tHead.rows[i];handleRow(table,row,rowIndex,customize);rowIndex++;}for(var
i=0;i<bodyRowCount;i++){var
row=table.tBodies[0].rows[i];handleRow(table,row,rowIndex,customize);rowIndex++;}for(var
i
=0;i<footRowCount;i++){var
row=table.tFoot.rows[i];handleRow(table,row,rowIndex,customize);rowIndex++;}if(customize.sortCell!=null){customize.sortCell.sortDescending=customize.sortDescending;sortByCell(customize.sortCell,customize.firstDataRowIndex,customize.footingCount);}}return
table;}
-
-var columnTypes = ['S'];
-var columnAttributes = 'style="white-space:nowrap;",';
-customizeMacroTable('TBL1365578679389', columnTypes, 1,
'lightgoldenrodyellow', true, 'Click to sort', '', false, false, false, true,
0, false, '' );
-//-->
- </script>
-
-<h5><a name="Authorization-RoleAssertions"></a>Role Assertions</h5>
-
-<p>An alternative to checking a <tt>boolean</tt> to see if the
<tt>Subject</tt> has a role or not, you can simply assert that they have an
expected role before logic is executed. If the <tt>Subject</tt> does not have
the expected role, an <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/AuthorizationException.html">AuthorizationException</a></tt>
will be thrown. If they do have the expected role, the assertion will execute
quietly and logic will continue as expected.</p>
-
-<p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
-
-<span class="code-comment">//guarantee that the current user is a bank teller
and
-</span><span class="code-comment">//therefore allowed to open the account:
-</span>currentUser.checkRole(<span class="code-quote">"bankTeller"</span>);
-openBankAccount();
-</pre>
-</div></div>
-
-<p>A benefit of this approach over the <tt>hasRole*</tt> methods is that code
can be a bit cleaner in that you don't have to construct your own
<tt>AuthorizationExceptions</tt> if the current <tt>Subject</tt> does not meet
expected conditions (if you don't want to).</p>
-
-<p>There are few role-oriented <tt>Subject</tt> assertion methods you can
call, depending on your needs:</p>
-
-<p>
-</p><div class="table-wrap">
-
-<table class="confluenceTable" id="TBL1365578679390"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"> Subject Method </th><th
colspan="1" rowspan="1" class="confluenceTh"> Description </th></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkRole(java.lang.String)">checkRole(String
roleName)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
Returns quietly if the <tt>Subject</tt> is assigned the specified role or
throws an <tt>AuthorizationException</tt> if not. </td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkRoles(java.util.Collection)">checkRoles(Collection<String>
roleNames)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
Returns quietly if the <tt>Subject</tt> is assigned <em>all</em> of the
specified role or th
rows an <tt>AuthorizationException</tt> if not. </td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkRoles(java.lang.String...)">checkRoles(String...
roleNames)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
Same effect as the <tt>checkRoles</tt> method above, but allows Java 5 var-args
style arguments. </td></tr></tbody></table>
-</div>
-
-<script type="text/javascript"> <!--
-var columnTypes = ['S'];
-var columnAttributes = 'style="white-space:nowrap;",';
-customizeMacroTable('TBL1365578679390', columnTypes, 1,
'lightgoldenrodyellow', true, 'Click to sort', '', false, false, false, true,
0, false, '' );
-//-->
- </script>
-
-<h4><a name="Authorization-PermissionBasedAuthorization"></a>Permission-Based
Authorization</h4>
-
-<p>As stated above in our overview of Roles, often a better way of performing
access control is through permission-based authorization. Permission-based
authorization, because it is strongly associated with your application's raw
functionality (and the behavior on an application's core resources),
permission-based authorization source code changes when your functionality
changes, not when there is a security policy change. This means code is
impacted much-less frequently than similar role-based authorization code.</p>
-
-<h5><a name="Authorization-PermissionChecks"></a>Permission Checks</h5>
-
-<p>If you want to check to see if a <tt>Subject</tt> is permitted to do
something or not, you can call any of the various <tt>isPermitted*</tt> method
variants. There are two primary means of checking permissions - with
object-based <tt>Permission</tt> instances or with Strings that represent
<tt>Permissions</tt></p>
-
-<h6><a name="Authorization-ObjectbasedPermissionChecks"></a>Object-based
Permission Checks</h6>
-
-<p>One possible way of performing permission checks is to instantiate an
instance of Shiro's <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Permission.html">org.apache.shiro.authz.Permission</a></tt>
interface and pass it to the <tt>*isPermitted</tt> methods that accept
permission instances.</p>
-
-<p>For example, consider the following scenario: There is a <tt>Printer</tt>
in an office with a unique identifier <tt>laserjet4400n</tt>. Our software
needs to check to see if the current user is allowed print documents on that
printer before we allow them to press a 'print' button. The permission check
to see if this possible could be formulated like this:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Permission printPermission = <span class="code-keyword">new</span>
PrinterPermission(<span class="code-quote">"laserjet4400n"</span>, <span
class="code-quote">"print"</span>);
-
-Subject currentUser = SecurityUtils.getSubject();
-
-<span class="code-keyword">if</span>
(currentUser.isPermitted(printPermission)) {
- <span class="code-comment">//show the Print button
-</span>} <span class="code-keyword">else</span> {
- <span class="code-comment">//don't show the button? Grey it out?
-</span>}
-</pre>
-</div></div>
-
-<p>In this example, we also see an example of a very powerful
<em>instance-level</em> access control check - the ability to restrict behavior
based on <em>individual data instances</em>.</p>
-
-<p>Object-based <tt>Permissions</tt> are useful if:</p>
-
-<ul><li>You want compile-time type-safety</li><li>You want to guarantee
permissions are represented and used correctly</li><li>You want explicit
control of how permission resolution logic (called permission implication
logic, based on the Permission interface's <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Permission.html#implies(org.apache.shiro.authz.Permission)">implies</a></tt>
method) executes.</li><li>You want to guarantee Permissions reflect
application resources accurately (for example, maybe Permission classes can be
auto-generated during a project's build based on a project's domain
model).</li></ul>
-
-
-<p>There are few Object permission-oriented <tt>Subject</tt> methods you can
call, depending on your needs:</p>
-
-<p>
-</p><div class="table-wrap">
-
-<table class="confluenceTable" id="TBL1365578679391"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"> Subject Method </th><th
colspan="1" rowspan="1" class="confluenceTh"> Description </th></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermitted(org.apache.shiro.authz.Permission)">isPermitted(Permission
p)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
<tt>true</tt> if the <tt>Subject</tt> is permitted to perform an action or
access a resource summarized by the specified <tt>Permission</tt> instance,
<tt>false</tt> otherwise. </td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermitted(java.util.List)">isPermitted(List<Permission>
perms)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
an array of <tt
>isPermitted</tt> results corresponding to the indices in the method argument.
> Useful as a performance enhancement if many permission checks need to be
>performed (e.g. when customizing a complex view) </td></tr><tr><td
>colspan="1" rowspan="1" class="confluenceTd"> <tt><a class="external-link"
>href="static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermittedAll(java.util.Collection)">isPermittedAll(Collection<Permission>
> perms)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd">
>Returns <tt>true</tt> if the <tt>Subject</tt> is permitted <em>all</em> of
>the specified permissions, <tt>false</tt> otherwise.
></td></tr></tbody></table>
-</div>
-
-<script type="text/javascript"> <!--
-var columnTypes = ['S'];
-var columnAttributes = 'style="white-space:nowrap;",';
-customizeMacroTable('TBL1365578679391', columnTypes, 1,
'lightgoldenrodyellow', true, 'Click to sort', '', false, false, false, true,
0, false, '' );
-//-->
- </script>
-
-<h6><a name="Authorization-Stringbasedpermissionchecks"></a>String-based
permission checks</h6>
-
-<p>While Object-based permissions can be useful (compile-time type-safety,
guaranteed behavior, customized implication logic, etc), they can sometimes
feel a bit 'heavy handed' for many applications. An alternative is to use
normal <tt>Strings</tt> to represent a permission instance.</p>
-
-<p>For example, based on the print permission example above, we can
re-formulate that same check as a <tt>String</tt>-based permission check:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
-
-<span class="code-keyword">if</span> (currentUser.isPermitted(<span
class="code-quote">"printer:print:laserjet4400n"</span>)) {
- <span class="code-comment">//show the Print button
-</span>} <span class="code-keyword">else</span> {
- <span class="code-comment">//don't show the button? Grey it out?
-</span>}
-</pre>
-</div></div>
-
-<p>This example still shows the same instance-level permission check, but
important parts of the permission - <tt>printer</tt> (resource type),
<tt>print</tt> (action), and <tt>laserjet4400n</tt> (instance id) - were all
represented in a String.</p>
-
-<p>This particular example shows a special colon-delimited format defined by
Shiro's default <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/permission/WildcardPermission.html">org.apache.shiro.authz.permission.WildcardPermission</a></tt>
implementation, which most people will find suitable.</p>
-
-<p>That is, the above code block is (mostly) a shortcut for the following:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
-
-Permission p = <span class="code-keyword">new</span> WildcardPermission(<span
class="code-quote">"printer:print:laserjet4400n"</span>);
-
-<span class="code-keyword">if</span> (currentUser.isPermitted(p) {
- <span class="code-comment">//show the Print button
-</span>} <span class="code-keyword">else</span> {
- <span class="code-comment">//don't show the button? Grey it out?
-</span>}
-</pre>
-</div></div>
-
-<p>The <tt>WildcardPermission</tt> token format and formation options are
covered in-depth in Shiro's <a href="permissions.html"
title="Permissions">Permission documentation</a>.</p>
-
-<p>And while the above String defaults to the <tt>WildcardPermission</tt>
format, you can actually invent your own String format and use that if you
prefer. We'll cover how to do this as part of the Realm Authorization section
below.</p>
-
-<p>String-based permissions are beneficial in that you are not forced to
implement an interface and simple strings are often easy to read. The downside
is that you don't have type safety and if you needed more complicated behavior
that are outside the scope of what the Strings represent, you're going to want
to implement your own permission objects based on the permission interface. In
practice, most Shiro end-users choose the String-based approach for their
simplicity, but ultimately your application's requirements will dictate which
is better.</p>
-
-<p>Like the Object-based permission check methods, there are String variants
to support String-based permission checks:</p>
-
-<p>
-</p><div class="table-wrap">
-
-<table class="confluenceTable" id="TBL1365578679392"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"> Subject Method </th><th
colspan="1" rowspan="1" class="confluenceTh"> Description </th></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermitted(java.lang.String)">isPermitted(String
perm)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
<tt>true</tt> if the <tt>Subject</tt> is permitted to perform an action or
access a resource summarized by the specified <tt>String</tt> permission,
<tt>false</tt> otherwise. </td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermitted(java.util.List)">isPermitted(String...
perms)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
an array of <tt>isPermitted</tt> results corresp
onding to the indices in the method argument. Useful as a performance
enhancement if many <tt>String</tt> permission checks need to be performed
(e.g. when customizing a complex view) </td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#isPermittedAll(java.lang.String...)">isPermittedAll(String...
perms)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
<tt>true</tt> if the <tt>Subject</tt> is permitted <em>all</em> of the
specified <tt>String</tt> permissions, <tt>false</tt> otherwise.
</td></tr></tbody></table>
-</div>
-
-<script type="text/javascript"> <!--
-var columnTypes = ['S'];
-var columnAttributes = 'style="white-space:nowrap;",';
-customizeMacroTable('TBL1365578679392', columnTypes, 1,
'lightgoldenrodyellow', true, 'Click to sort', '', false, false, false, true,
0, false, '' );
-//-->
- </script>
-
-<h5><a name="Authorization-PermissionAssertions"></a>Permission Assertions</h5>
-
-<p>As an alternative to checking a <tt>boolean</tt> to see if the
<tt>Subject</tt> is permitted to do something or not, you can simply assert
that they have an expected permission before logic is executed. If the
<tt>Subject</tt> is not permitted, an <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/AuthorizationException.html">AuthorizationException</a></tt>
will be thrown. If they are permitted as expected, the assertion will execute
quietly and logic will continue as expected.</p>
-
-<p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
-
-<span class="code-comment">//guarantee that the current user is permitted
-</span><span class="code-comment">//to open a bank account:
-</span>Permission p = <span class="code-keyword">new</span>
AccountPermission(<span class="code-quote">"open"</span>);
-currentUser.checkPermission(p);
-openBankAccount();
-</pre>
-</div></div>
-
-<p>or, the same check, using a String permission:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
-
-<span class="code-comment">//guarantee that the current user is permitted
-</span><span class="code-comment">//to open a bank account:
-</span>currentUser.checkPermission(<span
class="code-quote">"account:open"</span>);
-openBankAccount();
-</pre>
-</div></div>
-
-
-<p>A benefit of this approach over the <tt>isPermitted*</tt> methods is that
code can be a bit cleaner in that you don't have to construct your own
<tt>AuthorizationExceptions</tt> if the current <tt>Subject</tt> does not meet
expected conditions (if you don't want to).</p>
-
-<p>There are few permission-oriented <tt>Subject</tt> assertion methods you
can call, depending on your needs:</p>
-
-<p>
-</p><div class="table-wrap">
-
-<table class="confluenceTable" id="TBL1365578679393"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"> Subject Method </th><th
colspan="1" rowspan="1" class="confluenceTh"> Description </th></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkPermission(org.apache.shiro.authz.Permission)">checkPermission(Permission
p)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
quietly if the <tt>Subject</tt> is permitted to perform an action or access a
resource summarized by the specified <tt>Permission</tt> instance, or throws an
<tt>AuthorizationException</tt> if not. </td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkPermission(java.lang.String)">checkPermission(String
perm)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> R
eturns quietly if the <tt>Subject</tt> is is permitted to perform an action or
access a resource summarized by the specified <tt>String</tt> permission, or
throws an <tt>AuthorizationException</tt> if not. </td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"> <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkPermissions(java.util.Collection)">checkPermissions(Collection<Permission>
perms)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Returns
quietly if the <tt>Subject</tt> is permitted <em>all</em> the specified
permissions, or throws an <tt>AuthorizationException</tt> if not.
</td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/Subject.html#checkPermissions(java.lang.String...)">checkPermissions(String...
perms)</a></tt> </td><td colspan="1" rowspan="1" class="confluenceTd"> Same
effect as the <tt>checkPer
missions</tt> method above, but using <tt>String</tt>-based permissions.
</td></tr></tbody></table>
-</div>
-
-<script type="text/javascript"> <!--
-var columnTypes = ['S'];
-var columnAttributes = 'style="white-space:nowrap;",';
-customizeMacroTable('TBL1365578679393', columnTypes, 1,
'lightgoldenrodyellow', true, 'Click to sort', '', false, false, false, true,
0, false, '' );
-//-->
- </script>
-
-<h3><a name="Authorization-AnnotationbasedAuthorization"></a>Annotation-based
Authorization</h3>
-
-<p>In addition to the <tt>Subject</tt> API calls, Shiro provides a collection
of Java 5+ annotations if you prefer meta-based authorization control.</p>
-
-<h4><a name="Authorization-Configuration"></a>Configuration</h4>
-
-<p>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.</p>
-
-<p>For AspectJ, you can review our <a class="external-link"
href="https://github.com/apache/shiro/tree/master/samples/aspectj">AspectJ
sample application</a>.</p>
-
-<p>For Spring applications, you can look into our <a href="spring.html"
title="Spring">Spring Integration</a> documentation.</p>
-
-<p>For Guice applications, you can look into our <a href="guice.html"
title="Guice">Guice Integration</a> documentation.</p>
-
-<h4><a
name="Authorization-The%7B%7BRequiresAuthentication%7D%7Dannotation"></a>The
<tt>RequiresAuthentication</tt> annotation</h4>
-
-<p>The <a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/annotation/RequiresAuthentication.html">RequiresAuthentication</a>
annotation requires the current <tt>Subject</tt> to have been authenticated
during their current session for the annotated class/instance/method to be
accessed or invoked.</p>
-
-<p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-@RequiresAuthentication
-<span class="code-keyword">public</span> void updateAccount(Account
userAccount) {
- <span class="code-comment">//<span class="code-keyword">this</span> method
will only be invoked by a
-</span> <span class="code-comment">//Subject that is guaranteed
authenticated
-</span> ...
-}
-</pre>
-</div></div>
-
-<p>This is mostly equivalent to the following Subject-based logic:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> void updateAccount(Account
userAccount) {
- <span class="code-keyword">if</span>
(!SecurityUtils.getSubject().isAuthenticated()) {
- <span class="code-keyword">throw</span> <span
class="code-keyword">new</span> AuthorizationException(...);
- }
-
- <span class="code-comment">//Subject is guaranteed authenticated here
-</span> ...
-}
-</pre>
-</div></div>
-
-<h4><a name="Authorization-The%7B%7BRequiresGuest%7D%7Dannotation"></a>The
<tt>RequiresGuest</tt> annotation</h4>
-
-<p>The <a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/annotation/RequiresGuest.html">RequiresGuest</a>
annotation requires the current Subject to be a "guest", that is, they are not
authenticated or remembered from a previous session for the annotated
class/instance/method to be accessed or invoked.</p>
-
-<p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-@RequiresGuest
-<span class="code-keyword">public</span> void signUp(User newUser) {
- <span class="code-comment">//<span class="code-keyword">this</span> method
will only be invoked by a
-</span> <span class="code-comment">//Subject that is unknown/anonymous
-</span> ...
-}
-</pre>
-</div></div>
-
-<p>This is mostly equivalent to the following Subject-based logic:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> void signUp(User newUser) {
- Subject currentUser = SecurityUtils.getSubject();
- PrincipalCollection principals = currentUser.getPrincipals();
- <span class="code-keyword">if</span> (principals != <span
class="code-keyword">null</span> && !principals.isEmpty()) {
- <span class="code-comment">//known identity - not a guest:
-</span> <span class="code-keyword">throw</span> <span
class="code-keyword">new</span> AuthorizationException(...);
- }
-
- <span class="code-comment">//Subject is guaranteed to be a 'guest' here
-</span> ...
-}
-</pre>
-</div></div>
-
-<h4><a
name="Authorization-The%7B%7BRequiresPermissions%7D%7Dannotation"></a>The
<tt>RequiresPermissions</tt> annotation</h4>
-
-<p>The <a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/annotation/RequiresPermissions.html">RequiresPermissions</a>
annotation requires the current Subject be permitted one or more permissions
in order to execute the annotated method.</p>
-
-<p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-@RequiresPermissions(<span class="code-quote">"account:create"</span>)
-<span class="code-keyword">public</span> void createAccount(Account account) {
- <span class="code-comment">//<span class="code-keyword">this</span> method
will only be invoked by a Subject
-</span> <span class="code-comment">//that is permitted to create an account
-</span> ...
-}
-</pre>
-</div></div>
-
-<p>This is mostly equivalent to the following Subject-based logic:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> void createAccount(Account account) {
- Subject currentUser = SecurityUtils.getSubject();
- <span class="code-keyword">if</span> (!subject.isPermitted(<span
class="code-quote">"account:create"</span>)) {
- <span class="code-keyword">throw</span> <span
class="code-keyword">new</span> AuthorizationException(...);
- }
-
- <span class="code-comment">//Subject is guaranteed to be permitted here
-</span> ...
-}
-</pre>
-</div></div>
-
-<h4><a name="Authorization-The%7B%7BRequiresRoles%7D%7Dpermission"></a>The
<tt>RequiresRoles</tt> permission</h4>
-
-<p>The <a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/annotation/RequiresRoles.html">RequiresRoles</a>
annotation requires the current Subject to have all of the specified roles. If
they do not have the role(s), the method will not be executed and an
AuthorizationException is thrown.</p>
-
-<p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-@RequiresRoles(<span class="code-quote">"administrator"</span>)
-<span class="code-keyword">public</span> void deleteUser(User user) {
- <span class="code-comment">//<span class="code-keyword">this</span> method
will only be invoked by an administrator
-</span> ...
-}
-</pre>
-</div></div>
-
-<p>This is mostly equivalent to the following Subject-based logic:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> void deleteUser(User user) {
- Subject currentUser = SecurityUtils.getSubject();
- <span class="code-keyword">if</span> (!subject.hasRole(<span
class="code-quote">"administrator"</span>)) {
- <span class="code-keyword">throw</span> <span
class="code-keyword">new</span> AuthorizationException(...);
- }
-
- <span class="code-comment">//Subject is guaranteed to be an
'administrator' here
-</span> ...
-}
-</pre>
-</div></div>
-
-<h4><a name="Authorization-The%7B%7BRequiresUser%7D%7Dannotation"></a>The
<tt>RequiresUser</tt> annotation</h4>
-
-<p>The <a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/annotation/RequiresUser.html">RequiresUser</a>*
annotation requires the current Subject to be an application user for the
annotated class/instance/method to be accessed or invoked. An 'application
user' is defined as a <tt>Subject</tt> that has a known identity, either known
due to being authenticated during the current session or remembered from
'RememberMe' services from a previous session.</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-@RequiresUser
-<span class="code-keyword">public</span> void updateAccount(Account account) {
- <span class="code-comment">//<span class="code-keyword">this</span> method
will only be invoked by a 'user'
-</span> <span class="code-comment">//i.e. a Subject with a known identity
-</span> ...
-}
-</pre>
-</div></div>
-
-<p>This is mostly equivalent to the following Subject-based logic:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> void updateAccount(Account account) {
- Subject currentUser = SecurityUtils.getSubject();
- PrincipalCollection principals = currentUser.getPrincipals();
- <span class="code-keyword">if</span> (principals == <span
class="code-keyword">null</span> || principals.isEmpty()) {
- <span class="code-comment">//no identity - they're anonymous, not
allowed:
-</span> <span class="code-keyword">throw</span> <span
class="code-keyword">new</span> AuthorizationException(...);
- }
-
- <span class="code-comment">//Subject is guaranteed to have a known
identity here
-</span> ...
-}
-</pre>
-</div></div>
-
-<h3><a name="Authorization-JSPTagLibAuthorization"></a>JSP TagLib
Authorization</h3>
-
-<p>Shiro offers a Tag Library for controlling JSP/GSP page output based on
<tt>Subject</tt> state. This is covered in the <a href="web.html"
title="Web">Web</a> chapter's <a href="web.html#Web-taglibrary">JSP/GSP Tag
Library</a> section.</p>
-
-<h2><a name="Authorization-AuthorizationSequence"></a>Authorization
Sequence</h2>
-
-<p>Now that we've seen how to perform authorization based on the current
<tt>Subject</tt>, let's take a look at what happens inside Shiro whenever an
authorization call is made.</p>
-
-<p>We've taken our previous architecture diagram from the <a
href="architecture.html" title="Architecture">Architecture</a> chapter, and
left only the components relevant to authorization highlighted. Each number
represents a step during an authorization operation:
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline"></p>
-
-<p><span class="image-wrap" style="display: block; text-align: center"><img
src="assets/images/ShiroAuthorizationSequence.png" style="border: 0px solid
black"></span></p>
-
-<p><br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-<b>Step 1</b>: Application or framework code invokes any of the
<tt>Subject</tt> <tt>hasRole*</tt>, <tt>checkRole*</tt>, <tt>isPermitted*</tt>,
or <tt>checkPermission*</tt> method variants, passing in whatever permission or
role representation is required.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-<b>Step 2</b>: The <tt>Subject</tt> instance, typically a <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/subject/support/DelegatingSubject.html">DelegatingSubject</a></tt>
(or a subclass) delegates to the application's <tt>SecurityManager</tt> by
calling the <tt>securityManager</tt>'s nearly identical respective
<tt>hasRole*</tt>, <tt>checkRole*</tt>, <tt>isPermitted*</tt>, or
<tt>checkPermission*</tt> method variants (the <tt>securityManager</tt>
implements the <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Authorizer.html">org.apache.shiro.authz.Authorizer</a></tt>
interface, which defines all Subject-specific authorization methods).
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-<b>Step 3</b>: The <tt>SecurityManager</tt>, being a basic 'umbrella'
component, relays/delegates to its internal <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Authorizer.html">org.apache.shiro.authz.Authorizer</a></tt>
instance by calling the <tt>authorizer</tt>'s respective <tt>hasRole*</tt>,
<tt>checkRole*</tt>, <tt>isPermitted*</tt>, or <tt>checkPermission*</tt>
method. The <tt>authorizer</tt> instance is by default a <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/ModularRealmAuthorizer.html">ModularRealmAuthorizer</a></tt>
instance, which supports coordinating one or more <tt>Realm</tt> instances
during any authorization operation.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
-<b>Step 4</b>: Each configured <tt>Realm</tt> is checked to see if it
implements the same <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Authorizer.html">Authorizer</a></tt>
interface. If so, the Realm's own respective <tt>hasRole*</tt>,
<tt>checkRole*</tt>, <tt>isPermitted*</tt>, or <tt>checkPermission*</tt> method
is called. </p>
-
-<h3><a
name="Authorization-%7B%7BModularRealmAuthorizer%7D%7D"></a><tt>ModularRealmAuthorizer</tt></h3>
-
-<p>As mentioned earlier, the Shiro <tt>SecurityManager</tt> implementations
default to using a <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/ModularRealmAuthorizer.html">ModularRealmAuthorizer</a></tt>
instance. The <tt>ModularRealmAuthorizer</tt> equally supports applications
with single Realm as well as those with multiple realms.</p>
-
-<p>For any authorization operation, the <tt>ModularRealmAuthorizer</tt> will
iterate over its internal collection of <tt>Realms</tt> and interact with each
one in iteration order. Each <tt>Realm</tt> interaction functions as
follows:</p>
-
-<ol><li>If the <tt>Realm</tt> itself implements the <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Authorizer.html">Authorizer</a></tt>
interface, its respective <tt>Authorizer</tt> method (<tt>hasRole*</tt>,
<tt>checkRole*</tt>, <tt>isPermitted*</tt>, or <tt>checkPermission*</tt>) is
called.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline">
- <ol><li>If the Realm's method results in an exception, the exception is
propagated as an <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authc/AuthenticationException.html">AuthorizationException</a></tt>
to the <tt>Subject</tt> caller. This short-circuits the authorization process
and any remaining Realms will not be consulted for that authorization operation.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline"></li><li>If the Realm's method is
a <tt>hasRole*</tt> or <tt>isPermitted*</tt> variant that returns a boolean and
that return value is <tt>true</tt>, the <tt>true</tt> value is returned
immediately and any remaining Realms are short circuited. This behavior exists
as a performance enhancement, as typically if permitted by one Realm, it is
implied that the Subject is permitted. This favors security policies where
everything is prohibited by default and things are explicitly allowed, the most
secure type of security policy.
-<br clear="none" class="atl-forced-newline">
-<br clear="none" class="atl-forced-newline"></li></ol>
- </li><li>If the Realm does not implement the <tt>Authorizer</tt>
interface, it is ignored.</li></ol>
-
-
-<h4><a name="Authorization-RealmAuthorizationOrder"></a>Realm Authorization
Order</h4>
-
-<p>It is important to point out that, exactly like authentication, the
<tt>ModularRealmAuthorizer</tt> will interact with Realm instances in
<em>iteration</em> order.</p>
-
-<p>The <tt>ModularRealmAuthorizer</tt> has access to the <tt>Realm</tt>
instances configured on the <tt>SecurityManager</tt>. When executing an
authorization operation, it will iterate over that collection, and for each
<tt>Realm</tt> that implements the <tt>Authorizer</tt> interface itself, invoke
the Realm's respective <tt>Authorizer</tt> method (e.g. <tt>hasRole*</tt>,
<tt>checkRole*</tt>, <tt>isPermitted*</tt>, or <tt>checkPermission*</tt>).</p>
-
-<h4><a
name="Authorization-Configuringaglobal%7B%7BPermissionResolver%7D%7D"></a>Configuring
a global <tt>PermissionResolver</tt></h4>
-
-<p>When performing a <tt>String</tt>-based permission check, most of Shiro's
default <tt>Realm</tt> implementations convert this String into an actual
<tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/Permission.html">Permission</a></tt>
instance first before performing permission <em>implication</em> logic. </p>
-
-<p>This is because Permissions are evaluated based on implication logic and
not a direct equality check (see the <a href="permissions.html"
title="Permissions">Permission</a> documentation for more about implication vs.
equality). Implication logic is better represented in code than via String
comparisons. Therefore, most Realms need to convert, or <em>resolve</em> a
submitted permission string into a corresponding representative
<tt>Permission</tt> instance.</p>
-
-<p>To aid in this conversion, Shiro supports the notion of a <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/permission/PermissionResolver.html">PermissionResolver</a></tt>.
Most <tt>Shiro</tt> Realm implementations use a <tt>PermissionResolver</tt>
to support their implementation of the <tt>Authorizer</tt> interface's
<tt>String</tt>-based permission methods: when one of these methods is invoked
on the Realm, it will use the <tt>PermissionResolver</tt> to convert the string
into a Permission instance, and perform the check that way.</p>
-
-<p>All Shiro <tt>Realm</tt> implementations default to an internal <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/permission/WildcardPermissionResolver.html">WildcardPermissionResolver</a></tt>
which assumes Shiro's <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/permission/WildcardPermission.html">WildcardPermission</a></tt>
String format.</p>
-
-<p>If you want to create your own <tt>PermissionResolver</tt> implementation,
perhaps to support your own Permission string syntax, and you want all
configured <tt>Realm</tt> instances to support that syntax, you can set your
<tt>PermissionResolver</tt> globally for all <tt>Realms</tt> that can be
configured with one.</p>
-
-<p>For example, in <tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader
panelHeader" style="border-bottom-width: 1px;"><b>shiro.ini</b></div><div
class="codeContent panelContent">
-<pre class="code-java">
-globalPermissionResolver = com.foo.bar.authz.MyPermissionResolver
-...
-securityManager.authorizer.permissionResolver = $globalPermissionResolver
-...
-</pre>
-</div></div>
-
-<div class="panelMacro"><table class="noteMacro"><colgroup span="1"><col
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1"
valign="top"><img align="middle"
src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif"
width="16" height="16" alt="" border="0"></td><td colspan="1"
rowspan="1"><b>PermissionResolverAware</b><br clear="none">If you want to
configure a global <tt>PermissionResolver</tt>, each <tt>Realm</tt> that is to
receive the configured <tt>PermissionResolver</tt> <b><em>must</em></b>
implement the <tt><a class="external-link"
href="static/current/apidocs/src-html/org/apache/shiro/authz/permission/PermissionResolverAware.html">PermisionResolverAware</a></tt>
interface. This guarantees that the configured instance can be relayed to
each <tt>Realm</tt> that supports such configuration.</td></tr></table></div>
-
-<p>If you don't want to use a global <tt>PermissionResolver</tt> or you don't
want to be bothered with the <tt>PermissionResolverAware</tt> interface, you
can always configure a realm with a <tt>PermissionResolver</tt> instance
explicitly (assuming there is a JavaBeans-compatible setPermissionResolver
method):</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-permissionResolver = com.foo.bar.authz.MyPermissionResolver
-
-realm = com.foo.bar.realm.MyCustomRealm
-realm.permissionResolver = $permissionResolver
-...
-</pre>
-</div></div>
-
-<h4><a
name="Authorization-Configuringaglobal%7B%7BRolePermissionResolver%7D%7D"></a>Configuring
a global <tt>RolePermissionResolver</tt></h4>
-
-<p>Similar in concept to a <tt>PermissionResolver</tt>, a <tt><a
class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/permission/RolePermissionResolver.html">RolePermissionResolver</a></tt>
has the ability to represent <tt>Permission</tt> instances needed by a
<tt>Realm</tt> to perform permission checks.</p>
-
-<p>The key difference with a <tt>RolePermissionResolver</tt> however is that
the input <tt>String</tt> is a <em>role name</em>, and <em>not</em> a
permission string.</p>
-
-<p>A <tt>RolePermissionResolver</tt> can be used by a <tt>Realm</tt>
internally when needing to translate a role name into a concrete set of
<tt>Permission</tt> instances. </p>
-
-<p>This is a particularly useful feature for supporting legacy or inflexible
data sources that may have no notion of permissions.</p>
-
-<p>For example, many LDAP directories store role names (or group names) but do
not support association of role names to concrete permissions because they have
no 'permission' concept. A Shiro-based application can use the role names
stored in LDAP, but implement a <tt>RolePermissionResolver</tt> to convert the
LDAP name into a set of explicit permissions to perform preferred explicit
access control. The permission associations would be stored in another data
store, probably a local database.</p>
-
-<p>Because this notion of converting role names to permissions is very
application specific, Shiro's default <tt>Realm</tt> implementations do not use
them.</p>
-
-<p>However, if you want to create your own <tt>RolePermissionResolver</tt> and
have more than one <tt>Realm</tt> implementation that you want to configure
with it, you can set your <tt>RolePermissionResolver</tt> globally for all
<tt>Realms</tt> that can be configured with one.</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader
panelHeader" style="border-bottom-width: 1px;"><b>shiro.ini</b></div><div
class="codeContent panelContent">
-<pre class="code-java">
-globalRolePermissionResolver = com.foo.bar.authz.MyPermissionResolver
-...
-securityManager.authorizer.rolePermissionResolver =
$globalRolePermissionResolver
-...
-</pre>
-</div></div>
-
-<div class="panelMacro"><table class="noteMacro"><colgroup span="1"><col
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1"
valign="top"><img align="middle"
src="https://cwiki.apache.org/confluence/images/icons/emoticons/warning.gif"
width="16" height="16" alt="" border="0"></td><td colspan="1"
rowspan="1"><b>RolePermissionResolverAware</b><br clear="none">If you want to
configure a global <tt>RolePermissionResolver</tt>, each <tt>Realm</tt> that is
to receive the configured <tt>RolePermissionResolver</tt> <b><em>must</em></b>
implement the <tt><a class="external-link"
href="static/current/apidocs/org/apache/shiro/authz/permission/RolePermissionResolverAware.html">RolePermisionResolverAware</a></tt>
interface. This guarantees that the configured global
<tt>RolePermissionResolver</tt> instance can be relayed to each <tt>Realm</tt>
that supports such configuration.</td></tr></table></div>
-
-<p>If you don't want to use a global <tt>RolePermissionResolver</tt> or you
don't want to be bothered with the <tt>RolePermissionResolverAware</tt>
interface, you can always configure a realm with a
<tt>RolePermissionResolver</tt> instance explicitly (assuming there is a
JavaBeans-compatible setRolePermissionResolver method):</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-rolePermissionResolver = com.foo.bar.authz.MyRolePermissionResolver
-
-realm = com.foo.bar.realm.MyCustomRealm
-realm.rolePermissionResolver = $rolePermissionResolver
-...
-</pre>
-</div></div>
-
-<h3><a name="Authorization-CustomAuthorizer"></a>Custom Authorizer</h3>
-
-<p>If your application uses more than one realm to perform authorization and
the <tt>ModularRealmAuthorizer</tt>'s default simple iteration-based,
short-circuiting authorization behavior does not suit your needs, you will
probably want to create a custom <tt>Authorizer</tt> and configure the
<tt>SecurityManager</tt> accordingly.</p>
-
-<p>For example, in <tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent
panelContent">
-<pre class="code-java">
-[main]
-...
-authorizer = com.foo.bar.authz.CustomAuthorizer
-
-securityManager.authorizer = $authorizer
-</pre>
-</div></div>
\ No newline at end of file