diff --git a/spring/Apache Shiro/Apache Shiro Authorization.md b/spring/Apache Shiro/Apache Shiro Authorization.md index 1c15c20..77eec9a 100644 --- a/spring/Apache Shiro/Apache Shiro Authorization.md +++ b/spring/Apache Shiro/Apache Shiro Authorization.md @@ -3,4 +3,79 @@ Authorization(访问控制),分配访问某资源的特定权限。 ## Authorization的核心元素 ### Permission -Permission是 \ No newline at end of file +Permission是最原子级别的安全策略,用来控制用户与应用进行交互时可以执行哪些操作。**格式良好的permission描述了资源的类型和与该资源交互时可以执行的操作。** +对于与数据相关的资源,权限通常有create、read、update、delete(CRUD)。 +#### 权限粒度级别 +在Shiro中,可以在任何粒度对permission进行定义。如下是permission粒度的一些定义: +1. Resource级别:该级别是最广泛和最容易构建的粒度级别,在该级别用户可以对资源执行特定的操作。**在Resource级别,该资源类型被指定,但是没有限制用户操作特定的资源实例(即用户可以对该Resource类型的所有实例进行操作)** +2. Instance级别:该级别限定了Permission可以操作的Resource Instance,在该级别用户只能够对特定的Resource实例进行操作。 +3. Attribute级别:该级别比限定了Permission可以操作Resouce类型或Resource实例的某个属性 +### Roles +Roles是一个Permission的集合,用于简化权限和用户管理过程。用户可以被授予特定的角色来获得操作某些资源的权限。 +#### Role分类 +1. Role不实际关联具体的Permission,当你具有banker的角色时,其角色隐含你可以对账户进行操作的权限;当你具有waiter的角色时,默认可以对厨房的door进行open/close操作 +2. Role实际关联具体的Permission,在该情况下Role即为一系列Permission的集合,你可以对银行账号进行create、delete操作,因为操作银行账号是你已分配的admin角色的一个下属权限 +### User +在Shiro中,User即是一个Subject实例。在Shiro中,Subject可以是任何与系统进行交互的主体,可以是浏览器、客户端、crond定时任务等。 +## 在Apache Shiro中实行Authorization +在Apache Shiro中,Authorization可以通过如下方式执行: +1. 通过代码实现:即在java程序中通过代码实现访问控制 +2. jdk注解:可以在你的方法上加上authorization注解 +3. jsp/gsp taglibs +### 通过java code实现authorization +可以通过如下代码进行角色鉴定: +```java +//get the current Subject +Subject currentUser = SecurityUtils.getSubject(); + +if (currentUser.hasRole("administrator")) { + //show a special button +} else { + //don’t show the button?) +} +``` +可以通过如下代码实现对权限的鉴定操作: +```java +Subject currentUser = SecurityUtils.getSubject(); + +Permission printPermission = new PrinterPermission("laserjet3000n","print"); + +If (currentUser.isPermitted(printPermission)) { + //do one thing (show the print button?) +} else { + //don’t show the button? +} +``` +#### 基于String的权限鉴定 +如果不想构造Permission对象,可以通过构造一个字符串来代表权限。该字符串可以是任何格式,只要你的Realm能够识别该格式并且与权限进行交互。 +```java +String perm = "printer:print:laserjet4400n"; + +if(currentUser.isPermitted(perm)){ + //show the print button? +} else { + //don’t show the button? +} +``` +### 通过注解实现Authorization +可以通过java注解来实现Authorization过程,**在使用注解之前,必须先开启aop**。 +如果在执行openAccount之前,当前Subject必须拥有account:create权限,那么可以通过如下方式来实现权限鉴定。如果当前用户未被直接授予或通过role间接授予该权限,那么会抛出AuthorizationException异常。 +```java +//Will throw an AuthorizationException if none +//of the caller’s roles imply the Account +//'create' permission +@RequiresPermissions("account:create") +public void openAccount( Account acct ) { + //create the account +} +``` +如果要在执行方法之前进行角色校验,可以通过如下方式加上注解达到预期功能。 +```java +//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 +} +``` \ No newline at end of file