Tapestry 最新版5.1.0.5教程(九):权限控制框架的实现-进阶篇

 

在上一篇中我们研究了如何实现SpringSecurity中Jsp Tag的<security:authorize ifAllGranted="ROLE_SUPERVISOR">的功能。这一次我们一起研究一下如何实现在Tapestry5.1中添加一个 Filter来对所有的操作进行权限的过滤控制。
在SpringSecurity中,我们一般是在application-context.xml中,添加一个SpringSecurity的 Filter,然后在另外一个xml中详细配置如何根据Url的规则进行权限的控制。而Tapestry的哲学是尽量减少Xml中的配置(其IOC容器也 基本上是借鉴Guice而不Spring的),所以我们也是在代码中实现权限规则的控制。
总体上来看,可以用两种方式来实现url规则,一种是Request级别的Filter,一种是页面组件级别的Filter,如果是Request级别的 话,可以从Request对象中获取Url路径,这样就与SpringSecurity基本一样了。本文主要介绍页面组件级别的Filter,从中我们也 可以体会到Tapestry5.1中的IOC容器的强大和便利。

这就是Filter的代码,这个Filter必须实现ComponentRequestFilter接口。值得注意的是其构造函数所需要用到的4个 参数,这4个参数都是Tapestry5本身自有的服务,所以我们什么也不用做,Tapestry5自动会将服务的实例注入进来,这就是 Tapestry-IOC的威力。
ComponentRequestFilter接口一共有4个方法需要实现,具体代码如下:

 1  public   class  RequiresLoginFilter  implements  ComponentRequestFilter {
 2 
 3       private   final  PageRenderLinkSource renderLinkSource;
 4 
 5       private   final  ComponentSource componentSource;
 6 
 7       private   final  Response response;
 8     
 9       private   final  ApplicationStateManager appStateManager;
10     
11       public  RequiresLoginFilter(PageRenderLinkSource renderLinkSource,
12              ComponentSource componentSource, Response response,
13              ApplicationStateManager appStateManager
14              ) {
15           this .renderLinkSource  =  renderLinkSource;
16           this .componentSource  =  componentSource;
17           this .response  =  response;
18           this .appStateManager  =  appStateManager;
19      }
20 
21       public   void  handleComponentEvent(
22              ComponentEventRequestParameters parameters,
23              ComponentRequestHandler handler)  throws  IOException {
24 
25           if  (dispatchedToLoginPage(parameters.getActivePageName())) {
26               return ;
27          }
28 
29          handler.handleComponentEvent(parameters);
30 
31      }
32 
33       public   void  handlePageRender(PageRenderRequestParameters parameters,
34              ComponentRequestHandler handler)  throws  IOException {
35           if  (dispatchedToLoginPage(parameters.getLogicalPageName())) {
36               return ;
37          }
38          handler.handlePageRender(parameters);
39 
40      }
41 
42       private   boolean  dispatchedToLoginPage(String pageName) {
43          Component page  =  componentSource.getPage(pageName);
44         
45           if  (page.getClass().isAnnotationPresent(RequiresLogin. class )) {
46               if  (  !  appStateManager.exists(Authentication. class )) {
47                  redirect();
48                   return   true ;
49              }
50              Authentication auth  =  appStateManager.get(Authentication. class );
51               if  ( auth  ==   null  ) {
52                  redirect();
53                   return   true ;
54              }
55             
56                if  (  !  auth.isLoggedIn()) {
57                   redirect();
58                    return   true ;
59               }
60 
61              RequiresLogin requireLogin  =  page.getClass().getAnnotation(
62                      RequiresLogin. class );
63              String ifNotGranted  =  requireLogin.ifNotGranted();
64              String ifAllGranted  =  requireLogin.ifAllGranted();
65              String ifAnyGranted  =  requireLogin.ifAnyGranted();
66               boolean  permitted  =  auth.checkPermission(ifNotGranted, ifAllGranted, ifAnyGranted);
67               if  (  !  permitted ) {
68                   return   true ;
69              }
70          }
71 
72           return   false ;
73      }
74     
75       private   void  redirect() {
76           Link link  =  renderLinkSource.createPageRenderLink( " Logout " );
77         
78            try  {
79               response.sendRedirect(link);
80           }  catch  (Exception e) {
81           }
82      }
83 
84  }

 

在ComponentRequestFilter中,我们无法使用@SessionState注解来直接注入Session中的变量,但是我们可以 通过ApplicationStateManager来取得。

现在我们需要把刚定义的Filter注册到系统中,很简单,只要在AppModule中添加以下函数就行了:

1  public   static   void  contributeComponentRequestHandler(
2                  OrderedConfiguration < ComponentRequestFilter >  configuration) {
3          configuration.addInstance( " RequiresLogin " , RequiresLoginFilter. class );
4  }

从本例子中我们可以看到Tapesty Ioc容器使用的便利性,也认识到了Ioc容器在Tapestry体系中的重要性

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值