`
samjavaeye
  • 浏览: 193282 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

自定义WebLogic Role Mapper Provider样例

    博客分类:
  • Java
阅读更多

【概述】

开发环境:WebLogic Server 8.1

本文仅记录了主要的操作流程,涉及到的一些概念性的东西,就不详细叙述。需要了解的话,可以参考其在线文档中心

 

【Role Mapper Provider简介】

在请求者与Weblogic 资源之间建立动态关联(比如将用户所属的用户组与某个role进行映射)。当一个Weblogic资源被访问时,WebLogic Security Framework通过以下两种方式来确定哪个security roles将应用到某个特定的Subject上:

l  J2EEWebLogic部署描述符文件中获得security roles

l  使用业务逻辑和当前操作参数来决定security roles

在一个security realm中,至少需要有一个Role Mapping Provider

 

【开发流程】

    首先,需要一个weblogic.security.service.SecurityRole的实现类:

package examples.security.providers.rolemapper;

import weblogic.security.service.SecurityRole;

public class SampleSecurityRoleImpl implements SecurityRole {
	private String _roleName;
	private String _description;
	private int _hashCode;

	public SampleSecurityRoleImpl(String roleName, String description) {
		_roleName = roleName;
		_description = description;
		_hashCode = roleName.hashCode() + 17;
	}

	public boolean equals(Object secRole) {
		if (secRole == null) {
			return false;
		}
		if (this == secRole) {
			return true;
		}
		if (!(secRole instanceof SampleSecurityRoleImpl)) {
			return false;
		}
		SampleSecurityRoleImpl anotherSecRole = (SampleSecurityRoleImpl) secRole;
		if (!_roleName.equals(anotherSecRole.getName())) {
			return false;
		}
		return true;
	}

	public String toString() {
		return _roleName;
	}

	public int hashCode() {
		return _hashCode;
	}

	public String getName() {
		return _roleName;
	}

	public String getDescription() {
		return _description;
	}
}

 

 实现代码很简单,一个role基本上就包含名称和描述。

 

然后,为了简化起见,这里用一个类SampleRoleMapperDatabase来代替数据库里面存储的相关映射信息。实际应用中,可以改造这个类,让它读写数据库或其他存储设备。

 

package examples.security.providers.rolemapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import weblogic.management.security.ProviderMBean;
import weblogic.security.spi.Resource;

public class SampleRoleMapperDatabase {
	private Map roleMap = new Hashtable();
	private Map principalMap = new Hashtable();

	public SampleRoleMapperDatabase(ProviderMBean mbean) {
	}

	public void setRole(Resource resource, String roleName,
			String[] principalNames) {
		Vector principalVector = (Vector) principalMap.get(roleName);
		if (principalVector == null) {
			principalVector = new Vector();
			principalMap.put(roleName, principalVector);
		}
		principalVector.addAll(Arrays.asList(principalNames));
		Vector roleVector = (Vector) roleMap.get(resource);
		if (roleVector == null) {
			roleVector = new Vector();
			roleMap.put(resource, roleVector);
		}
		roleVector.add(roleName);
	}

	public void removeRole(Resource resource, String roleName) {
		if (resource != null)
			principalMap.remove(roleName);
		if (roleName != null)
			roleMap.remove(resource);
	}

	public Enumeration getRoles(Resource resource) {
		if (resource == null)
			return null;
		if (roleMap.get(resource) != null)
			return Collections.enumeration((Vector) roleMap.get(resource));
		else
			return null;
	}

	public Enumeration getPrincipalsForRole(Resource resource, String role) {
		List pricipalList = new ArrayList();
		if (role != null)
			pricipalList.addAll((Vector) roleMap.get(role));
		if (resource != null) {
			Vector roleVector = (Vector) roleMap.get(resource);
			if (roleVector != null) {
				Iterator iter = roleVector.iterator();
				while (iter.hasNext()) {
					Vector principalVector = (Vector) principalMap
							.get((String) iter.next());
					pricipalList.addAll(principalVector);
				}
			}
		}
		return Collections.enumeration(pricipalList);
	}

}

 

接下来,就可以开始实现weblogic.security.spi.RoleMapper接口了。该接口只有一个方法:

public Map getRoles(Subject subject, Resource resource,
			ContextHandler handler)

 

给定一个登录用户的Subject,和其请求的资源,返回在该资源上分配给该用户的所有role,返回的对象是一个Map,key是对应role的名称,value则是weblogic.security.service.SecurityRole对象(也就是上文中我们自己写的那个实现类)。

 

另外,我们还可以同时实现weblogic.security.spi.DeployableRoleProvider接口,这样如果在web.xml中配置了某些角色,那么在服务器启动时,WebLogic Server会将这些信息注入到我们的这个实现类里面去。该接口有两个方法:

public void deployRole(Resource resource, String roleName,
			String[] principalNames) throws RoleCreationException;

public void undeployRole(Resource resource, String roleName)
			throws RoleRemovalException;

分别对应添加和删除映射关系,我们根据传入的参数,修改数据库或其他地方的持久化映射数据。

 

完整实现类代码如下:

package examples.security.providers.rolemapper;

import java.security.Principal;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.security.auth.Subject;

import weblogic.management.security.ProviderMBean;
import weblogic.security.WLSPrincipals;
import weblogic.security.service.ContextHandler;
import weblogic.security.spi.DeployableRoleProvider;
import weblogic.security.spi.Resource;
import weblogic.security.spi.RoleCreationException;
import weblogic.security.spi.RoleMapper;
import weblogic.security.spi.RoleRemovalException;
import weblogic.security.spi.SecurityServices;

public final class SampleRoleMapperProviderImpl implements
		DeployableRoleProvider, RoleMapper {
	private String description;
	private SampleRoleMapperDatabase database;
	private static final Map NO_ROLES = Collections
			.unmodifiableMap(new HashMap(1));

	public void initialize(ProviderMBean mbean, SecurityServices services) {
		SampleRoleMapperMBean myMBean = (SampleRoleMapperMBean) mbean;
		description = myMBean.getDescription() + "\n" + myMBean.getVersion();
		database = new SampleRoleMapperDatabase(mbean);
	}

	public String getDescription() {
		return description;
	}

	public void shutdown() {
		System.out.println("SampleRoleMapperProviderImpl.shutdown");
	}

	public RoleMapper getRoleMapper() {
		return this;
	}

	public Map getRoles(Subject subject, Resource resource,
			ContextHandler handler) {
		System.out.println("SampleRoleMapperProviderImpl.getRoles");
		System.out.println("\tsubject\t= " + subject);
		System.out.println("\tresource\t= " + resource);
		Map roles = new HashMap();
		Set principals = subject.getPrincipals();
		for (Resource res = resource; res != null; res = res
				.getParentResource()) {
			getRoles(res, principals, roles);
		}
		getRoles(null, principals, roles);
		if (roles.isEmpty()) {
			return NO_ROLES;
		}
		return roles;
	}

	public void deployRole(Resource resource, String roleName,
			String[] principalNames) throws RoleCreationException {
		System.out.println("SampleRoleMapperProviderImpl.deployRole");
		System.out.println("\tresource\t\t= " + resource);
		System.out.println("\troleName\t\t= " + roleName);
		for (int i = 0; principalNames != null && i < principalNames.length; i++) {
			System.out.println("\tprincipalNames[" + i + "]\t= "
					+ principalNames[i]);
		}
		database.setRole(resource, roleName, principalNames);
	}

	public void undeployRole(Resource resource, String roleName)
			throws RoleRemovalException {
		System.out.println("SampleRoleMapperProviderImpl.undeployRole");
		System.out.println("\tresource\t= " + resource);
		System.out.println("\troleName\t= " + roleName);
		database.removeRole(resource, roleName);
	}

	private void getRoles(Resource resource, Set principals, Map roles) {
		for (Enumeration e = database.getRoles(resource); e != null
				&& e.hasMoreElements();) {
			String role = (String) e.nextElement();
			if (roleMatches(resource, role, principals)) {
				roles.put(role, new SampleSecurityRoleImpl(role,
						"no description"));
			}
		}
	}

	private boolean roleMatches(Resource resource, String role,
			Set principalsHave) {
		for (Enumeration e = database.getPrincipalsForRole(resource, role); e
				.hasMoreElements();) {
			String principalWant = (String) e.nextElement();
			if (principalMatches(principalWant, principalsHave)) {
				return true;
			}
		}
		return false;
	}

	private boolean principalMatches(String principalWant, Set principalsHave) {
		if (WLSPrincipals.getEveryoneGroupname().equals(principalWant)
				|| (WLSPrincipals.getUsersGroupname().equals(principalWant) && !principalsHave
						.isEmpty())
				|| (WLSPrincipals.getAnonymousUsername().equals(principalWant) && principalsHave
						.isEmpty())
				|| principalsContain(principalsHave, principalWant)) {
			return true;
		}
		return false;
	}

	private boolean principalsContain(Set principalsHave,
			String principalNameWant) {
		for (Iterator i = principalsHave.iterator(); i.hasNext();) {
			Principal principal = (Principal) i.next();
			String principalNameHave = principal.getName();
			if (principalNameWant.equals(principalNameHave)) {
				return true;
			}
		}
		return false;
	}

}

 

initialize()方法在WebLogic Server启动时会被自动调用,在这里我们可以根据需要进行一些初始化操作。

 

代码写完了,接下来,就要使用WebLogic提供的命令行工具来生成一个mbi文件,这个文件在后面往WebLogic Server里面部署我们的Provider时需要用到。

 

为了告诉WebLogic如何生成我们的这个mbi文件,我们需要编写一个xml文档。

SampleRoleMapper.xml内容如下:

<?xml version="1.0" ?>
<!DOCTYPE MBeanType SYSTEM "commo.dtd">
<MBeanType
	Name="SampleRoleMapper"
	DisplayName="自定义RoleMapper"
	Package="examples.security.providers.rolemapper"
	Extends="weblogic.management.security.authorization.DeployableRoleMapper"
	PersistPolicy="OnUpdate"
	Description="This MBean represents configuration attributes for the Sample RoleMapper Provider.&lt;p&gt;"
>
	<MBeanAttribute
		Name="ProviderClassName"
		Type="java.lang.String"
		Writeable="false"
		Default="&quot;examples.security.providers.rolemapper.SampleRoleMapperProviderImpl&quot;"
		Description="The name of the Java class that my first role mapper provider." />
	<MBeanAttribute
		Name="Description"
		Type="java.lang.String"
		Writeable="false"
		Default="&quot;Provider that performs role mapper&quot;"
		Description="None." />
	<MBeanAttribute
		Name="Version"
		Type="java.lang.String"
		Writeable="false"
		Default="&quot;1.0&quot;"
		Description="The version of the Sample Role Mapper Provider." />
</MBeanType>

 MBeanType标签的Name属性,跟后面自动生成的java文件名有关,这里不可以命名成跟上文中我们自己写的Provider实现类同名;DisplayName随便写;Package跟上文相关类的包名保持一致即可;Extends属性比较关键,根据WebLogic Server的API来,只不过API里面的类名结尾有个MBean,这边去掉这个后缀即可。

 

三个MBeanAttribute标签的Name是固定的,直接拷贝。当然Name为ProviderClassName的这个MBeanAttribute要修改一下Default属性,改为我们自己的那个Provider实现类的全类名,注意要用转义的双引号(&quot;)括起来。

 

比较关键的修改就这些,其他属性看着改就好了。特别需要强调的是,这个xml文件比较关键,稍微错一点,后面代码生成就会出错。

 

编写完这个xml文件(MBeanType定义文件)后,还需要拷贝一个commo.dtd文件到相同目录,这个文件在C:\bea\weblogic81\server\lib目录可以找到。

运行cmd命令,打开命令行窗口。先运行:C:\bea\weblogic81\server\bin\setWLSEnv.cmd进行环境变量设置。

然后运行以下命令,生成mbi文件:

java -DMDF=C:\bea\user_projects\applications\Test3\Test3Web\WEB-INF\src\examples\security\providers\rolemapper\SampleRoleMapper.xml -Dfiles=D:\temp\0209 -DcreateStubs=true -cp .;%CLASS_PATH%;C:\bea\weblogic81\server\lib\weblogic.jar;C:\bea\weblogic81\server\lib\mbeantypes\wlManagement.jar;C:\bea\jdk142_08\lib\tools.jar weblogic.management.commo.WebLogicMBeanMaker

其中-DMDF参数指定SampleRoleMapper.xml文件位置;-Dfiles参数指定要生成的文件存放位置,这里我指定了一个临时目录;注意需要将weblogic.jar、wlManagement.jar和对应jdk的tools.jar文件在classpath中明确指定。

 

如果一切顺利的话,WebLogicMBeanMaker工具将生成两个java文件和一个mbi文件。如果上述SampleRoleMapper.xml文件中稍有错误(比如少了一个&quot;),过程中就会提示编译错误,其实是该工具根据我们编写的xml自动生成的java文件出现编译错误。此时应该仔细检查xml文件,甚至需要重新编写一次该文件(有一次我就遇到怎么查也没错,把文件删了重写一遍就好了)。

 

文件生成完了之后,接下来就是打包发布了。WebLogic也有提供相应工具,不过我还是自己用ant做比较方便。把两个java文件拷贝到eclipse里面,跟自己写的那三个文件放一起。另外再找个目录放生成的mbi文件。

 

然后编写一个ant脚本来打包发布jar文件,方便后续修改代码进行调试。

<?xml version="1.0" encoding="UTF-8"?>
<project name="Test3" default="自定义授权Provider">
	<property name="classBase" value="${basedir}/Test3Web/WEB-INF/classes"/>
	<property name="mbiBase" value="${classBase}/examples/security/providers/mbi"/>
	<property name="mbeantypesBase" value="C:/bea/weblogic81/server/lib/mbeantypes"/>
    <description>
		WebLogic Security Provider 自动打包发布
    </description>

        <target name="自定义RoleMapperProvider">
    	<jar destfile="${mbeantypesBase}/myRoleMapperProvider.jar">
	    	<fileset 
	    		dir="${classBase}" 
	    		includes="examples/security/providers/rolemapper/,examples/util/"/>
			<fileset file="${mbiBase}/SampleRoleMapper.mbi"/>
    	</jar>
    </target>

</project>

 

这里我们把用到的class文件和mbi文件打包后,直接拷贝到C:/bea/weblogic81/server/lib/mbeantypes目录中去,这样就完成了部署操作。

 

接下来,启动WebLogic服务器,打开浏览器,进入http://localhost:7001/console控制台页面,登录后就能看到我们自己的这个provider了。

 

配置完了以后,重启WebLogic服务器,即可生效。

 

 

分享到:
评论

相关推荐

    java实现自定义Weblogic监控

    java实现自定义Weblogic监控java实现自定义Weblogic监控java实现自定义Weblogic监控

    定制自己的WebLogic LDAP Authentication Provider

    WebLogic服务器使用Security Providers来处理用户认证,这些提供者可以是内置的,如默认的`DefaultAuthenticator`,也可以是自定义的,如我们这里的`LDAP Authentication Provider`。认证提供者的主要职责是验证用户...

    java监控weblogic

    Java 实现自定义 Weblogic 监控 Java 是一种广泛使用的编程语言,Weblogic 是一款流行的应用服务器,而 Java 实现自定义 Weblogic 监控则是指使用 Java 语言来实现对 Weblogic 服务器的监控。本文将详细介绍如何...

    weblogic.xml配置详解

    `weblogic.xml` 文件是 WebLogic Server 应用服务器中专门用于自定义和配置部署在该服务器上的 Web 应用程序的一个重要配置文件。它允许开发人员和系统管理员针对 WebLogic Server 的特定特性进行定制设置,以满足...

    Weblogic安装、配置、优化、集群教程大全

    教程名称: Weblogic安装、配置、优化、集群教程大全【】BEA WebLogic管理员手册【】java实现自定义Weblogic监控【】Oracle weblogic Server 11 g R1【】RHEL5.4 ORACLE11G WEBLOGIC10.3集群安装部署手册【】...

    显示自定义错误页面,用户自定义

    在IT行业中,尤其是在Web开发领域,自定义错误页面是一个重要的用户体验设计环节。它允许开发者根据自己的需求和品牌风格,为用户呈现更为友好、更具指导性的错误信息,而不是默认的浏览器或服务器错误页面。本篇...

    weblogic10.3.3之后版本升级至weblogic10.3.6文档.docx

    ### WebLogic 10.3.3 至 10.3.6 升级指南 #### 一、概述 本指南旨在详细介绍如何从WebLogic Server 10.3.3及其后续版本升级到10.3.6版本的具体步骤。升级过程中需要考虑的因素以及必要的准备措施也将被涵盖。 ###...

    weblogic监控 weblogic调优 weblogic版本区别 weblogic启动关闭脚本

    WebLogic Server是一款由Oracle公司开发的企业级Java应用服务器,它为构建、部署和管理企业级Java应用程序提供了全面的平台。本文将深入探讨WebLogic的监控、调优、不同版本之间的区别以及启动和关闭脚本的使用。 ...

    Weblogic 套件和Weblogic 标准版 Weblogic 企业版 功能对比

    在IT领域,特别是针对企业级应用服务器的选择与配置,Oracle WebLogic Server无疑占据了重要的位置。WebLogic Server作为一款高性能、可扩展的企业级Java应用服务器,提供了丰富的功能与服务,适用于构建、部署和...

    weblogic安装及配置

    WebLogic 安装及配置 一、WebLogic Server 版本 WebLogic Server 是一个基于 Java 的中间件服务器,提供了一个强大而灵活的平台来开发、部署和管理企业级应用程序。WebLogic Server 有多种版本,包括: * ...

    weblogic.jar

    开发者在编写自定义插件、部署工具或集成解决方案时会用到这个jar包。 `api.jar`可能指的是WebLogic Server的一部分API或者特定组件的API,具体功能取决于上下文。它通常包含了特定模块的接口和类,供开发者在实现...

    weblogic部署项目详细步骤使用手册

    同时,也可以根据自己的需要进行多种自定义的配置。 扩展知识点 * Weblogic 的 advantages:Weblogic 是一种功能强大且灵活的 Java EE 服务器,可以提供高性能、高可用性和高安全性的 Web 应用程序部署环境。 * ...

    weblogic详细安装部署手册

    ### WebLogic详细安装部署流程 #### 一、安装前准备 **1.1 JDK环境配置** - **确保JDK已安装:** 在安装WebLogic之前,必须先安装Java Development Kit (JDK)。WebLogic服务器依赖于JDK来运行。请确保安装的是与...

    eclipse的weblogic插件

    为了在Eclipse中方便地开发、调试和管理运行在WebLogic上的应用,Eclipse提供了WebLogic插件。 WebLogic插件的安装方法如描述所述,首先需要将下载的WebLogic插件压缩包解压。这个压缩包通常包含了若干个.jar文件,...

    weblogic11g安装与卸载

    - **自定义安装(Custom)**:允许用户选择安装哪些组件。 - **升级安装(Upgrade)**:用于升级现有环境。 **步骤五:** 选择 Java 开发工具包(JDK)。确保系统中已经安装了兼容的 JDK,并且在安装过程中选择正确...

    LINUX FOR weblogic8.1.5安装手册

    - **WebLogic安装路径**:确认或自定义WebLogic的安装目录。 - **完成安装**:安装完成后,点击“Done”完成安装流程。 #### 四、WebLogic配置步骤 1. **切换至配置目录**:使用`#cd /opt/weblogic/bea/weblogic...

    weblogic10.3性能优化参数配置

    Weblogic 10.3 性能优化参数配置 Weblogic 服务器是 Oracle 公司推出的一个基于 Java 的中间件服务器,广泛应用于企业级应用系统中。为了确保 Weblogic 服务器的高性能和稳定运行,需要对其进行合理的配置和优化。...

    weblogic weblogic weblogic

    WebLogic是Oracle公司的一款企业级Java应用服务器,它基于Java EE(Enterprise Edition)平台,用于构建、部署和管理分布式应用程序。WebLogic Server是许多大型企业和组织的核心组件,它提供了多种功能和服务,包括...

    weblogic傻瓜式安装教程

    ### WebLogic傻瓜式安装教程详解 #### 一、前言 本文档旨在提供一个简单易懂的WebLogic安装教程,适用于初次接触WebLogic或希望快速完成安装的用户。通过本教程,您将学会如何在Linux环境下进行WebLogic的安装与...

Global site tag (gtag.js) - Google Analytics