RCP实践之安全模型

    感谢大家最近对本系列的关注和评论,我会继续完善内容,并且总结教训写出更好的东东来。
    今天谈谈最近在研究的RCP安全模型,其实RCP在诞生之初就是建立在一个非常鲁棒的框架之上的---OSGi,它不但有全新的概念,全新的思路,全新的热插拔技术,还有非常好的安全模型( equinox security 项目好像还在孵化中) 。

    解决RCP的安全问题,从最近的调研中看是有四种方式:
1.equinox security项目;
2.使用org.eclipse.ui.activities扩展点定义可访问权限和角色;
3.使用Eclipse-JAAS插件;
4.自己写代码在对功能点进行过滤;

   第一种方案不可行,因为equinox security项目还在孵化中,而且没有充足的文档,因此放弃;
   第二种方案可行,但是灵活性不够,我们很难在项目开始之初充分的定义出所有的角色以及角色对应的权限,而且还要引入大量的配置,所以也放弃;
   第三种方案可能可行,因为从老外的文档中看出,这个插件是可用的,而且是强大的,它的原理就是定义了一堆自己的扩展点,然后通过分析扩展点,过滤掉不可用的功能点。但是这个插件的更新时间竟然是2005年,N久都没有人管过了~而且还是基于Eclipse3.0的实现,所以也放弃了;
    我选择的是第四种方案,自己写代码对功能点进行过滤,其实思路很简单,我们定义基类,在基类中过滤掉有那些功能点可以被显示,或者不能被显示。
    RCP应用中所需要关注安全点主要是:
1.Action
2.Viewer
3.编辑器
4.透视图
    经过讨论,其实我们的关注点主要集中在Action和透视图,因为透视图总会包含一组Viewer出现所以我们只要在透视图布局类中将我们不需要关注的Viewer过滤掉,那么Viewer就可以被管理起来了,而编辑器的出现也主要是针对Viewer出现的,如果一个Viewer不能显示,那么和它对应的编辑器也永远无法显示,所以编辑器几乎不用考虑。
   其实安全模型的核心就是Action,Viewer,透视图。
   对于Action,存在两种,一种是开发人员自己在代码中创建出来的Action(new Action),另一种就是在plugin.xml中配置的。
  第一种情况的基类:
 1 package  com.glnpu.dmp.client.platform.core.internal.security.absaction;
 2
 3 import  org.apache.log4j.Logger;
 4 import  org.eclipse.jface.action.Action;
 5 import  org.eclipse.jface.resource.ImageDescriptor;
 6
 7 import  com.glnpu.dmp.client.platform.core.internal.security.SecurityManager;
 8
 9 /** */ /**
10 * 继承自<code>Action</code>,在构造方法中加入用户权限判断。
11 * @author lign
12 *
13 */

14 public   abstract   class  AbstractSecurityAction  extends  Action  {
15    private Logger log = Logger.getLogger(this.getClass());
16    
17    public AbstractSecurityAction(String text, ImageDescriptor image){
18        super(text, image);
19        this.setActionId();
20        log.debug("当前处理的Action为: " + this.getId());
21        //权限判断
22        SecurityManager.securityFiltration(this);
23    }

24    /** *//**
25     * 实现者必须实现此方法,并在方法内调用setId方法,为Action命名。
26     */

27    public abstract void setActionId();
28}
开发人员自己创建的Action都继承自AbstractSecurityAction类,在此类的构造方法中,调用SecurityManager.securityFiltration(this);方法,判断当前Action的ID是否与当前用户权限的中的ID相同,如果相同则调用action.setEnabled(true);,否则则是action.setEnabled(false);
     /** */ /**
     * 通过传入的IAction实例的id,判断是否与用户对应的权限相同,如果存在与用户权限中,则此IAction为可视,否则为不可视。
     * 
@param action
     
*/

    
public   static   void  securityFiltration(IAction action) {
        
if(action!=null{
            action.setEnabled(
false);
            
if(action.getId()!=null && !action.getId().equals("")) {
                log.debug(
"当前处理的Action为 : " + action.getId() + " 当前用户可用Action列表长度为 :" + UserInfo.getInstance().getActionList().size());
                
for(String str : UserInfo.getInstance().getActionList()) {
                    
if(str.equals(action.getId())) {
                        action.setEnabled(
true);
                        log.debug(
"当前Action : " + action.getId() + "与用户可用Action列表中Action匹配,此Action可显示");
                        
return;
                    }

                }

            }

        }

    }

   第二种情况的基类:
 1 package  com.glnpu.dmp.client.platform.core.internal.security.absaction;
 2
 3 import  org.eclipse.jface.action.IAction;
 4 import  org.eclipse.jface.viewers.ISelection;
 5 import  org.eclipse.ui.IEditorActionDelegate;
 6 import  org.eclipse.ui.IEditorPart;
 7
 8 import  com.glnpu.dmp.client.platform.core.internal.security.SecurityManager;
 9
10 /** */ /**
11 * 实现自<code>IEditorActionDelegate</code>重载selectionChanged方法,在其中加入用户权限判断。
12 * @author lign
13 *
14 */

15 public   abstract   class  AbstractSecurityEditorActionDelegate  implements  IEditorActionDelegate  {
16
17    /**//* (non-Javadoc)
18     * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
19     */

20    public abstract void setActiveEditor(IAction action, IEditorPart targetEditor);
21
22    /**//* (non-Javadoc)
23     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
24     */

25    public abstract void run(IAction action);
26
27    /**//* 
28     * 重载方法,加入权限判断重置Action是否可用
29     */

30    public void selectionChanged(IAction action, ISelection selection) {
31        //判断权限
32        SecurityManager.securityFiltration(action);
33    }

34
35}
以上是扩展editorAction扩展点时要继承的基类,其他两种情况同它相同。
   这种方法虽然笨拙,但是还是有用的。
   Viewer的显示总是依靠某一个透视图的,因此就有了我们的透视图基类:
 1 package  com.glnpu.dmp.client.platform.core.internal.security.absperspective;
 2
 3 import  java.util.ArrayList;
 4 import  java.util.List;
 5
 6 import  org.apache.log4j.Logger;
 7 import  org.eclipse.ui.IFolderLayout;
 8 import  org.eclipse.ui.IPageLayout;
 9 import  org.eclipse.ui.IPerspectiveFactory;
10
11 import  com.glnpu.dmp.client.platform.core.internal.security.SecurityManager;
12
13 /** */ /**
14 * 实现自<code>IPerspectiveFactory</code>,提供标准布局,及左侧为Viewers,底部为Viewers
15 * @author lign
16 *
17 */

18 public   abstract   class  AbstractSecurityPerspective  implements  IPerspectiveFactory  {
19    
20    private Logger log = Logger.getLogger(this.getClass());
21    
22    protected String [] leftViewerIds = null;
23    protected String [] bottomViewerIds = null;
24    protected String perspectiveName = null;
25    
26    /**//* (non-Javadoc)
27     * @see org.eclipse.ui.IPerspectiveFactory#createInitialLayout(org.eclipse.ui.IPageLayout)
28     */

29    public void createInitialLayout(IPageLayout layout) {
30        List<String> leftViewerList = getLeftViewers(leftViewerIds);
31        log.debug("当前用户可用的leftViewer列表长度为 : " + leftViewerList.size());
32        if(leftViewerList.size()>0{
33            IFolderLayout folderLayoutLeft = layout.createFolder(this.perspectiveName+"Left", IPageLayout.LEFT, 0.25f, layout.getEditorArea()); 
34            for(String str : leftViewerList) {
35                folderLayoutLeft.addView(str);
36                layout.getViewLayout(str).setCloseable(false);
37            }

38        }

39
40        List<String> bottomViewerList = getBottomViewers(bottomViewerIds);
41        log.debug("当前用户可用的bottomViewer列表长度为 : " + bottomViewerList.size());
42        if(bottomViewerList.size()>0{
43            IFolderLayout&n

你可能感兴趣的:(eclipse,log4j,UI,Security,osgi)