Wenn wir den Code nicht einrichten, sondern nur ändern, sieht die Fehlerschnittstelle nach dem Ausführen des Programms wie in Abbildung 1 unten dargestellt aus:
Die Ausnahme wird wie folgt ausgelöst:
****************** Ausnahmetext ****************
System.MethodAccessException: Versuch der sicherheitstransparenten Methode „Rare.Card.Libary.Controls.
ReadCardControl.btnRead_Click(System.Object, System.EventArgs)“, um nativen Code über die Methode „Rare.Card.Libary“ aufzurufen .MifareOneHelper.rf_read(Int32, Int32, Byte[ ])' fehlgeschlagen. Methoden müssen sicherheitskritisch oder
sicherheitskritisch sein, um nativen Code aufzurufen.
Von Nach Rücksprache mit MSDN lautet die Erklärung der Ausnahme wie folgt:
In Microsoft .NET Framework 4 hat das Sicherheitsmodell der Common Language Runtime (CLR) viele Änderungen erfahren. Eine der Änderungen, die Einführung der Level2-Transparenz
(sehr ähnlich dem Sicherheitsmodell von Silverlight), wird sich wahrscheinlich auf die Autoren der AllowPartiallyTrustedCallers (APTCA)-Bibliothek auswirken. Es gibt drei Transparenzattribute: SecurityTransparent, SecuritySafeCritical und SecurityCritical.
SecurityTransparent: Als SecurityTransparent gekennzeichneter Code ist aus Sicherheitsgründen zuverlässig. Es können keine gefährlichen Vorgänge ausgeführt werden, wie z. B. die Geltendmachung von Berechtigungen, das
Ausführen von nicht überprüfbarem Code oder das Aufrufen von nativem Code. Es kann auch keinen sicherheitskritischen Code direkt aufrufen.
Wie oben erwähnt, muss jeder teilweise vertrauenswürdige Code aus Sicherheitsgründen SecurityTransparent sein. Dies ist auch die Standardtransparenz der APTCA-Bibliothek.
SecurityCritical: Im Gegensatz zu SecurityTransparent ist SecurityCritical-Code in der Lage, jeden gewünschten Vorgang auszuführen. Es kann Deklarationen,
Aufrufe an nativen Code und andere Vorgänge ausführen. Es kann andere Methoden aufrufen, ohne durch das Transparenzflag eingeschränkt zu werden.
Nur vollständig vertrauenswürdiger Code kann sicherheitskritisch sein. Tatsächlich ist (nicht APTCA) vollständig vertrauenswürdiger Code standardmäßig sicherheitskritisch,
und schützt ihn so vor Aufrufen durch transparente, teilweise vertrauenswürdige Aufrufer.
SecuritySafeCritical: SecuritySafeCritical-Code spielt die Rolle einer Brücke, die es transparentem Code ermöglicht, Schlüsselmethoden aufzurufen. SecuritySafeCritical
-Code verfügt über dieselben Berechtigungen wie SecurityCritical-Code, kann jedoch von SecurityTransparent-Code aufgerufen werden. Daher ist es äußerst wichtig, dass der SecuritySafeCritical-Code die zugrunde liegenden SecurityCritical-Methoden auf sichere Weise offenlegt (um zu verhindern, dass teilweise vertrauenswürdiger Schadcode versucht, diese Methoden über die SecuritySafeCritical-Schicht anzugreifen).
Wie SecurityCritical-Code muss auch SecuritySafeCritical-Code vollständig vertrauenswürdig sein.
Laut der Erklärung von MSDN liegt das Problem in der C#-Klassenbibliothek CardReader.Library, die die ursprüngliche Dll kapselt. Wir können das Transparenzattribut auf Codeebene festlegen, um das Problem zu lösen.
Die konkrete Lösung lautet wie folgt:
1. Setzen Sie das transparente Attribut des Lesecodes der ActiveX-Steuerkarte auf: SecuritySafeCritical. Die Codeliste lautet nach der Einstellung wie folgt:
[SecuritySafeCritical] /// <summary> /// 读卡 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnRead_Click(object sender, EventArgs e) { int i = 0; byte[] data = new byte[16]; byte[] buff = new byte[32]; for (i = 0; i < 16; i++) data[i] = 0; for (i = 0; i < 32; i++) buff[i] = 0; st = MifareOneHelper.rf_read(icdev, sec * 4 + 1, data); if (st == 0) { SerialInterfaceHelper.hex_a(data, buff, 16); txtCardID.Text = System.Text.Encoding.ASCII.GetString(buff); lblMsg.Text = "读取卡号成功!"; } else lblMsg.Text = "读取卡号失败!"; //test method //if (string.IsNullOrEmpty(txtCardID.Text)) //{ // lblMsg.Text = "读取数据失败!"; //} //else //{ // lblMsg.Text = string.Format("读取数据:{0}!", txtCardID.Text); //} }
Hinweis zum Hinzufügen einer Referenz: using System.Security;
Der Testcode wird hier auskommentiert und der serielle Kommunikations- und Kartenlesecode wird verwendet.
2. Legen Sie das transparente Attribut fest, das die ursprüngliche Kartenleser-DLL kapselt.
Setzen Sie das transparente Attribut der M1-Kartenleser-Hilfsklasse MifareOneHelper auf: [SecurityCritical] und setzen Sie das
transparente Attribut der aufgerufenen Methode MifareOneHelper.rf_read auf [SecurityCritical].
Setzen Sie das transparente Attribut der seriellen Kommunikationshilfsklasse SerialInterfaceHelper auf: [SecurityCritical] und setzen Sie das
transparente Attribut der aufgerufenen Methode SerialInterfaceHelper.hex_a auf [SecurityCritical].
Der vollständige Code wurde bereitgestellt. Wenn der Client ActiveX nicht installiert, wird die Adresse, auf der ActiveX ausgeführt wird, zur vertrauenswürdigen Site hinzugefügt Die Site wird auf „Minimieren“ reduziert oder die Option „Sites vertrauen“ für ActiveX festgelegt.