FluorineFx:认证与授权
来源:互联网 发布:淘宝店铺售后服务 编辑:程序博客网 时间:2024/05/17 00:00
FluorineFx:认证与授权
对认证与授权没啥概念的新同学,建议先看下 .net中的认证(authentication)与授权(authorization),然后再继续。
Flash/Flex在通过FluorineFx调用.Net中的方法时,同样也会遇到认证与授权问题,即:
“是否随便一个阿猫阿狗都能来调用我的方法?”或者可以理解为:“调用我的方法前是否需要登录?” 这就是认证
“门卫放进来后,是不是不管什么身份的人,都能来拿东西?”或者可以理解为:“登录后的用户,具备何种资格的人才能调用方法?” 这就是授权
步骤:
1、先创建自己的LoginCommand类(相当于门卫,用于把关):DemoLoginCommand
01
using
System.Collections;
02
using
System.Security.Principal;
03
using
FluorineFx.Security;
04
05
namespace
_04_Authentication
06
{
07
public
class
DemoLoginCommand:GenericLoginCommand
08
{
09
public
override
IPrincipal DoAuthentication(
string
username, Hashtable credentials)
10
{
11
string
password = credentials[
"password"
]
as
string
;
12
if
(username.Length > 0)
//当然:这里只是演示,实际应用中可从数据库中检验用户名和密码
13
{
14
GenericIdentity identity =
new
GenericIdentity(username);
15
//下面的代码,授予登录用户:"admin"角色,仍然只是演示,实际应用中,可以根据用户名到数据库里查询对应的角色
16
GenericPrincipal principal =
new
GenericPrincipal(identity,
new
string
[] {
"admin"
});
17
18
return
principal;
19
}
20
else
//检验不通过的处理
21
{
22
return
null
;
23
}
24
}
25
}
26
}
2、再创建一个不需要认证就能随便调用的远程服务 DemoLoginService
01
using
System;
02
using
System.Collections.Generic;
03
using
System.Linq;
04
using
System.Web;
05
using
FluorineFx;
06
07
namespace
_04_Authentication
08
{
09
[RemotingService]
10
public
class
DemoLoginService
11
{
12
//其实这个方法随便起什么名字都行,只要在flash中调用时跟这里一致就行(可以理解为方法占位符),但是通常为了有意义,命名为Login
13
public
bool
Login()
14
{
15
//这个返回值,其实返回true或false都无所谓,重点不在这里
16
return
true
;
17
}
18
19
//同样,这里方法的名字其实也可以随便起
20
public
bool
Logout()
21
{
22
new
DemoLoginCommand().Logout(
null
);
//这一行才是关键,相当于把"认证信息"清空了
23
return
true
;
//明白了上一行后,其实也应该能想到:这里返回true或flase其实都不重要
24
}
25
}
26
}
3、为了对比,再来创建一个需要认证的远程服务:DemoSecureService
01
using
System;
02
using
System.Collections.Generic;
03
using
System.Linq;
04
using
System.Web;
05
using
FluorineFx;
06
07
namespace
_04_Authentication
08
{
09
[RemotingService]
10
public
class
DemoSecureService
11
{
12
//太简单了,不作解释了
13
public
string
HelloWorld()
14
{
15
return
"从服务端返回的安全数据."
;
16
}
17
}
18
}
等一下,提个问题:比较这个服务跟刚才创建的服务,除了里面的方法名称(及相关的方法处理逻辑)不同,本质上没区别吧? 凭啥说调用这个服务就需要认证,而刚才那个服务就能随便调用?
很好,希望大家带着这个问题继续,后面会揭晓。
先打个岔:回想一下asp.net中后台目录权限的处理,我们可以在web.config 中通过配置来决定某个目录是否可访问
1
<
location
path
=
"admin"
>
2
<
system.web
>
3
<
authorization
>
4
<
deny
users
=
"?"
/>
5
<
deny
roles
=
"买家"
/>
6
<
deny
roles
=
"卖家"
/>
7
</
authorization
>
8
</
system.web
>
9
</
location
>
这段配置的意思就是 /admin目录,匿名用户无法访问(即要求登录),同时"买家","卖家"二种角色被拒绝了(即:就算你登录了,只要你是"买家"或"卖家"角色,同样也访问不了)
FluorineFx中,同样也是用配置来实现权限访问的:
先看remoting-config.xml的配置
01
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02
<
service
id
=
"remoting-service"
03
class
=
"flex.messaging.services.RemotingService"
04
messageTypes
=
"flex.messaging.messages.RemotingMessage"
>
05
06
07
<
adapters
>
08
<
adapter-definition
id
=
"dotnet"
class
=
"FluorineFx.Remoting.RemotingAdapter"
default
=
"true"
/>
09
</
adapters
>
10
11
<
default-channels
>
12
<
channel
ref
=
"my-amf"
/>
13
</
default-channels
>
14
15
16
17
<
destination
id
=
"fluorine"
>
18
<
properties
>
19
<!--这里表示所有源(文件)包括在内-->
20
<
source
>*</
source
>
21
</
properties
>
22
<
security
>
23
<!--这里表明访问上面source中定义的服务时,必须满足"privileged-users"的安全限制-->
24
<
security-constraint
ref
=
"privileged-users"
/>
25
</
security
>
26
</
destination
>
27
28
29
<
destination
id
=
"login"
>
30
<
properties
>
31
<
source
>_04_Authentication.DemoLoginService</
source
>
32
<!--注意这里没有<security />节点,即_04_Authentication.DemoLoginService的访问没有安全限制,也就是可随便调用-->
33
</
properties
>
34
</
destination
>
35
36
</
service
>
关键地方已经注释了,这个配置就表明了_04_Authentication.DemoLoginService不需要登录就能调用,而其它服务调用时要受到"privileged-users"的限制,那么这个限制到底如何描述的呢?
services-config.xml配置
01
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
02
<
services-config
>
03
<
services
>
04
<
service-include
file-path
=
"remoting-config.xml"
/>
05
</
services
>
06
07
08
<
security
>
09
<!--这里跟前面的"privileged-users"对应上了-->
10
<
security-constraint
id
=
"privileged-users"
>
11
<!--表明认证方法为开发人员自定义-->
12
<
auth-method
>Custom</
auth-method
>
13
<!--调用该限制相关的服务,必须是admin或user角色-->
14
<
roles
>
15
<
role
>admin</
role
>
16
<
role
>user</
role
>
17
</
roles
>
18
</
security-constraint
>
19
<!--这里指明了验证登录时,由谁来把关,即DemoLoginCommand-->
20
<
login-command
class
=
"_04_Authentication.DemoLoginCommand"
server
=
"asp.net"
/>
21
</
security
>
22
23
<
channels
>
24
<
channel-definition
id
=
"my-amf"
class
=
"mx.messaging.channels.AMFChannel"
>
25
<
endpoint
uri
=
"http://{server.name}:{server.port}/{context.root}/Gateway.aspx"
class
=
"flex.messaging.endpoints.AMFEndpoint"
/>
26
</
channel-definition
>
27
<
properties
>
28
<!-- <legacy-collection>true</legacy-collection> -->
29
</
properties
>
30
</
channels
>
31
</
services-config
>
同样:重点地方已经加了注释。
另外一个重要配置:fluorineFx说到底是宿主在asp.net iis环境中的,所以它的认证票据同样是保存在cookie中的,web.config的表单认证方式要设置为Forms,即
01
<?
xml
version
=
"1.0"
?>
02
<
configuration
>
03
<
system.web
>
04
<
compilation
debug
=
"true"
targetFramework
=
"4.0"
/>
05
06
<
httpModules
>
07
<
add
name
=
"FluorineGateway"
type
=
"FluorineFx.FluorineGateway, FluorineFx"
/>
08
</
httpModules
>
09
10
<!--这里要指定为Forms认证方式-->
11
<
authentication
mode
=
"Forms"
></
authentication
>
12
13
</
system.web
>
14
</
configuration
>
ok,服务端就全部完成了,再来看Flash端的调用:
UI界面:
先讲下我们要做什么:
a、点击“登录”或“注销”时,调用不需要登录的DemoLoginService
b、点击"远程调用"时,调用需要认证的DemoSecureService
预测一下结果:
点击“登录”前,如果直接点击“远程调用”,应该会调用失败(因此此时尚未登录认证)
如果先点击“登录”后,再点击“远程调用”,因为这时已经登录认证过了,所以应该成功
完整flash代码:
001
package
002
{
003
import
flash.display.Sprite;
004
import
flash.net.ObjectEncoding;
005
import
org.bytearray.remoting.Service;
006
import
org.bytearray.remoting.PendingCall;
007
import
org.bytearray.remoting.events.ResultEvent;
008
import
org.bytearray.remoting.events.FaultEvent;
009
import
fl.controls.TextInput;
010
import
flash.text.TextField;
011
import
fl.controls.TextArea;
012
import
fl.controls.Button;
013
import
flash.events.MouseEvent;
014
015
016
017
public
class
LoginDemo
extends
Sprite
018
{
019
private
var
_txtUserName:TextInput;
020
private
var
_txtPassWord:TextInput;
021
private
var
_txtResult:TextArea;
022
private
var
_btnLogin:Button;
023
private
var
_btnLogOut:Button;
024
private
var
_btnCall:Button;
025
026
private
var
_gatewayUrl:
String
=
""
;
027
private
var
_service:Service;
028
private
var
_callService:Service;
029
private
var
_rpc:PendingCall;
030
031
032
public
function
LoginDemo()
033
{
034
035
this
._txtUserName = txtUserName;
036
this
._txtPassWord = txtPassword;
037
this
._txtResult = txtResult;
038
this
._btnCall = btnCall;
039
this
._btnLogin = btnLogin;
040
this
._btnLogOut = btnLogout;
041
042
this
._txtUserName.text =
"菩提树下的杨过"
;
043
this
._txtPassWord.displayAsPassword =
true
;
044
this
._txtPassWord.text =
"123456"
;
045
046
047
if
(root.loaderInfo.parameters.remotingGatewayPath !=
null
)
048
{
049
_gatewayUrl = root.loaderInfo.parameters.remotingGatewayPath +
"/Gateway.aspx"
;
050
}
051
else
052
{
053
_gatewayUrl =
"http://localhost:22892/Gateway.aspx"
;
054
055
}
056
057
058
this
._btnLogin.addEventListener(MouseEvent.CLICK,btnLogin_Click);
059
this
._btnLogOut.addEventListener(MouseEvent.CLICK,btnLogout_Click);
060
this
._btnCall.addEventListener(MouseEvent.CLICK,btnCall_Click);
061
062
063
}
064
065
//登录
066
private
function
btnLogin_Click(e:MouseEvent):
void
067
{
068
_service =
new
Service(
"_04_Authentication.DemoLoginService"
,_gatewayUrl,ObjectEncoding.AMF3);
069
//这一行是关键,用于将用户名、密码发送到DemoLoginCommand
070
_service.setRemoteCredentials(
this
._txtUserName.text,
this
._txtPassWord.text);
071
_rpc = _service.Login();
072
_rpc.addEventListener( ResultEvent.RESULT, loginSuccess );
073
_rpc.addEventListener( FaultEvent.FAULT, loginFailure );
074
075
}
076
077
private
function
loginSuccess( pEvt:ResultEvent ):
void
078
{
079
this
._txtResult.text =
"登录成功!"
;
080
}
081
082
083
084
private
function
loginFailure( pEvt:FaultEvent ):
void
085
{
086
this
._txtResult.text =
"登录失败,原因:"
+ pEvt.fault.description;
087
}
088
089
//注销
090
private
function
btnLogout_Click(e:MouseEvent):
void
091
{
092
_service =
new
Service(
"_04_Authentication.DemoLoginService"
,_gatewayUrl,ObjectEncoding.AMF3);
093
_rpc = _service.Logout();
094
_rpc.addEventListener( ResultEvent.RESULT, logoutSuccess );
095
_rpc.addEventListener( FaultEvent.FAULT, logoutFailure );
096
097
}
098
099
100
private
function
logoutSuccess( pEvt:ResultEvent ):
void
101
{
102
this
._txtResult.text =
"注销成功!"
;
103
}
104
105
106
107
private
function
logoutFailure( pEvt:FaultEvent ):
void
108
{
109
this
._txtResult.text =
"注销失败,原因:"
+ pEvt.fault.description;
110
}
111
112
//远程调用需要认证的服务
113
private
function
btnCall_Click(e:MouseEvent):
void
114
{
115
_callService =
new
Service(
"_04_Authentication.DemoSecureService"
,_gatewayUrl,ObjectEncoding.AMF3);
116
_rpc = _callService.HelloWorld();
117
_rpc.addEventListener( ResultEvent.RESULT, callSuccess );
118
_rpc.addEventListener( FaultEvent.FAULT, callFailure );
119
120
}
121
122
123
private
function
callSuccess( pEvt:ResultEvent ):
void
124
{
125
this
._txtResult.text =
"调用成功:"
+ pEvt.result;
126
}
127
128
129
130
private
function
callFailure( pEvt:FaultEvent ):
void
131
{
132
this
._txtResult.text =
"调用失败,原因:"
+ pEvt.fault.description;
133
}
134
}
135
}
测试运行的截图:
这是一上来就直接点击"远程调用"的结果,注意右侧的大文本框:Requested access is not allowed 即访问不允许,说明这个服务是需要认证才能调用的。
如果点击“登录”后,再点击"远程调用",这回成功了,说明认证起作用了。
最后再啰嗦一下:前面提到了FluorineFx的认证票据跟asp.net一样,是保存在Cookie的,所以如果您把swf嵌入到网页上,在flash中点击登录后,如果在其它aspx页面上用
01
<%
if
(!User.Identity.IsAuthenticated)
02
{
03
Response.Write(
"<h5>尚未登录!</h5>"
);
04
}
05
else
06
{
07
Response.Write(
"<h5><span style='color:red'>"
+ User.Identity.Name +
"</span>已经登录!</h5>"
);
08
09
10
}
11
%>
同样也能检测出用户的登录状态!(前提是不要关闭刚才那个嵌入swf的页面)
唯一遗憾的是:FluorineFx生成的Cookie认证票据中,并未包含Roles角色信息,所以在AspX页面上无法用IsInRole来判断当前用户的角色(我跟踪了一下,fluorineFx在Cookie中仅保存了用户名、密码以及一些唯一性标识,官方提供的认证演示中虽然有用IsInRole来判断,但其实是没用的)。
当然这个问题,您可以修改FluorineFx的源码来解决,这点工作就留给大家了。
不过令人高兴的是,反过来却可以!即:如果在asp.net上登录了,认证和授权信息在flash里能识别,通常情况下,这已经能满足绝大多数需要了。
示例源代码下载: http://cid-2959920b8267aaca.office.live.com/self.aspx/Flash/FluorineFx^_Demo^_04.rar
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文连接:http://www.cnblogs.com/yjmyzz/archive/2010/08/30/1812956.html
- FluorineFx:认证与授权
- [转]FluorineFx:认证与授权
- Flex与.NET互操作(九):FluorineFx.NET的认证(Authentication )与授权(Authorization)
- Flex与.NET互操作(九):FluorineFx.NET的认证(Authentication )与授权(Authorization)
- Flex与.NET互操作(九):FluorineFx.NET的认证(Authentication )与授权(Authorization)
- 认证与授权
- OAuth认证与授权
- Mosca认证与授权
- ACL系统授权与认证
- 认证(authentication)与授权(authorization)
- 认证(Authentication)与授权(Authorization)
- ActiveMq认证与授权配置
- Asp.net中的认证与授权
- JAAS:java授权与认证服务
- Spring security认证与授权(一)
- Spring security认证与授权(二)
- Spring security认证与授权(三)
- Spring security认证与授权(四)
- iptable配置
- 老子的软件之道 - 道篇 16 再谈需求
- Oracle PL/SQL正则表达式之脱字符caret(^)与中括号square brankets([])的组合使用小例
- 又遇WebService 的跨域访问
- 翻译小工具
- FluorineFx:认证与授权
- apache [error]:server reached MaxClients setting, consider raising the MaxClients setting
- C++ Utilities四(Uninitialized memory的使用)
- 关于类关系图的使用小技巧
- 使用textcopy对sqlserver的Image字段进行读取和写入
- 适合T-SQL入门的人看
- What do you really have?
- Linux C 线程同步实例分析(二)
- ERP和SAP是什么意思?