[Seasar-user:19923] (続)S2BlazeDSでの認証の実装

tmp [E-MAIL ADDRESS DELETED]
2010年 6月 27日 (日) 23:28:36 JST


お世話になります。Zenです。

以前S2BlazeDSでの認証の実装方法を質問したものです。

現在いろいろと実験している最中なのですが、
とりあえずBlazeDSのしきたり通り?の実装を試しているのですが、
Cool Deploy、Warm Deployではうまく動くのですが、Hot Deployで
うまく動きません。

実装しているのは、Flex上でRemoteObject.ChannelSet#loginを使った下記のよ
うなカスタム認証で、
http://help.adobe.com/ja_JP/LiveCycleDataServicesES/3.0/Developing/WSc3ff6d0ea77859461172e0811f00f7045b-7f36.html
Tomcatの認証機構でなく、flex.messaging.security.AppServerLoginCommandを
継承したクラスを
つくっています。
Hot Deployでも認証機構(/doAuthentication/) はちゃんと動いているのです
が、認可(doAuthorization)で
「Login required before authorization can proceed.」というメッセージがで
てしまいます。
と同時にコンソールには
「HOT deploy対象クラス(custom.service.UserService)が非対象クラスから参照
されて通常のクラスローダにロードされています。」と表示されます。
※ custom.service.UserServiceはremoting-config.xmlでdestinationに指定した
サービスクラスです。

ここで、Seaser側のクラスの動的な読み込みが原因なのか?、それとも、クラス
の作り方が悪いのか?
Seaserど素人の私では手をこまねいているわけです...。

Hot Deploy であってもSeaser(S2BlazeDS)の起動時にクラスローダーが指定のク
ラスを読ませられるのか?
それとも、そもそも実装がおかしいのか?
こういう案件はWarm Deployで対処しろという感じなのか?
よくわかりません。

認証処理なので、システム全体の開発に影響が出てくるところなので出来れば
Hot Deploy でうまく動く方法があれば
ご教授願いたいです。

一応、拙いテストソースを以下に示します。
Flex側は該当処理部分だけですが、
---------------------------------------------------
<mx:Script><![CDATA[
public getMethod(){
if(userService.channelSet.authenticated){
userService.test();
}else{
login();
}
}
public function login():void{
var token:AsyncToken = userService.channelSet.login(username.text,
password.text);
token.addResponder(new ItemResponder(loginResultEvent, loginFaultEvent));
}
private function loginFaultEvent(fe:FaultEvent, token:AsyncToken):void {
/*ログイン失敗時処理*/
}
private function loginResultEvent(re:ResultEvent, token:AsyncToken):void {
/*ログイン成功時処理*/
}
]]></mx:Script>
<mx:AMFChannel id="AMFChannel" uri="http://localhost:8400/コンテキスト
/messagebroker/amf"/>
<mx:ChannelSet id="channelSet" channels="{[AMFChannel]}" />
<mx:RemoteObject destination="userService" id="userService"
showBusyCursor="true" channelSet="{channelSet}" />

remoting-config.xmlの該当部分
---------------------------------------------------
<destination id="userService">
<properties>
<source>custom.service.UserService</source>
<scope>application</scope>
</properties>
<security>
<security-constraint ref="trusted" />
</security>
</destination>

services-config.xmlの該当部分
---------------------------------------------------
<security>
<security-constraint id="trusted">
<auth-method>Custom</auth-method>
<roles>
<role>managers</role>
</roles>
</security-constraint>

<login-command class="login.LoginManager" server="all">
<per-client-authentication>false</per-client-authentication>
</login-command>
</security>


LoginManager.java(認証、認可クラス)
---------------------------------------------------
package login;
import java.security.Principal;
import java.util.List;
import javax.servlet.ServletConfig;
import flex.messaging.security.AppServerLoginCommand;

public class LoginManager extends AppServerLoginCommand
{
public Principal doAuthentication(String username, Object attributes)
throws SecurityException
{
String password = (String)attributes;
//ユーザーの認証処理です。
if(username.equals("ユーザー名") && password.equals("パスワード"))
{
//UserVOはユーザー情報保持用クラス
UserVO vo = new UserVO(username);
vo.groups= new String [1];
//ダミーのグループ情報
vo.groups[0]="managers";
return vo;
}
return null;
}
public boolean doAuthorization(Principal user, List roles) throws
SecurityException
{
//ユーザーの認可処理です。
UserVO userObj = (UserVO)user;
if(userObj == null) return false;
//許可されたグループに所属しているか?
for(int i=0;i<roles.size();i++)
{
String role = (String)roles.get(i);
if(userObj.hasRole(role))
return true;
}
return false;
}
public boolean logout(Principal arg0) {
return false;
}
public void start(ServletConfig arg0) {
}
public void stop() {
}
}

UserVO .java(ユーザー情報保持用クラス)
---------------------------------------------------
package login;
import java.security.Principal;
public class UserVO implements Principal
{
public String [] groups;
public String username;

public UserVO(String username)
{
this.username = username;
}
public String getName() {
return this.username;
}
public boolean hasRole(String role)
{
for(int i=0;i<groups.length;i++)
{
if(groups[i].equals(role))
return true;
}
return false;
}
}




Seasar-user メーリングリストの案内