第一范文网 - 专业文章范例文档资料分享平台

OAuth2学习及DotNetOpenAuth部分源码研究

来源:用户分享 时间:2025/9/12 17:28:23 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

y] = result = newDescription; } } } return result; } internal MessageDescription Get(IMessage message); internal MessageDictionary GetAccessor(IMessage message); internal MessageDictionary GetAccessor(IMessage message, bool getOriginalValues) }

可以看到,类内部有个字典,所有新建的MessageDescription对象实例都会被加入其中.而每次从中获取描述时,如果当前不存在,就会新建一个并返回.

为了能够在元数据层面操作对象,作者引入了MessageDictionary类

internalclass MessageDictionary : IDictionary { privatereadonly IMessage message; privatereadonly MessageDescription description; privatereadonlybool getOriginalValues; internal MessageDictionary(IMessage message, MessageDescription description, bool getOriginalValues) { this.message = message; this.description = description; this.getOriginalValues = getOriginalValues; } publicvoid Add(string key, string value) { MessagePart part; if (this.description.Mapping.TryGetValue(key, out part)) { if (part.IsNondefaultValueSet(this.message)) { thrownew ArgumentException(MessagingStrings.KeyAlreadyExists); } part.SetValue(this.message, value); } else { this.message.ExtraData.Add(key, value); } } }

可以看到,每一个MessageDictionary类实例都与一个IMessage对象实例和一个MessageDescription对象实例关联,在构造函数中传入.对MessageDictionary的操作就是对IMessage的操作.

比如上面所举的Add方法,首先去MessageDescription处获取名为key的MessagePart对象.如果获取不到,说明要么IMessage对象没有此属性或字段,要么没有标记MessagePartAttribute特性导致没有对应的MessagePart描述对象.于是将其存于ExtraData属性中.此属性是IDictionary类型.如果获取到了,则查看IMessage对象的此成员当前是否是默认值,如果不是默认值,则说明之前已赋过值,现在属于重复赋值,于是抛出异常,否则使用MessagePart对象的SetValue方法对其赋值.这里的赋值就用到了上面提的映射器.

最后,使用MessageSerializer类将MessageDictionary类实例序列化成IDictionary,或将IDictionary反序列化成MessageDictionary

internalclass MessageSerializer { privatereadonly Type messageType; private MessageSerializer(Type messageType) { this.messageType = messageType; } internalstatic MessageSerializer Get(Type messageType) { returnnew MessageSerializer(messageType); } internal IDictionary Serialize(MessageDictionary messageDictionary) { var result = new Dictionary(); foreach (var pair in messageDictionary) { MessagePart partDescription; if (messageDictionary.Description.Mapping.TryGetValue(pair.Key, out partDescription)) { Contract.Assume(partDescription != null); if (partDescription.IsRequired || partDescription.IsNondefaultValueSet(messageDictionary.Message)) { result.Add(pair.Key, pair.Value); } } else { // This is extra data. We always write it out.result.Add(pair.Key, pair.Value); } } return result; } internalvoid Deserialize(IDictionary fields, MessageDictionary messageDictionary) { foreach (var pair in fields) { messageDictionary[pair.Key] = pair.Value; } } }

对于序列化,直接遍历MessageDictionary类,将必填成员,非默认值成员和非MessageDescription类描述的成员都取出来,组装成Dictionary返回.对于反序列化,则是遍历IDictionary,将值取出装入MessageDictionary类并返回. 最后再来研究SerializeCore方法与DeserializeCore方法 SerializeCore方法如下

protectedoverridebyte[] SerializeCore(T message) { var fields = MessageSerializer.Get(message.GetType()).Serialize(MessageDescriptions.GetAccessor(message)); string value = MessagingUtilities.CreateQueryString(fields); return Encoding.UTF8.GetBytes(value); }

第一行,将信息通过上面所述的方式序列化成IDictionary类型,然后将其转换成QueryString字符串

internalstaticstring CreateQueryString(IEnumerable> args) { StringBuilder sb = new StringBuilder(args.Count() * 10); foreach (var p in args) { sb.Append(EscapeUriDataStringRfc3986(p.Key)); sb.Append('='); sb.Append(EscapeUriDataStringRfc3986(p.Value)); sb.Append('&'); } sb.Length--; // remove trailing &return sb.ToString(); }

可以看到,很简单,就是遍历字值对拼接字符串,,最后使用Utf8进行二进制编码后返回. DeserializeCore方法如下

protectedoverridevoid DeserializeCore(T message, byte[] data) { string value = Encoding.UTF8.GetString(data); // Deserialize into message newly created instance.var serializer = MessageSerializer.Get

(message.GetType()); var fields = MessageDescriptions.GetAccessor(message); serializer.Deserialize(HttpUtility.ParseQueryString(value).ToDictionary(), fields); }

首先将二进制流转换成Utf8编码的字符串,然后将此串转换成QueryString字符串,然后再次转换成IDictionary字典 internalstatic Dictionary ToDictionary(this NameValueCollection nvc) { return ToDictionary(nvc, false); } internalstatic Dictionary ToDictionary(this NameValueCollection nvc, bool throwOnNullKey) { var dictionary = new Dictionary(); foreach (string key in nvc) { dictionary.Add(key, nvc[key]); } return dictionary; } 最后反序列化入指定类型的MessageDescriptions类中并返回.

3.资源服务端

在.Net中,有两个类别的体系来保证安全,通过代码访问安全,使代码可以根据它所来自的位置以及代码标识的其他方面,获得不同等级的受信度,减小恶意代码或包含错误的代码执行的可能性,来保证二进制层面的执行安全.比如在沙箱中运行的程序,就是部分信任程序,比如无法操作本地硬盘文件.通过基于角色的安全,使代码判定当前用户是谁以及拥有的角色,获取不同的权限,来保证业务安全.DotNetOpenAuth框架使用的是后者. 参考:

.NET(C#):不同级别的安全透明代码对类型的影响 .NET中非对称加密RSA算法的密钥保存

搜索更多关于: OAuth2学习及DotNetOpenAuth部分源码研究 的文档
OAuth2学习及DotNetOpenAuth部分源码研究.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c784pk0utkd1od1e2lz3j_11.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top