zoukankan      html  css  js  c++  java
  • 【读书笔记】C#高级编程 第二十二章 安全性

    (一)身份验证和授权

    安全性的两个基本支柱是身份验证和授权。身份验证是标识用户的过程,授权在验证了所标识用户是否可以访问特性资源之后进行的。

     

    1、标识和Principal

    使用标识可以验证运行应用程序的用户。Principal是一个包含用户的标识和用户所属角色的对象。

    AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
    
     
    var principal = WindowsPrincipal.Current as WindowsPrincipal;
    var identity = principal.Identity as WindowsIdentity;
    Console.WriteLine("身份类型:{0}",identity.ToString());
    Console.WriteLine("名称:{0}",identity.Name);
    Console.WriteLine("角色是否为用户:{0}",principal.IsInRole(WindowsBuiltInRole.User));
    Console.WriteLine("角色是否为超级管理员:{0}", principal.IsInRole(WindowsBuiltInRole.Administrator));
    Console.WriteLine("是否身份验证:{0}",identity.IsAuthenticated);
    Console.WriteLine("身份验证类型:{0}", identity.AuthenticationType);
    Console.WriteLine("是否匿名:{0}", identity.IsAnonymous);
    Console.WriteLine("账户标记:{0}", identity.Token);

     

    2、角色

    基于角色的安全性可以很好地解决资源访问问题。

     

    3、声明基于角色的安全性

    如果使用非本地User组中的账户运行以下代码,ShowMessage()方法将会抛出一个异常。

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
     
        try
        {
            ShowMessage();
        }
        catch (SecurityException exception)
        {
            Console.WriteLine("捕捉安全异常:({0})",exception.Message);
            Console.WriteLine("当前主体应放置入本地用户组");
        }
        Console.ReadKey();
    }
    [PrincipalPermission(SecurityAction.Demand,Role ="BUILTIN\Users")]
    private static void ShowMessage()
    {
        Console.WriteLine("当前主体已登录本地");
        Console.WriteLine("(本地用户组中成员是)");
    }

     

    4、声称

    除了使用角色之外,还可以使用声称访问用户信息。声称与实体有关,描述实体的能力。实体通常是用户,也可以是应用程序。能力描述了实体允许执行的操作。这样声称比角色模型灵活得多。

    var principal = WindowsPrincipal.Current as ClaimsPrincipal;
     
    Console.WriteLine();
    Console.WriteLine("获取包含所有声明的集合,这些声明都来自于此声明主体关联的声明标识符。");
    foreach (var claim in principal.Claims)
    {
        Console.WriteLine("主题:{0}", claim.Subject)
        Console.WriteLine("颁发者:{0}", claim.Issuer);
        Console.WriteLine("声称类型:{0}", claim.Type);
        Console.WriteLine("值类型:{0}", claim.ValueType);
        Console.WriteLine("值:{0}", claim.Value);
        foreach (var prop in claim.Properties)
        {
            Console.WriteLine("	属性:{0} {1}", prop.Key, prop.Value);
        }
        Console.WriteLine();
    }

     

    5、客户端应用程序服务

    代码过长不贴文章里

    服务端源码:Download

    客户端源码:Download

    在运行之前需要注意的是:客户端的app.config要修改 serviceUri的连接位置为服务端运行的连接,例子:源代码中的serviceUri为serviceUri="http://localhost:59514/Role_JSON_Appservice.axd",要修改为你运行网站以后的链接地址(假设为http://localhost:9999/)加Role_JSON_Appservice.axd,最终serviceUri="http://localhost:9999/Role_JSON_Appservice.axd"。

     

    (二)加密

    1、签名

     1 internal static CngKey aliceKeySignature;
     2 internal static byte[] alicePubKeyBlob;
     3 static void Main(string[] args)
     4 {
     5     CreateKeys();
     6  
     7     byte[] aliceData = Encoding.UTF8.GetBytes("Alice");
     8     byte[] aliceSignature = CreateSignatrue(aliceData,aliceKeySignature);
     9  
    10     Console.WriteLine("Alice创建了签名:{0}",Convert.ToBase64String(aliceSignature));
    11  
    12     if (VerifySignature(aliceData,aliceSignature,alicePubKeyBlob))
    13     {
    14         Console.WriteLine("Alice的签名验证成功");
    15     }
    16  
    17     Console.ReadKey();
    18 }
    19  
    20 private static bool VerifySignature(byte[] data, byte[] signature, byte[] pubKey)
    21 {
    22     bool retValue = false;
    23     using (CngKey key = CngKey.Import(pubKey, CngKeyBlobFormat.GenericPublicBlob))
    24     using (var signingAlg =new ECDsaCng(key))
    25     {
    26         retValue = signingAlg.VerifyData(data, signature);
    27         signingAlg.Clear();
    28     }
    29     return retValue;
    30 }
    31  
    32 private static byte[] CreateSignatrue(byte[] data, CngKey key)
    33 {
    34     byte[] signature;
    35     using (var signingAlg=new ECDsaCng(key))
    36     {
    37         signature = signingAlg.SignData(data);
    38         signingAlg.Clear();
    39     }
    40     return signature;
    41 }
    42 
    43  
    44 private static void CreateKeys()
    45 {
    46     aliceKeySignature = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
    47     alicePubKeyBlob = aliceKeySignature.Export(CngKeyBlobFormat.GenericPublicBlob);
    48 }

     

     

    2、交换秘钥和安全传输

    使用DiffieHellman算法交换一个对称秘钥,以进行安全的传输。

     

    (三)资源的访问控制

    在操作系统中,资源都使用访问控制列表(ACL)来保护。资源有一个关联的安全描述符。安全描述符包含了资源拥有者的信息,并引用了两个访问控制列表:自由访问控制列表(DACL,确定谁拥有访问权)和系统访问控制列表(SACL,确定安全事件日志的审核规则)。ACL包含一个访问控制项(ACE,包含类型、安全标识符和权限)列表。在DACL中,ACE的类型可以是允许访问或拒绝访问。可以用文件设置和获得的权限是创建、读取、写入、删除、修改、改变许可和获得许可。

    获取一个文件的访问控制列表:

    static void Main(string[] args)
    {
        string fileName = @"C:UsersAdministratorDesktop1.txt";
        using (FileStream fs=File.Open(fileName,FileMode.Open))
        {
            FileSecurity securityDescriptor = fs.GetAccessControl();
            AuthorizationRuleCollection rules = securityDescriptor.GetAccessRules(true, true, typeof(NTAccount));
     
            foreach (AuthorizationRule rule in rules)
            {
                var fileRule = rule as FileSystemAccessRule;
                Console.WriteLine("访问类型:{0}",fileRule.AccessControlType);
                Console.WriteLine("权限:{0}",fileRule.FileSystemRights);
                Console.WriteLine("身份:{0}",fileRule.IdentityReference.Value);
                Console.WriteLine();
            }
        }
    }

     

    修改访问权限参考:http://www.cnblogs.com/wolf-sun/p/4591734.html

     

     

    (五)代码访问安全性

    在基于角色的安全性中,可以定义用户允许做什么。在基于代码的安全性中,可以规定代码能做什么。

    1、第2级安全透明性

    使用SecurityRules特性注解程序集,并设置SecurityRuleSet.Level2,以应用.NET4新增的级别。

    [assembly: SecurityRules(SecurityRuleSet.Level2)]

     

    2、权限

    如果代码运行在沙盒中,沙盒就可以定义.NET权限,以定义代码允许执行的操作。权限是允许(或禁止)每个代码组执行的动作(例:读取文件系统中的文件)。.NET权限独立于操作系统权限。.NET权限仅由CLR验证。

     

    (1)权限集

    权限集是权限的集合。

     

    (2)通过编程要求权限

    程序集可以用声明或编程的方式要求权限。

     

    (3)使用沙盒API包含未授权的代码

     

     

    (五)使用证书发布代码

    可以利用数字证书来对程序集进行签名,让软件的消费者验证软件发布者的身份。

  • 相关阅读:
    Nginx+Lua学习笔记-环境搭建
    Scala学习笔记-Servlet环境搭建
    Scala学习笔记-环境搭建以及简单语法
    Python v3.4 not found的解决方法
    【闲聊】最近一段时间的总结
    javassist初接触
    java调用cmd
    Flexpaper初接触
    Derby初接触
    LVS Keepalived 集群
  • 原文地址:https://www.cnblogs.com/dlxh/p/6792500.html
Copyright © 2011-2022 走看看