定制基于Tomcat的Flex认证
首先,我们先来实现基本认证(Basic)
1.编辑Tomcat的conf目录下的tomcat-users.xml添加用户名及角色定义
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="managers"/>
<user username="abc" password="abc" roles="managers"/>
</tomcat-users>
2.编辑BlazeDS的Samples应用的Services-config.xml添加安全设置
<security>
<login-command class="flex.messaging.security.TomcatLoginCommand" server="Tomcat">
<per-client-authentication>false</per-client-authentication>
</login-command>
<security-constraint id="trusted">
<auth-method>Custom</auth-method>
<roles>
<role>managers</role>
</roles>
</security-constraint>
</security>
3.编辑Samples应用的remoting-config.xml对指定的Service添加安全设置
<destination id="consultantService">
<properties>
<source>com.adobe.demo.ConsultantService
</source>
</properties>
<security>
<security-constraint ref="trusted"/>
</security>
</destination>
4.然后修改Samples应用的Web.xml,添加安全设置定义
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Sample</web-resource-name>
<url-pattern>/messagebroker/amf/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>managers</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>managers</role-name>
</security-role>
5.创建一个简单的Flex应用,实现自定义的登录
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:view="com.adobe.demo.view.*"
backgroundColor="#FFFFFF"
initialize="creationCompleteHandler();"
>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.messaging.config.ServerConfig;
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.messaging.ChannelSet;
// Define a ChannelSet object.
public var cs:ChannelSet;
// Define an AsyncToken object.
public var token:AsyncToken;
// Initialize ChannelSet object based on the
// destination of the RemoteObject component.
private function creationCompleteHandler():void {
if (cs == null)
cs = ServerConfig.getChannelSet(loaderService.destination);
//login
Alert.show("Init");
}
// Login and handle authentication success or failure.
private function ROLogin():void {
// Make sure that the user is not already logged in.
if (cs.authenticated == false) {
token = cs.login("abc", "abc");
// Add result and fault handlers.
token.addResponder(new AsyncResponder(LoginResultEvent, LoginFaultEvent));
}
}
// Handle successful login.
private function LoginResultEvent(event:ResultEvent, token:Object=null):void {
switch(event.result) {
case "success":
authenticatedCB.selected = true;
Alert.show("login successfully");
break;
default:
}
}
// Handle login failure.
private function LoginFaultEvent(event:FaultEvent, token:Object=null):void {
switch(event.fault.faultCode) {
case "Client.Authentication":
default:
authenticatedCB.selected = false;
Alert.show("Login failure: " + event.fault.faultString);
}
}
// Logout and handle success or failure.
private function ROLogout():void {
// Add result and fault handlers.
token = cs.logout();
token.addResponder(new AsyncResponder(LogoutResultEvent,LogoutFaultEvent));
}
// Handle successful logout.
private function LogoutResultEvent(event:ResultEvent, token:Object=null):void {
switch (event.result) {
case "success":
//authenticatedCB.selected = false;
Alert.show("logout successfully");
break;
default:
}
}
// Handle logout failure.
private function LogoutFaultEvent(event:FaultEvent, token:Object=null):void {
Alert.show("Logout failure: " + event.fault.faultString);
}
// Handle message recevied by RemoteObject component.
private function resultHandler(event:ResultEvent):void {
//ta.text += "Server responded: "+ event.result + "\n";
Alert.show("Ok loading data");
}
// Handle fault from RemoteObject component.
private function faultHandler(event:FaultEvent):void {
//ta.text += "Received fault: " + event.fault + "\n";
Alert.show("error loading data");
}
]]>
</mx:Script>
<mx:HBox>
<mx:Button label="Login"
click="ROLogin();"/>
<mx:Button label="Load Data"
click="loaderService.loadConsultants();"/>
<mx:Button label="Logout"
click="ROLogout();"/>
<mx:CheckBox id="authenticatedCB"
label="Authenticated?"
enabled="false"/>
</mx:HBox>
<mx:RemoteObject id="loaderService" destination="consultantService" result="resultHandler(event)" fault="faultHandler(event)" showBusyCursor="true" />
</mx:Application>
接下来我们实现基于JDBC的用户登录认证
1.创建用户管理表
CREATE TABLE users ( username varchar(15) NOT NULL PRIMARY KEY, password varchar(15) NOT NULL ); CREATE TABLE user_roles ( username varchar(15) NOT NULL, role varchar(15) NOT NULL, PRIMARY KEY (username, role)
);
2.复制Mysql 的JDBC Driver到Tomcat lib目录下,编辑Server.xml文件,将Realm的类从UserDatabase
改成JDBCRealm
<!-- Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/ -->
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost/consultant_db?user=root&password=root"
userTable="users" userNameCol="username" userCredCol="password"
userRoleTable="user_roles" roleNameCol="role"/>
3.在Samples应用目录下创建Context.xml
<!--
Enable the TomcatValve for custom login support from this webapp.
-->
<Context>
<Realm className="org.apache.catalina.realm.JDBCRealm" />
<Valve className="flex.messaging.security.TomcatValve"/>
</Context>
重新运行上面的Flex客户端,你会发现我们已经可以使用Datbase中的用户名和密码进行验证了。