posts - 2,  comments - 0,  trackbacks - 0
  2008年12月22日

TOMCAT 中的访问控制策略

TOMCAT的安全控制策略是根据Servlet 2.4规范来实现的。

1.在$CATALINA/conf/server.xml文件中配置:

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"  debug="0" resourceName="UserDatabase"/>

这里UserDatabase是一个jndi的名称,也需要在server.xml中配置,对应于$CATALINA/conf/tomcat-users.xml文件

2.tomcat-users.xml文件里面定义了用户和角色

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="manager"/>
  <role rolename="admin"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="manager" password="tomcat" roles="manager"/>
  <user username="admin" password="tomcat" roles="admin"/>
</tomcat-users>

3.在相应的应用的web.xml文件中加入<security-constraint><login-config> <security-role>标签,如下所示:
  <!-- Security is active on entire directory -->
  <security-constraint>
    <display-name>Tomcat Server Configuration Security Constraint</display-name>
    <web-resource-collection>
      <web-resource-name>Protected Area</web-resource-name>
      <!-- Define the context-relative URL(s) to be protected -->
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <!-- Anyone with one of the listed roles may access this area -->
      <role-name>admin</role-name>
    </auth-constraint>
  </security-constraint>

  <!-- Login configuration uses form-based authentication -->
  <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>Tomcat Server Configuration Form-Based Authentication Area</realm-name>
    <form-login-config>
      <form-login-page>/login.jsp</form-login-page>
      <form-error-page>/error.jsp</form-error-page>
    </form-login-config>
  </login-config>

  <!-- Security roles referenced by this web application -->
  <security-role>
    <description>
      The role that is required to log in to the Administration Application
    </description>
    <role-name>admin</role-name>
  </security-role>

4.在 <login-config>标签的<auth-method>FORM</auth-method>属性中,可以看到这里的authentication method 设置为FORM,这是一种基于表单的用户认证方式。基于form的用户认证需要在<form-login-page>/login.jsp</form-login-page>定义的登陆页面中提供一个包括用户名和密码的html表单,这个表单相对应于用户名和密码的元素必须是j_username和j_password,并且表单的ACTION必须为j_security_check。譬如: 
<form method="POST" action="j_security_chack"> 
<input type="text" name="j_username"> 
<input type="password" name="j_password"> 
</form> 

在验证通过之后,login页面会自动转向该应用的默认页面(index.html,index.jsp等等)。

除了FORM验证方式之外,还有BASIC和CLIENT-CERT这两种用户认证方式,前者是基本的用户认证方式,要求浏览器弹出一个对话框,录入用户名和密码。后者是使用客户数字证书来认证请求。

5.以上四步完成之后便可以通过在tomcat-users.xml文件中添加用户和角色来实现访问控制了。还是比较方面的。

posted @ 2008-12-26 17:17 sunnyiric 阅读(1483) | 评论 (0)编辑 收藏
Hibernate的主键生成策略有好几种:
1) assigned
2) hilo
3) seqhilo
4) increment
5) identity
6) sequence
7) native
8) uuid.hex
9) uuid.string
10) foreign
一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适
应性。另外由于常用的数据库,如Oracle、DB2、SQLServer、MySql 等,都提
供了易用的主键生成机制(Auto-Increase 字段或者Sequence)。我们可以在数
据库提供的主键生成机制上,采用generator-class=native的主键生成方式。
不过值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,
大量并发insert数据时可能会引起表之间的互锁。
数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状
态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),
之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之
后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据
库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生
了较大影响。
因此,对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生成
机制。
另外我们可以扩展Hibernate的类来做自己的主键生成策略:
java 代码
 
  1. package com.gsta.eshore.framework.util.uid;  
  2. import java.io.Serializable;  
  3. import org.hibernate.engine.SessionImplementor;  
  4. import org.hibernate.id.AbstractUUIDGenerator;  
  5. import org.hibernate.id.Configurable;  
  6. import org.hibernate.id.IdentifierGenerator;  
  7. import java.util.Properties;  
  8. import org.hibernate.Hibernate;  
  9. import org.hibernate.dialect.Dialect;  
  10. import org.hibernate.type.Type;  
  11. import org.hibernate.util.PropertiesHelper;  
  12. /** 
  13.  * <b>uuid</b><br> 
  14. * @author hwq 
  15.  */  
  16. public class UIDGenerator extends AbstractUUIDGenerator implements Configurable {  
  17.     private static long lastTime = System.currentTimeMillis();  
  18.     private static short lastCount = -32768;  
  19.     private static Object mutex = new Object();  
  20.     private static long ONE_SECOND = 1000L;  
  21.     private String sep = "";  
  22.     public Serializable generate(SessionImplementor session, Object obj) {  
  23.         long l = 0L;  
  24.         short word0 = 0;  
  25.         int i = 0;  
  26.         synchronized(mutex)  
  27.         {  
  28.             if(lastCount == 32767)  
  29.             {  
  30.                 for(boolean flag = false; !flag;)  
  31.                 {  
  32.                     l = System.currentTimeMillis();  
  33.                     if(l < lastTime + ONE_SECOND)  
  34.                     {  
  35.                         try  
  36.                         {  
  37.                             Thread.currentThread();  
  38.                             Thread.sleep(ONE_SECOND);  
  39.                         }  
  40.                         catch(InterruptedException interruptedexception) { }  
  41.                     } else  
  42.                     {  
  43.                         lastTime = l;  
  44.                         lastCount = -32768;  
  45.                         flag = true;  
  46.                     }  
  47.                 }  
  48.             } else  
  49.             {  
  50.                 l = lastTime;  
  51.             }  
  52.             word0 = lastCount++;  
  53.             i = getHostUniqueNum();  
  54.         }  
  55.         String s = Integer.toString(i, 16) + sep + Long.toString(l, 16) + sep + Integer.toString(word0, 16);  
  56.         if(s.length() > 24)  
  57.             s = s.substring(s.length() - 24);  
  58.         return s;  
  59.     }  
  60.     public Serializable generate_old(SessionImplementor session, Object obj) {  
  61.         String name = obj.getClass().getName();  
  62.         return new StringBuffer(64)  
  63.             .append(name.substring(name.lastIndexOf('.')+1)).append(sep)  
  64.             .append((short)getIP()).append(sep)  
  65.             .append(Math.abs((short)getJVM())).append(sep)  
  66.             .append(getCount())   
  67.             .toString();  
  68.     }  
  69.     private static int getHostUniqueNum()  
  70.     {  
  71.         return (new Object()).hashCode();  
  72.     }  
  73.     public void configure(Type type, Properties params, Dialect d) {  
  74.         sep = PropertiesHelper.getString("separator", params, "");  
  75.     }  
  76.     public static void main( String[] args ) throws Exception {  
  77.         Properties props = new Properties();  
  78.         props.setProperty("separator""");  
  79.         IdentifierGenerator gen = new UIDGenerator();  
  80.         ( (Configurable) gen ).configure(Hibernate.STRING, props, null);  
  81.         IdentifierGenerator gen2 = new UIDGenerator();  
  82.         ( (Configurable) gen2 ).configure(Hibernate.STRING, props, null);  
  83.         for ( int i=0; i<10; i++) {  
  84.             String id = (String) gen.generate(null, gen);  
  85.             System.out.println(id);  
  86.             String id2 = (String) gen2.generate(null, gen2);  
  87.             System.out.println(id2);  
  88.         }  
  89.     }  
  90. }  
这个类必须要扩展AbstractUUIDGenerator并实现Configurable接口,在generate方法中生成我们想要的主键。
在hibernate的配置文件中要做以下的配置:
xml 代码
 
  1. <id name="id" type="java.lang.String">  
  2.       <column name="id" length="24" />  
  3.       <generator class="com.gsta.eshore.framework.util.uid.UIDGenerator"><param name="separator">-</param></generator>  
  4.   </id>  
Generator的类要引用UIDGenerator,并且可以带参数生成主键,示例是根据时间,Ip等生成一个24位的字符串。这样做的灵活性大大提高了,提供了最好的性能和数据库平台适应性。
但是有时候我们在保存一条记录的时候是不能指定主键的,因为它的主键要来源于其他的表的主键,(hibernate推荐用代理主键,但是有时候设计的时候没有用到)。这个时候的主键生成策略就要是assigned了。为了保持主键的连贯性,我总不能又用另外一种主键生成策略吧。
仿照上面的类,我们做一个生成24为随机字符串的类。
java 代码
 
  1. package com.gsta.eshore.framework.util.uid;  
  2. public class UID  
  3. {  
  4.     private static long lastTime = System.currentTimeMillis();  
  5.     private static short lastCount = -32768;  
  6.     private static Object mutex = new Object();  
  7.     private static long ONE_SECOND = 1000L;  
  8.     public UID()  
  9.     {  
  10.     }  
  11.     public static String getUID()  
  12.     {  
  13.         long l = 0L;  
  14.         short word0 = 0;  
  15.         int i = 0;  
  16.         synchronized(mutex)  
  17.         {  
  18.             if(lastCount == 32767)  
  19.             {  
  20.                 for(boolean flag = false; !flag;)  
  21.                 {  
  22.                     l = System.currentTimeMillis();  
  23.                     if(l < lastTime + ONE_SECOND)  
  24.                     {  
  25.                         try  
  26.                         {  
  27.                             Thread.currentThread();  
  28.                             Thread.sleep(ONE_SECOND);  
  29.                         }  
  30.                         catch(InterruptedException interruptedexception) { }  
  31.                     } else  
  32.                     {  
  33.                         lastTime = l;  
  34.                         lastCount = -32768;  
  35.                         flag = true;  
  36.                     }  
  37.                 }  
  38.             } else  
  39.             {  
  40.                 l = lastTime;  
  41.             }  
  42.             word0 = lastCount++;  
  43.             i = getHostUniqueNum();  
  44.         }  
  45.         String s = Integer.toString(i, 16) + "`" + Long.toString(l, 16) + "`" + Integer.toString(word0, 16);  
  46.         if(s.length() > 24)  
  47.             s = s.substring(s.length() - 24);  
  48.         return s;  
  49.     }  
  50.     private static int getHostUniqueNum()  
  51.     {  
  52.         return (new Object()).hashCode();  
  53.     }  
  54.   
  55.    public static void main(String[] args) {  
  56.         for (int i = 0; i < 100; i++) {  
  57.             String uid=getUID();  
  58.             System.out.println(uid);  
  59.         }  
  60.         }  
  61. }  
在save一个实体的时候调用entity.setId(UID.getUID())。
呵呵,以后用hibernate就不用烦用什么主键生成策略了,自己做一个。
posted @ 2008-12-22 16:29 sunnyiric 阅读(493) | 评论 (0)编辑 收藏