Fluorinefx: authentication and authorization

Source: Internet
Author: User

For new students who do not have any idea about authentication and authorization, we recommend that you take a look at authentication and authorization in. net before continuing.

 

Flash/flex also encounters authentication and authorization problems when calling methods in. NET through fluorinefx, that is:

"Is my method accessible to any cat or dog ?" It can be understood as: "Do I need to log on before calling my method ?" This is Authentication

"After the guard comes in, can anyone of any identity get something ?" It can also be understood as: "What qualifications can users who have logged on call methods ?" This is authorization.

 

Steps:

1. Create your own logincommand class (equivalent to the guard for checking): demologincommand

Using system. collections; using system. security. principal; using fluorinefx. security; namespace _ 04_authentication {public class demologincommand: genericlogincommand {public override iprincipal doauthentication (string username, hashtable credentials) {string Password = Credentials ["password"] as string; If (username. length> 0) // Of course: This is only a demonstration. In actual applications, you can check the username and password from the database {genericidentity identity = new genericidentity (username); // the following code, grant the logon User: "admin" role, which is still a demo. In actual applications, You can query the role genericprincipal principal = new genericprincipal (identity, new String [] {"admin"}); Return principal;} else // handle events that fail the test {return NULL ;}}}}

2. Create a remote service demologinservice that can be called without authentication

Using system; using system. collections. generic; using system. LINQ; using system. web; using fluorinefx; namespace _ 04_authentication {[remotingservice] public class demologinservice {// In fact, any name can be used for this method, as long as the call in Flash is consistent with the call here (it can be understood as a method placeholder), but generally, to make sense, the return value is named login public bool login, in fact, it doesn't matter if true or false is returned. The focus is not to return true here;} // Similarly, the method name here can also be set to public bool logout () {New demologincommand (). logout (null); // This line is the key, which is equivalent to clearing the "authentication information" and returning true; // after understanding the previous line, you should also think: true or flase is returned here, which is not important }}}

3. For comparison, create a remote service that requires authentication: demosecureservice

Using system; using system. collections. generic; using system. LINQ; using system. web; using fluorinefx; namespace _ 04_authentication {[remotingservice] public class demosecureservice {// This is too simple. It does not explain Public String helloworld () {return "security data returned from the server. ";}}}

Wait a moment and ask a question: comparing this service with the service just created, except for the method name (and related method processing logic) in it is essentially no difference, right? By what, authentication is required to call this service, and that service can be called at will just now?

Very good. I hope you can continue with this question and we will announce it later.

Let's take a look at the processing of the background directory permissions in Asp.net. We can use the configuration in Web. config to determine whether a directory is accessible.

<Location Path = "admin"> <system. Web> <authorization> <deny users = "? "/> <Deny roles =" buyer "/> <deny roles =" seller "/> </authorization> </system. Web> </location>

The configuration in this section indicates that the/Admin directory cannot be accessed by anonymous users (that is, login is required), and the two roles "buyer" and "seller" are rejected (I .e: even if you log on, as long as you are a "buyer" or "seller", you cannot access it)

Fluorinefx also uses configurations to implement access permissions:

First look at the remoting-config.xml Configuration

<? XML version = "1.0" encoding = "UTF-8"?> <Service id = "remoting-service" class = "flex. messaging. services. remotingservice "messagetypes =" flex. messaging. messages. remotingmessage "> <adapters> <adapter-definition id =" DOTNET "class =" fluorinefx. remoting. remotingadapter "default =" true "/> </adapters> <default-channels> <channel ref =" My-AMF "/> </default-channels> <destination ID =" fluorine "> <Properties> <! -- All source sources (Files) are included --> <source> * </source> </Properties> <Security> <! -- This indicates that when accessing the service defined in source above, the security restrictions of "privileged-users" must be met --> <security-constraint ref = "privileged-users"/> </Security> </destination> <destination ID = "login"> <Properties> <source> _ 04_authentication.demologinservice </source> <! -- Note that there are no <Security/> nodes, that is, the access to _ 04_authentication.demologinservice is not restricted by security, that is, it can be called at will --> </Properties> </destination> </service>

The key point has been commented out. This configuration indicates that _ 04_authentication.demologinservice can be called without logon. Other service calls must be limited by "privileged-users, how is this restriction described?

Services-config.xml Configuration

<? XML version = "1.0" encoding = "UTF-8"?> <Services-config> <services> <service-include file-Path = "remoting-config.xml"/> </services> <Security> <! -- The preceding "privileged-users" corresponds to --> <security-constraint id = "privileged-users"> <! -- Indicates that the authentication method is customized by the developer --> <auth-method> Custom </auth-method> <! -- Call services related to this restriction, the role must be admin or user --> <roles> <role> admin </role> <role> User </role> </roles> </security-constraint> <! -- Here, we specify who checks the logon token, demologincommand --> <login-command class = "_ 04_authentication.demologincommand" Server = "Asp.net"/> </Security> <channels> <channel-definition id = "My-AMF" Class = "MX. messaging. channels. amfchannel "> <endpoint uri =" http: // {server. name }:{ server. port}/{context. root}/gateway. aspx "class =" flex. messaging. endpoints. amfendpoint "/> </channel-definition> <Properties> <! -- <Legacy-collection> true </legacy-collection> --> </Properties> </channels> </services-config>

Similarly, annotations have been added to the key areas.

Another important configuration: fluorinefx is hosted in the Asp.net IIS environment, so its authentication ticket is also saved in the cookie. The form authentication method of Web. config should be set to forms, that is

<? XML version = "1.0"?> <Configuration> <system. web> <compilation DEBUG = "true" targetframework = "4.0"/> 

OK, the server is complete. Let's take a look at the flash call:

Ui:

 

First, let's talk about what we want to do:

A. When you click "Log on" or "log off", call the demologinservice that does not need to be logged on.

B. When you click "remote call", call the demosecureservice to be authenticated.

Prediction Result:

Before clicking "Log on", if you directly click "remote call", the call should fail (So logon authentication is not yet performed)

If you click "Log on" and then click "remote call", the authentication is successful because the logon authentication has been completed.

Complete flash code:

Package {import flash. display. sprite; import flash.net. objectencoding; import Org. bytearray. remoting. service; import Org. bytearray. remoting. pendingcall; import Org. bytearray. remoting. events. resultevent; import Org. bytearray. remoting. events. faultevent; import FL. controls. textinput; import flash. text. textfield; import FL. controls. textarea; import FL. controls. button; import flash. events. mouseevent; public class Logindemo extends sprite {private VaR _ txtusername: textinput; private VaR _ txtpassword: textinput; private VaR _ txtresult: textarea; private VaR _ btnlogin: button; private VaR _ btnlogout: button; private VaR _ btncall: button; private VaR _ gatewayurl: String = ""; private VaR _ service: Service; private VaR _ callservice: Service; private VaR _ RPC: pendingcall; public Function logindemo () {This. _ txtusername = txtusername; This. _ txtpassword = txtpassword; this. _ txtresult = txtresult; this. _ btncall = btncall; this. _ btnlogin = btnlogin; this. _ btnlogout = btnlogout; this. _ txtusername. TEXT = "Yang Guo under the bodhi tree"; this. _ txtpassword. displayaspassword = true; this. _ txtpassword. TEXT = "123456"; if (root. loaderinfo. parameters. remotinggatewaypath! = NULL) {_ gatewayurl = root. loaderinfo. parameters. remotinggatewaypath + "/gateway. aspx ";} else {_ gatewayurl =" http: // localhost: 22892/gateway. aspx ";} This. _ btnlogin. addeventlistener (mouseevent. click, btnlogin_click); this. _ btnlogout. addeventlistener (mouseevent. click, btnlogout_click); this. _ btncall. addeventlistener (mouseevent. click, btncall_click);} // log on to the private function btnlogin_click (E: mouseevent): void {_ Ser Vice = new service ("_ 04_authentication.demologinservice", _ gatewayurl, objectencoding. amf3); // This line is critical for sending the user name and password to demologincommand_service.setremotecredentials (this. _ txtusername. text, this. _ txtpassword. text); _ RPC = _ service. login (); _ RPC. addeventlistener (resultevent. result, loginsuccess); _ RPC. addeventlistener (faultevent. fault, loginfailure);} private function loginsuccess (pevt: resultevent): void {T His. _ txtresult. Text = "Logon successful! ";} Private function loginfailure (pevt: faultevent): void {This. _ txtresult. TEXT = "Logon Failed, cause:" + pevt. fault. description;} // cancel private function btnlogout_click (E: mouseevent): void {_ service = new service ("_ 04_authentication.demologinservice", _ gatewayurl, objectencoding. amf3); _ RPC = _ service. logout (); _ RPC. addeventlistener (resultevent. result, logoutsuccess); _ RPC. addeventlistener (faultevent. fault, logoutfai Lure);} private function logoutsuccess (pevt: resultevent): void {This. _ txtresult. Text = "logout successful! ";} Private function logoutfailure (pevt: faultevent): void {This. _ txtresult. TEXT = "logout failed, cause:" + pevt. fault. description;} // remotely call the private function btncall_click (E: mouseevent): void {_ callservice = new service ("_ 04_authentication.demosecureservice", _ gatewayurl, objectencoding. amf3); _ RPC = _ callservice. helloworld (); _ RPC. addeventlistener (resultevent. result, callsuccess); _ RPC. addeventlistener (faultevent. fault, callfailure);} private function callsuccess (pevt: resultevent): void {This. _ txtresult. TEXT = "Call successful:" + pevt. result;} private function callfailure (pevt: faultevent): void {This. _ txtresult. TEXT = "Call failed, cause:" + pevt. fault. description ;}}}

Test run:

This is the result of clicking "remote call" directly. Note the large text box on the right: Requested access is not allowed, indicating that access is not allowed. This indicates that this service can be called only after authentication.

If you click "Log on" and then click "remote call", the authentication takes effect.

 

Finally, I will try again: As mentioned above, fluorinefx's authentication ticket is stored in cookies like Asp.net. Therefore, if you embed SWF on a webpage and Click Log On in flash, if you use

<% IF (! User. Identity. isauthenticated) {response. Write ("<H5> not logged on! </H5> ");} else {response. write ("<H5> <span style = 'color: red'>" + User. identity. name + "</span> already logged on! </H5> ") ;}%>

The user's logon status can also be detected! (The premise is not to close the page that just embedded SWF)

 

The only pity is that the cookie authentication ticket generated by fluorinefx does not contain the roles role information, so the isinrole cannot be used to determine the role of the current user on the ASPX page (I tracked it, fluorinefx only saves the user name, password, and some unique identifiers in the cookie. Although the official authentication demonstration uses isinrole for determination, it is actually useless ).

 

Of course, you can modify the source code of fluorinefx to solve this problem.

 

But fortunately, the opposite is acceptable! That is: If you log on to Asp.net, authentication and authorization information can be identified in flash. In general, this can meet the needs of the vast majority.

 

Download the sample source code: Example

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.