给JFinal添加Shiro插件功能,支持Shiro所有注解-使用篇
给JFinal添加Shiro插件功能,支持Shiro所有注解-使用篇
玛雅牛 发表于5年前
给JFinal添加Shiro插件功能,支持Shiro所有注解-使用篇
  • 发表于 5年前
  • 阅读 24745
  • 收藏 92
  • 点赞 22
  • 评论 42

腾讯云 技术升级10大核心产品年终让利>>>   

基于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

 

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRoles {
    String[] value();
    Logical logical() default Logical.AND; 
}

可以用在Controller或者方法上。可以多个roles,默认逻辑为 AND也就是所有具备所有role才能访问。

示例:

 

属于user角色
@RequiresRoles("user")

必须同时属于user和admin角色
@RequiresRoles({"user","admin"})

属于user或者admin之一。
@RequiresRoles(value={"user","admin"},logical=Logical.OR)

2)RequiresPermissions

 

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {
    String[] value();
    Logical logical() default Logical.AND; 
}

RequiresRoles及其类似,使用如下

 

@RequiresPermissions("index:hello")
@RequiresPermissions({"index:hello","index:world"})
@RequiresPermissions(value={"index:hello","index:world"},logical=Logical.OR)

3)RequiresAuthentication,RequiresUser,RequiresGuest

这三个使用方法类似。

 

@RequiresAuthentication
@RequiresUser
@RequiresGusst

4)这个是本人额外新增的一个注解@ClearShiro,用来清除某个方法上的所有访问控制注解。

这个主要用于某个Controller的绝大部分方法都需要某个角色的权限,但是个别方法例外的情况。

 

@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。

 

me.setErrorView(401, "/au/login.html");
me.setErrorView(403, "/au/login.html");
me.setError404View("/404.html");
me.setError500View("/500.html");

3)顶一个routes成员变量。

public class AppConfig extends JFinalConfig {
	/**
	 * 供Shiro插件使用。
	 */
	Routes routes;

4)在configRoute方法中加入this.routes = me;

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) {方法的最好加入

 

//加载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)配置一个拦截器,我这是配置了一个全局拦截器,在某些系统中,可以只给后他需要验证的部分添加拦截器,前台部分可以不用该访问控制拦截器。

 

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

 

[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前面添加

 

<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中配置了

[urls]
/** = anon
/card/** = user
/school/** = user

相关访问控制规则,ShiroFilter会优先匹配这些规则,这个规则通过后,才会执行JFinal的Filer。才会进入JFinal的处理循环。

 

标签: JFinal Shiro 应用
共有 人打赏支持
玛雅牛
粉丝 472
博文 104
码字总数 26328
作品 4
评论 (42)
JFinal
代量码少,使用简单,顶一个,谢谢分享 :)
木川瓦兹
写个详细的教程吧
木川瓦兹
写个详细的教程吧,一步一步怎么集成shiro还有这个插件
玛雅牛

引用来自“飞翔的猴子”的评论

写个详细的教程吧,一步一步怎么集成shiro还有这个插件

最近比较忙,因为项目中要用Shiro,才做了这个插件。
使用注意哪里该写的都写了。一步一步的教程只能等不忙了写了。
这个插件考虑使用者应该有一定的经验,而不是初学者。呵呵。见谅啊。
小鲅鱼
支持~~~
小鲅鱼
@玛雅牛
3)public void configPlugin(Plugins me) {方法的最好加入
//加载Shiro插件
me.add(new ShiroPlugin()); ShiroPlugin()不需要 routes参数了吗?
玛雅牛

引用来自“eyelee”的评论

@玛雅牛
3)public void configPlugin(Plugins me) {方法的最好加入
//加载Shiro插件
me.add(new ShiroPlugin()); ShiroPlugin()不需要 routes参数了吗?

需要routes参数的。忘记修改了。多谢提醒。
小鲅鱼

引用来自“玛雅牛”的评论

引用来自“eyelee”的评论

@玛雅牛
3)public void configPlugin(Plugins me) {方法的最好加入
//加载Shiro插件
me.add(new ShiroPlugin()); ShiroPlugin()不需要 routes参数了吗?

需要routes参数的。忘记修改了。多谢提醒。

发现提供的JFinalShiroPlugin.jar 与 JFinal.jar中shiro插件的类导入冲突~~ @JFinal 啥时候整合进去啊?
玛雅牛

引用来自“eyelee”的评论

引用来自“玛雅牛”的评论

引用来自“eyelee”的评论

@玛雅牛
3)public void configPlugin(Plugins me) {方法的最好加入
//加载Shiro插件
me.add(new ShiroPlugin()); ShiroPlugin()不需要 routes参数了吗?

需要routes参数的。忘记修改了。多谢提醒。

发现提供的JFinalShiroPlugin.jar 与 JFinal.jar中shiro插件的类导入冲突~~ @JFinal 啥时候整合进去啊?

http://git.oschina.net/myaniu/jfinalshiroplugin
下载源码,然后自己改下包名,或者直接打包进jfinal中。
玛雅牛
Shiro的认证注解处理是有内定的处理顺序的,如果有个多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关):
RequiresRoles
RequiresPermissions
RequiresAuthentication
RequiresUser
RequiresGuest
例如:你同时生命了RequiresRoles和RequiresPermissions,那就要求拥有此角色的同时还得拥有相应的权限。
callmeHEN
你好,我搞了一天了。搞不定 特来请教。
jfinal+shiro,我完全按照你的来。但是我配置了shiro的cache就报shiro cache冲突,我删除shiro.ini里的cache可以启动正常。

我登录是成功的,但是访问路径时,还是要跳转到login,不知道怎么回事。

另外,我的jsp页面 加上shiro标签就出错。org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code,也不知道是什么原因。。。。哎,求指点
邹德雄
大牛,您整合的shiro插件里头是不是应该在各种AuthzHandler里面判断下是否验证登陆呢?因为我发现只要登陆一次,验证通过,不管重启多少次,都不需要重新登陆验证。建议:assertAuthorized() 方法里面加上
Subject user = getSubject();
if(!user.isAuthenticated()){
  throw new UnauthenticatedException("Unauthorized ...");
}
然后再做检查验证操作。。
玛雅牛

引用来自“邹德雄”的评论

大牛,您整合的shiro插件里头是不是应该在各种AuthzHandler里面判断下是否验证登陆呢?因为我发现只要登陆一次,验证通过,不管重启多少次,都不需要重新登陆验证。建议:assertAuthorized() 方法里面加上
Subject user = getSubject();
if(!user.isAuthenticated()){
  throw new UnauthenticatedException("Unauthorized ...");
}
然后再做检查验证操作。。

浏览器需要全部关闭才行。是否使用了RememberMe功能?
overtake
支持,技术帖子!赞
dandyIder
是不是类似 spring security
的安全框架?
先 make 下
tflyy14
大牛,按照你方法,我进行了配置,基本上可以正常运行了,但是注解不起作用,难道要使用spring这样的AOP框架才行吗
玛雅牛

引用来自“tflyy14”的评论

大牛,按照你方法,我进行了配置,基本上可以正常运行了,但是注解不起作用,难道要使用spring这样的AOP框架才行吗

注解要起作用,必须添加shiro的拦截器才行。
tflyy14

引用来自“玛雅牛”的评论

引用来自“tflyy14”的评论

大牛,按照你方法,我进行了配置,基本上可以正常运行了,但是注解不起作用,难道要使用spring这样的AOP框架才行吗

注解要起作用,必须添加shiro的拦截器才行。

我添加了拦截器的,但是里面具体代码该如何实现呢,有没有具体实现代码呢?谢谢
玛雅牛

引用来自“tflyy14”的评论

引用来自“玛雅牛”的评论

引用来自“tflyy14”的评论

大牛,按照你方法,我进行了配置,基本上可以正常运行了,但是注解不起作用,难道要使用spring这样的AOP框架才行吗

注解要起作用,必须添加shiro的拦截器才行。

我添加了拦截器的,但是里面具体代码该如何实现呢,有没有具体实现代码呢?谢谢

参照本例1),2),3),4)。本文仅是对jfinal和shiro进行集成,若要用好,还需了解下shiro的相关知识。
tflyy14

引用来自“玛雅牛”的评论

引用来自“tflyy14”的评论

引用来自“玛雅牛”的评论

引用来自“tflyy14”的评论

大牛,按照你方法,我进行了配置,基本上可以正常运行了,但是注解不起作用,难道要使用spring这样的AOP框架才行吗

注解要起作用,必须添加shiro的拦截器才行。

我添加了拦截器的,但是里面具体代码该如何实现呢,有没有具体实现代码呢?谢谢

参照本例1),2),3),4)。本文仅是对jfinal和shiro进行集成,若要用好,还需了解下shiro的相关知识。

大神,我根据你的方法做了以后,发现登陆以后,过1分钟左右刷新页面的时候,sessionid就发生了变化,需要重新登陆(session超期时间为30分钟),其他的功能都正常,请问有什么方法可以解决吗?
×
玛雅牛
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: