终端身份实施文档

上传brook.tar

tar zvf brook.tar 解压到/usr_projects/domains/mydomain/

有以下目录

brook-lib

brook-web-lib

bin

doc

conf

 

拷贝brook-web-lib中的jar到WEB-INF/lib下

可选:将setBrookEnv.sh 拷贝到 WLS_HOME/common/bin目录下,并修改其中BROOK_LIB环境变量

 

修改startWebLogic.sh,增加运行 setBrookEnv.sh(用于设置将brook2自身的jar包到app server的classpath中)

. /opt/bea/user_projects/domains/mydomain/brook/bin/setBrookEnv.sh

 

修改brook-lib/log4j.properties的日志级别和log4j.debug=false

可选(目前打包的时候已经拷贝):拷贝conf/brook-advice.properties到BROOK_LIB下

 

拷贝conf/brook.properties到WEB-INF下,修改其中showSession和excludePattern

 

修改web.xml,增加IdentityContextFilter

注意:被修改的weblogic和app的原文件需要备份(startWebLogic.sh 和web.xml),以便万一安装失败能恢复原来的文件

 

然后在console中

增加一个DataSource:

DriverName:com.mchz.brook.jdbc.proxy.DriverLoggingProxy

URL:jdbc:jdbcdslog:oracle:thin:@172.16.4.37:1521:xe;targetDriver=oracle.jdbc.OracleDriver

 

dump session信息,查看后修改sessionProperties

全部弄好后把log4j的日志级别调整为warning

 

 

 

<!--[if !supportLists]-->1.         <!--[endif]-->对一个数据源的测试

<!--[if !supportLists]-->a)         <!--[endif]-->测试环境搭建

<!--[if !supportLists]-->                        i.              <!--[endif]-->Weblogic 8

<!--[if !supportLists]-->                      ii.              <!--[endif]-->部署测试程序 brook-selenium2,直接点击界面上就可以测试

<!--[if !supportLists]-->2.         <!--[endif]-->对多个数据源的测试(开发中已经测试过2个数据源的情况)

<!--[if !supportLists]-->a)         <!--[endif]-->测试环境搭建

<!--[if !supportLists]-->                        i.              <!--[endif]-->Weblogic 8,部署测试webapp和终端身份组件

<!--[if !supportLists]-->                      ii.              <!--[endif]-->Oracle database 并且要在其中建一张test表,里面就一个id字段number类型

<!--[if !supportLists]-->                    iii.              <!--[endif]-->安装setclientinfo存储过程

<!--[if !supportLists]-->                     iv.              <!--[endif]--> 

 

终端身份原理和文档

原理简述:自己实现了自定义的驱动程序,在目标应用上使用这个自定义的驱动建立DataSource,并配置目标应用使用新定义的DataSource

目标应用请求JDBC连接的时候,返回的是自定义的JDBC Connection,当发出SQL语句的时候,自定义驱动会先发出一条plsql存储过程的调用,把web端传过来的终端身份信息,传递到数据库中,然后在发出目标应用的sql语句,这样数据库就知道这条sql语句是从哪个终端发出的了。

 

Web前端就是一个Filter,拦截所有需要的URL请求,然后把终端信息,例如IP地址等获取出来,放到ThreadLocalIdentityContext中,这样自定义驱动就能通过ThreadLocal获取到终端信息了。也可以通过配置,把需要的Session信息获取出来,不过这个需要一些尝试。在系统运行的时候,把session信息dump出来,然后挑选正确的key,配置到终端身份的配置信息中。如果无法获取key,是无法获取相应的值的。

 

对反向代理的支持。很多应用都采用了这样的架构:前段通过F5或者Radware这样的硬件,或者Haproxy这样的软件代理服务器,把http请求转发给后端的应用服务器集群,例如多个weblogic实例(各个weblogic并不相关,不是weblogic自身的集群)。在这样的情况下,如果不做其他的改动,Web端取到的终端IP是代理服务器的IP地址,而不是终端浏览器的IP地址。现在很多代理服务器(比如F5)都支持在转发HTTP请求的时候,在HTTP header中增加一个X-Forward-For头,把真正的HTTP请求的IP转发过来。通过在Web Filter中对这个字段进行检测,就能取到真正的HTTP请求的终端地址。但是,需要在F5或者其他代理服务器中打开对X-Forward-For的支持。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

对集群的支持。由于中间件部署方式有很多变化,需要在实施的时候也做相应的改变。

单个实例的情况是最简单的,只要部署好之后重启就可以了。

对于集群的情况,则需要滚动安装。也即:先停集群中一个中间件实例,安装部署,然后再加入回集群,依次进行直到所有的中间件实例上都安装完毕。

 

Oracle端:

Oracle中的v$session视图中,有所有当前连接到数据库的session信息。其中有两个字段client_identifier是用来表明终端信息的。在OracleJDBC驱动中(OracleConnection),提供了传递终端信息的API

SetEndToEndMetrics,但是此API只能针对Oracle 10及其以上版本才能生效。对于Oracle 9数据库,技术服务部提供了setclientinfo这个存储过程能够代替此API

根据技术服务部门提供的信息,要让CAPAA能审计到终端的信息,无论是9i还是10g都必须调用setclientinfo这个存储过程,否则CAPAA无法审计到终端信息。

 

SVN http://svn.mchz.com.cn/svn/brook2

下面有三个工程

<!--[if !supportLists]-->1.         <!--[endif]-->brook2-core:实现了自定义的jdbc驱动程序。目前此工程的编译并导出jar文件,是用了eclipseexport功能,今后需要写一个ant脚本来脱离ide的耦合。编译需要用jdk1.4的标准,因为客户大量使用的weblogic 816版本,是用jdk1.4的,否则会导致客户生产端报class文件版本不正确的错误而无法启动。代码中包含部分jmx的内容,目前尚未应用到实际生产环境中,如果编译时产生相关的编译错误,可以暂时先删除相应的代码。相应目录说明:

<!--[if !supportLists]-->a)         <!--[endif]-->src目录:源代码

<!--[if !supportLists]-->b)        <!--[endif]-->lib目录:依赖包

<!--[if !supportLists]-->c)         <!--[endif]-->script目录:

<!--[if !supportLists]-->                        i.              <!--[endif]-->setBrookEnv.sh Unix/Linux下,需要加入到weblogic启动脚本(startWeblogic.sh)中运行的配置脚本

<!--[if !supportLists]-->                      ii.              <!--[endif]-->setBrookEvn.bat Windows平台下,需要加入到weblogic启动脚本(startWeblogic.sh)中运行的配置脚本

<!--[if !supportLists]-->                    iii.              <!--[endif]-->setclientinfo.sql 需要在生产库端运行的plsql初始化脚本,会创建一个终端身份需要调用的plsql存储过程

<!--[if !supportLists]-->d)        <!--[endif]-->doc目录:文档目录

<!--[if !supportLists]-->                        i.              <!--[endif]-->deploy.txt 实施文档,包含简要的实施步骤

<!--[if !supportLists]-->                      ii.              <!--[endif]-->history.txt 实施历史文档

<!--[if !supportLists]-->                    iii.              <!--[endif]-->todo.txt 需要改进的todolist

<!--[if !supportLists]-->2.         <!--[endif]-->brook2-web:实现了web端获取终端信息的filter,需要加载到第三方应用的web.xml文件中。目前此工程的编译并导出jar文件,是用了eclipseexport功能,今后需要写一个ant脚本来脱离ide的耦合。相应目录说明:

<!--[if !supportLists]-->a)         <!--[endif]-->src目录:源代码

<!--[if !supportLists]-->b)        <!--[endif]-->lib目录:依赖包

<!--[if !supportLists]-->3.         <!--[endif]-->brook2-selenium:测试程序,部署好中间件和数据库之后,能够测试是否生效。项目在checkout eclipse之后,需要配置一些src目录到main/java,否则eclipse会报java源代码路径和package不匹配。build的时候,需要将brook2-corebrook2-web两个工程生成的jar包,放到此工程的lib目录下,然后运行ant脚本。相应目录说明

<!--[if !supportLists]-->a)         <!--[endif]-->src/main/java目录:源代码

<!--[if !supportLists]-->b)        <!--[endif]-->src/main/resource目录:资源目录

<!--[if !supportLists]-->                        i.              <!--[endif]-->brook-advice.properties 终端身份的配置文件

<!--[if !supportLists]-->                      ii.              <!--[endif]-->jdbc.properties jdbc连接配置

<!--[if !supportLists]-->                    iii.              <!--[endif]-->log4j.properties 日志配置

<!--[if !supportLists]-->c)         <!--[endif]-->src/main/webapp目录:brook2-selenium包含的webapp的文件和资源

 

brook2-selenium中需要应用brook2-corebrook2-core中生成的jar

brook2-web需要引用brook2-corejar包,或者在eclipse中指定项目的依赖关系

需要用JDK 1.4的编译器编译,或者在build.xml中指定。

 

代码解析:

 

 

 

实施详细文档:

上传brook.tar文件

weblogicdomain目录下解压此压缩文件,生成一个brook目录。

目录结构:

bin

设置brookclasspath的启动脚本,需要在启动weblogic domainstartWebLogic.sh中执行

setBrookEnv.sh (linux环境下)

setBrookEnv.bat (windows环境下)

 

brook-lib

brook需要的jar包,在setBrookEnv脚本中加入到weblogicclasspath

 

brook-web-lib

需要拷贝到webappWEB-INF/lib目录下的jar

 

conf

配置文件

brook.properties 此文件需要拷贝到WEB-INF目录下

web.xml里面有设置filter的范例

 

doc

deploy.txt 部署文档

 

修改setBrookEnv.sh,把其中的路径修改成当前正确的路径,主要是修改BROOK_LIB环境变量,把他指定到brook-lib的目录

 

修改startWebLogic.sh,在启动过程中执行setBrookEnv.sh,增加这一行

. /opt/bea/alfredxu/user_projects/domains/alfredxu/brook/bin/setBrookEnv.sh

 

brook/brook-web-lib下的jar包拷贝到webapp下的WEB-INF/lib目录下

conf/brook.properties拷贝到webapp下的WEB-INF目录下

修改webappweb.xml文件,增加如下的filter配置

        <filter>

                <filter-name>brook</filter-name>

                <filter-class>com.mchz.brook.web.filter.IdentityFilter</filter-class>

        </filter>

 

        <filter-mapping>

                <filter-name>brook</filter-name>

                <url-pattern>*.do</url-pattern>

        </filter-mapping>

其中filter-mapping中的url-pattern需要根据应用的情况来具体配置,有些应用的请求,不一定是.do结尾的

重启weblogic,让brookjar生效。

配置brook用的连接池。在weblogicconsole中,根据webapp使用的连接池,配置一个brook用的新连接池。

 

 

 

<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="_x0000_i1027" type="#_x0000_t75" style='width:414.75pt; height:259.5pt'> <v:imagedata src="file:///C:\Users\hua\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png" o:title="" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

 

<!--[if gte vml 1]><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:414.75pt;height:259.5pt'> <v:imagedata src="file:///C:\Users\hua\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png" o:title="" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

然后把webapp使用的JNDI引用的连接池改为brook新配置的连接池

<!--[if gte vml 1]><v:shape id="_x0000_i1026" type="#_x0000_t75" style='width:414.75pt;height:259.5pt'> <v:imagedata src="file:///C:\Users\hua\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png" o:title="" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

重启weblogic,让webapp使用新的连接池。此时日志里面应该会显示新连接池初始化的日志信息。类似如下显示。

11:29:52,449  INFO ConnectionLogger:45 - connect to URL jdbc:jdbcdslog:oracle:thin:@172.16.4.37:1521:xe;targetDriver=oracle.jdbc.OracleDriver with properties: {user=asset, password=asset, v$session.program=brook}

11:29:52,449 DEBUG DriverLoggingProxy:54 - s = jdbc

11:29:52,449 DEBUG DriverLoggingProxy:54 - s = oracle

11:29:52,449 DEBUG DriverLoggingProxy:54 - s = thin

11:29:52,450 DEBUG DriverLoggingProxy:54 - s = @172.16.4.37

11:29:52,450 DEBUG DriverLoggingProxy:54 - s = 1521

11:29:52,450 DEBUG DriverLoggingProxy:54 - s = xe

11:29:52,450 DEBUG DriverLoggingProxy:54 - s = targetDriver

11:29:52,450  INFO DriverLoggingProxy:67 - connecting to database

11:29:52,451  INFO ConnectionLogger:45 - connect to URL jdbc:oracle:thin:@172.16.4.37:1521:xe with properties: {user=asset, v$session.terminal=spring, password=asset, v$session.program=veronica}

 

 

如何卸载

console中将webapp使用的JNDI引用的连接池改为原来的连接池。

web.xml中加入的filter去掉或者注释掉

startWebLogic.sh中执行的setBrookEnv.sh那行去掉或者注释掉

重启weblogic

 

如何验证安装成功:

连接生产库,查询v$session表格中的client_identifier字段,看有没有相应的终端信息

查看CAPAA的访问审计,查看终端信息这个字段有没有终端IP

查看weblogic日志输出,在用户请求发出某条sql语句的时候,会有类似输出

16:44:29,719  INFO GenericLoggingProxy:54 - ==== need to set brook createStatement====

16:44:29,719 DEBUG ConnectionAdviceImpl:39 - in connection advice: connection advice ,target class:class oracle.jdbc.driver.T4CConnection

16:44:29,719 DEBUG AttachStrategy:42 - identity context is: com.mchz.brook.web.IdentityContext@11c8258[sessionId=GM9LPLbFQ2jtwFpJmRQh2Q3yP4hfnmGhJ3ZCMsRDV7WFnkCrQnhL!-1799731374!1334565869408,username=<null>,ip=172.16.4.100,host=172.16.4.100,etc={"etc":com.mchz.brook.web.IdentityContext@11c8258[sessionId=GM9LPLbFQ2jtwFpJmRQh2Q3yP4hfnmGhJ3ZCMsRDV7WFnkCrQnhL!-1799731374!1334565869408,username=<null>,ip=172.16.4.100,host=172.16.4.100,etc=<null>,action=<null>,module=<null>,sessionProperties={},ignored=false,accessTime=Mon Apr 16 16:44:29 CST 2012]},action=1334565869605,module=<null>,sessionProperties={},ignored=false,accessTime=Mon Apr 16 16:44:29 CST 2012]

16:44:29,720 DEBUG NormalAttachStrategy:25 - using normal attach strategy, need to attach: true

16:44:29,720 DEBUG IdentityContextStrategyStoreProcImpl:25 - call SetClientinfo(?,?,?,?) parameter: ip:172.16.4.100,{}, null, null, 1334565869605

16:44:29,733 DEBUG LogUtils:31 - createLogEntry()

16:44:29,733  INFO StatementLogger:53 - java.sql.Statement.executeQuery select * from v$session where action = '1334565869605' 12 ms.

 

 

注意:由于Oracle的关系,clientclientinfo这个存储过程中的

create or replace

procedure SetClientinfo(v_clientidentifier varchar2,v_clientinfo varchar2,v_module varchar2,v_action varchar2) is

  l_sid Number;

  l_ip  varchar2(64);

  l_session_info  varchar2(4000);

begin

  --dbms_session.set_identifier(v_clientidentifier);

  dbms_application_info.set_client_info(v_clientinfo);

  dbms_application_info.set_module(v_module,v_action);

  select substr(v_clientidentifier,4,instr(substr(v_clientidentifier,3),',')-2),

         substr(substr(v_clientidentifier,instr(substr(v_clientidentifier,3),',')+3),1,1000)

    into l_ip,l_session_info from dual;

  Tlgctxpkg.SetContext('end_ip',l_ip);

  Tlgctxpkg.SetContext('end_session_info',l_session_info);

exception

  when others then

    null;

end SetClientinfo;

 

  --dbms_session.set_identifier(v_clientidentifier);

这行代码,当需要在v$session中查看client_identifier的时候,需要注释掉,但是这个时候在client_identifier就无法被注入到访问审计中。终端信息在访问审计和v$session两者之间只能生效一个。

 

配置说明:

brook.properties

# session key properties format: sessionkey:beanpath:connkey,

excludePattern=.*.js|.*.css

sessionProperties=userinfo:username:username

showSessionEnabled=true
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

excludePattern 指定哪些URL请求不需要注入终端身份,一般来说静态文件,js, css等不需要注入,可以优化性能

 

sessionProperties 指定那个session key对应的object的属性要被注入到终端身份中

 

showSessionEnabled 是否需要在终端输出中导出session信息,正式部署之后,推荐设置为false

 

brook-lib/brook-advice.properties

#brook global config

brook.attachStrategy=normal

 

#brook aspect config

 

#brook driver aspect config

brook.aspect.driver.enabled=true

brook.aspect.driver.v$session.program=veronica

brook.aspect.driver.v$session.terminal=spring

 

#brook connection aspect config

brook.aspect.connection.oracle.version=9

brook.aspect.connection.enabled=true

 

#sqllog aspect config

brook.aspect.sqllog.enabled=false

brook.aspect.sqllog.id=1

 

brook.rule.log.1=1;127.0..*;.*;.*;.*;log

 

brook.attachStrategy=normal 设置终端身份信息的策略,一般推荐为normal

 

brook.aspect.driver.enabled=true

是否设置driver级别的信息,如下:

brook.aspect.driver.v$session.program=veronica

brook.aspect.driver.v$session.terminal=spring

v$session中对应的programterminal字段的值,可以用来帮助判断session是否是brook增强过的

 

brook.aspect.connection.oracle.version=9 重要,目前必须设置9才生效,即使是oracle 10的版本。因为目前就算是oracle 10版本通过setEndToEndMetrics调用设置终端信息,由于后台存储过程无法获取通过这种方式设置的终端信息,所以必须用oracle 9版本的通过调用setclientidentifier存储过程来设置

 

brook.aspect.connection.enabled=true是否设置connection级别的增强,即client_identifier

 

以下配置已经废弃,不推荐修改

brook.aspect.sqllog.enabled=false

brook.aspect.sqllog.id=1

 

brook.rule.log.1=1;127.0..*;.*;.*;.*;log

 

 

打包,各文件说明

 

你可能感兴趣的:(终端)