一、 Realm/ HTTP认证
1)Realm
Realm提供了Web认证用户和角色信息的存储机制,如下是Tomcat关于Realm的说明
我们看看Realm的接口定义
public interface Realm { public Container getContainer(); public void setContainer(Container container); public String getInfo(); public void addPropertyChangeListener(PropertyChangeListener listener); public Principal authenticate(String username, String credentials); public Principal authenticate(String username, byte[] credentials); public Principal authenticate(String username, String digest, String nonce, String nc, String cnonce, String qop, String realm, String md5a2); public Principal authenticate(X509Certificate certs[]); public void backgroundProcess(); public SecurityConstraint [] findSecurityConstraints(Request request, public boolean hasResourcePermission(Request request, Response response, SecurityConstraint [] constraint, Context context) throws IOException; public boolean hasRole(Principal principal, String role); public boolean hasUserDataPermission(Request request, Response response, SecurityConstraint []constraint) throws IOException; public void removePropertyChangeListener(PropertyChangeListener listener); }
Tomcat提供了多种的Realm实现,实现代码比较简单
2)HTTP认证
关于HTTP认证可参见《HTTP认证及其在Web平台中的实现 》,Tomcat通过Realm实现HTTP认证用户/角色信息的存储。Tomcat的HTTP认证实现以Valve的方式提供的(见之前关于pipeline的说明,需要注意的是,这个Valve不需要显式地配置,默认ContextConfig会根据web.xml设置的信息自动注册一个认证实现),每种实现会实现org.apache.catalina.Authenticator接口(空接口)
public interface Authenticator { }
默认Tomcat提供了如下的实现,代码比较简单,可同时参见Realm的实现
如下是tomcat默认提供的manager的web.xml中关于HTTP认证部分的配置
<security-constraint> <web-resource-collection> <web-resource-name>HTMLManger and Manager command</web-resource-name> <url-pattern>/jmxproxy/*</url-pattern> <url-pattern>/html/*</url-pattern> <url-pattern>/list</url-pattern> <url-pattern>/expire</url-pattern> <url-pattern>/sessions</url-pattern> <url-pattern>/start</url-pattern> <url-pattern>/stop</url-pattern> <url-pattern>/install</url-pattern> <url-pattern>/remove</url-pattern> <url-pattern>/deploy</url-pattern> <url-pattern>/undeploy</url-pattern> <url-pattern>/reload</url-pattern> <url-pattern>/save</url-pattern> <url-pattern>/serverinfo</url-pattern> <url-pattern>/status/*</url-pattern> <url-pattern>/roles</url-pattern> <url-pattern>/resources</url-pattern> <url-pattern>/findleaks</url-pattern> </web-resource-collection> <auth-constraint> <!-- NOTE: This role is not present in the default users file --> <role-name>manager</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>BASIC</auth-method> <realm-name>Tomcat Manager Application</realm-name> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description> The role that is required to log in to the Manager Application </description> <role-name>manager</role-name> </security-role>
二、 Manager/Cluster
1.Manager
Manager接口实现了对Session的管理,看看Tomcat中关于Manager的定义
org.apache.catalina.session.StandardManager是默认的Manager实现,在内存中维持Session信息,并支持简单地将 Session持久化到文件中,以支持在Tomcat重启后Session信息不会全部丢失(注意,只有通过正确的shutdown,Session信息才会被正确持久化)
我们可以通过扩展Manager来自定制对Session的管理(譬如,我们可以扩展使用memcached来存储session数据 ),除StandardManager,Tomcat还提供了如下的Session实现
2.Cluster
关于Cluster的详情可参见http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html ,Cluster是Manager的创建工厂,Cluster的接口非常简单,如下
public interface Cluster { public String getInfo(); public String getClusterName(); public void setClusterName(String clusterName); public void setContainer(Container container); public Container getContainer(); public void setProtocol(String protocol); public String getProtocol(); public Manager createManager(String name); public void registerManager(Manager manager); public void removeManager(Manager manager); public void backgroundProcess(); }
Cluster的实现只有一种org.apache.catalina.ha.tcp.SimpleTcpCluster,通过如下的配置范例,我们可以大概了解Cluster的主要结构,关于详细的实现,可以参见org.apache.catalina.ha包,代码相对比较独立,初始化和请求处理机制跟Tomcat机制类似,我们在前面中已有介绍。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>