源地址 : 点击打开链接
基于JDK1.6打包好的包括源码的Shiro插件在以下地址:
http://git.oschina.net/myaniu/jfinalshiroplugin/blob/master/dist/JFinalShiroPlugin-1.0.jar
Shiro共有5个注解,分别如下:
-
RequiresAuthentication:使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。
-
RequiresGuest:使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。
-
RequiresPermissions:当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。
-
RequiresRoles:当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。
-
RequiresUser:当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。
多个注解的问题:
Shiro的认证注解处理是有内定的处理顺序的,如果有个多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关):
RequiresRoles
RequiresPermissions
RequiresAuthentication
RequiresUser
RequiresGuest
例如:你同时生命了RequiresRoles和RequiresPermissions,那就要求拥有此角色的同时还得拥有相应的权限。
1)RequiresRoles
1
2
3
4
5
6
|
@Target
({ElementType.TYPE, ElementType.METHOD})
@Retention
(RetentionPolicy.RUNTIME)
public
@interface
RequiresRoles {
String[] value();
Logical logical()
default
Logical.AND;
}
|
可以用在Controller或者方法上。可以多个roles,默认逻辑为 AND也就是所有具备所有role才能访问。
示例:
1
2
3
4
5
6
7
8
|
属于user角色
@RequiresRoles
(
"user"
)
必须同时属于user和admin角色
@RequiresRoles
({
"user"
,
"admin"
})
属于user或者admin之一。
@RequiresRoles
(value={
"user"
,
"admin"
},logical=Logical.OR)
|
2)RequiresPermissions
1
2
3
4
5
6
|
@Target
({ElementType.TYPE, ElementType.METHOD})
@Retention
(RetentionPolicy.RUNTIME)
public
@interface
RequiresPermissions {
String[] value();
Logical logical()
default
Logical.AND;
}
|
和 RequiresRoles及其类似,使用如下
1
2
3
|
@RequiresPermissions
(
"index:hello"
)
@RequiresPermissions
({
"index:hello"
,
"index:world"
})
@RequiresPermissions
(value={
"index:hello"
,
"index:world"
},logical=Logical.OR)
|
3)RequiresAuthentication,RequiresUser,RequiresGuest
这三个使用方法类似。
1
2
3
|
@RequiresAuthentication
@RequiresUser
@RequiresGusst
|
4)这个是本人额外新增的一个注解@ClearShiro,用来清除某个方法上的所有访问控制注解。
这个主要用于某个Controller的绝大部分方法都需要某个角色的权限,但是个别方法例外的情况。
1
2
3
4
|
@RequiresRoles
(
"user"
)
public
class
LoginController
extends
Controller {
@ClearShiro
public
void
index(){
|
使用时需要做以下事项:
1)Shiro依赖于slf4j,commons-beanutils,commons-logging三个jar包。
2)public void configConstant(Constants me) { 方法中需加入401,403错误代码处理。
分别对应如下:
RequiresGuest,RequiresAuthentication,RequiresUser,未满足时,抛出未经授权的异常。
如果没有进行身份验证,返回HTTP401状态码
RequiresRoles,RequiresPermissions授权异常,如果没有权限访问对应的资源,返回HTTP状态码403。
1
2
3
4
|
me.setErrorView(
401
,
"/au/login.html"
);
me.setErrorView(
403
,
"/au/login.html"
);
me.setError404View(
"/404.html"
);
me.setError500View(
"/500.html"
);
|
3)顶一个routes成员变量。
1
2
3
4
5
|
public
class
AppConfig
extends
JFinalConfig {
/**
* 供Shiro插件使用。
*/
Routes routes;
|
4)在configRoute方法中加入this.routes = me;
1
2
3
4
5
|
public
void
configRoute(Routes me) {
this
.routes = me;
// TODO Auto-generated method stub
me.add(
"/"
, IndexController.
class
);
me.add(
"/au"
,AdminUserController.
class
);
|
5)public void configPlugin(Plugins me) {方法的最好加入
1
2
3
4
5
6
7
|
//加载Shiro插件
//me.add(new ShiroPlugin(routes));
ShiroPlugin shiroPlugin =
new
ShiroPlugin(
this
.routes);
shiroPlugin.setLoginUrl(
"/login.do"
);
shiroPlugin.setSuccessUrl(
"/index.do"
);
shiroPlugin.setUnauthorizedUrl(
"/login.do"
);
me.add(shiroPlugin);
|
6)配置一个拦截器,我这是配置了一个全局拦截器,在某些系统中,可以只给后他需要验证的部分添加拦截器,前台部分可以不用该访问控制拦截器。
1
2
3
4
|
public
void
configInterceptor(Interceptors me) {
// TODO Auto-generated method stub
me.add(
new
ShiroInterceptor());
}
|
7)根据需要实现一个Realm,继承自AuthorizingRealm即可。
可参考:
http://www.oschina.net/question/176164_35893
8)配置shiro.ini文件,该文件需放在 /WEB-INF/shiro.ini这个位置。我的shiro.ini如下:
参考了http://my.oschina.net/smile622/blog/135098
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[main]
#realm
myRealm = com.lh.openapi.manager.shiro.ShiroDbRealm
securityManager.realm = $myRealm
#cache
shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
shiroCacheManager.cacheManagerConfigFile = classpath:ehcache-shiro.xml
securityManager.cacheManager = $shiroCacheManager
#session
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO.activeSessionsCacheName = shiro-activeSessionCache
sessionManager.sessionDAO = $sessionDAO
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout =
360000
#这里的规则,web.xml中的配置的ShiroFilter会使用到。
[urls]
/** = anon
/card/** = user
/school/** = user
/rpc/rest/** = perms[rpc:invoke], authc
/** = authc
|
9)配置web.xml在所有filter前面添加
1
2
3
4
5
6
7
8
9
10
11
|
<
listener
>
<
listener-class
>org.apache.shiro.web.env.EnvironmentLoaderListener</
listener-class
>
</
listener
>
<
filter
>
<
filter-name
>shiro</
filter-name
>
<
filter-class
>org.apache.shiro.web.servlet.ShiroFilter</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>shiro</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
|
若shiro.ini中配置了
1
2
3
4
|
[urls]
/** = anon
/card/** = user
/school/** = user
|
相关访问控制规则,ShiroFilter会优先匹配这些规则,这个规则通过后,才会执行JFinal的Filer。才会进入JFinal的处理循环。
----------------------------------------------------------
陕西威尔伯乐信息技术有限公司 玛雅牛