关于应用技术及操作:
编程语言:C#
前端端:Windows Presentation Foundation (WPF) - .NET Framework 4.6.1
后端:Windows Communication Foundation (WCF) - .NET Framework 4.6.1
恢复所选项目上必要的包,在PM 控制台中运行以下命令
Update-Package -reinstall
在此应用程序中,我将展示如何在企业架构标准中使用 WCF 服务来使用授权和身份验证。
世界碳纤维
ASP.NET 身份验证服务
自定义认证
HTTP Cookie
授权主体权限属性
线程 CurrentPrincipal
消息拦截器
创建 WCF 服务应用程序。
添加重用 ASP.NET 身份验证服务的 AuthenticationService.svc。
创建用户验证器类。
在 Global.asax 中启用自定义身份验证。
如果用户有效则返回 Cookie。
修改服务配置。
使用名为 SumOperation、ReadOperation 和 WriteOperation 的三个不同方法创建 ExecuteOperationsService.svc。
使用PrincipalPermission 属性装饰服务方法,仅用于授权访问。
使用 AspNetCompatibilityRequirements 属性装饰 ExecuteOperationsService 类。
在服务器应用程序中实现拦截器。
在服务应用程序中对拦截器实施身份设置代码。
修改服务端代码以包含角色而不是名称。
使用加密票证来存储用户名和角色。
创建客户端应用程序并添加对这两个服务的引用。
在客户端应用程序中实现拦截器。
创建身份验证服务实例并调用 Login() 方法。
接收cookie并存储它。
创建一个 ExecuteOperationsService 实例并调用 SumOperation、ReadOperation 和 WriteOperation。
将 Cookie 附加到 ExecuteOperationsService 客户端
1. 添加重用 ASP.NET 身份验证服务的 AuthenticationService.svc。
添加新的 WCF 服务并将其命名为 AuthenticationService.svc。删除关联的文件,因为我们将公开 ASP.NET 身份验证服务。
删除AuthenticationService.cs
删除IAuthenticationService.cs
<%@ ServiceHost Language="C#" Service="System.Web.ApplicationServices.AuthenticationService" Factory="System.Web.ApplicationServices.ApplicationServicesHostFactory" %>
2. 在 Global.asax 中启用自定义身份验证,如果用户有效,则返回 Cookie。
将新项目 Web > Global Application Class添加到项目中。
protected void Application_Start(object sender, EventArgs e) { AuthenticationService.Authenticating += AuthenticationService_Authenticating; }
私人无效AuthenticationService_Authenticating(对象发送者,AuthenticatingEventArgs e){字符串角色= string.Empty; e.Authenticated = UserIsValid(e, ref 角色); e.AuthenticationIsComplete = true; 如果(e.Authenticated){ 字符串加密值 = FormsAuthentication.Encrypt(CreateFormsAuthenticationTicket(e,角色)); OperationContext.Current.OutgoingMessageProperties[HttpResponseMessageProperty.Name] = SetSetCookieInResponseChannelHeaders(encryptedValue); } }
该方法从身份验证事件参数的自定义凭据对象中提取用户名和密码。然后它使用我们的 UserValidator 类验证用户名和密码。
如果用户有效,则属性 Authenticated 分别表示 true / false。
3. 启用身份验证服务和 ASP.NET 兼容性
现在我们需要修改 web.config 文件以包含以下内容:
启用身份验证服务
启用 ASP.NET 兼容性
<系统.web.扩展> <脚本> <网络服务> <authenticationService启用=“true”/> </网络服务> </脚本> </system.web.extensions>
4. 在服务器应用程序中实现拦截器。
这是因为每次我们需要进行服务调用时,将 cookie 附加到操作上下文的上述代码似乎是一项乏味的工作。我们可以使用 WCF 拦截器将这些任务移至后台。
MSDN:WCF 数据服务使应用程序能够拦截请求消息,以便您可以向操作添加自定义逻辑。您可以使用此自定义逻辑来验证传入消息中的数据。您还可以使用它来进一步限制查询请求的范围,例如针对每个请求插入自定义授权策略。
以下是此步骤涉及的活动。
在服务器 web.config 中添加拦截器行为。
创建拦截器行为类。 (见项目)
创建IdentityMessageInspector类。 (见项目)
<系统.服务模型> <服务> <服务名称=“AuthenticationAndAuthorization.ExecuteOperationsService”behaviorConfiguration=“InterceptorBehavior”/> </服务> <行为> <服务行为> <行为> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults =“true”/> </行为> <行为名称=“InterceptorBehavior”> <serviceDebug includeExceptionDetailInFaults =“true”/> <拦截器行为扩展/> </行为> </服务行为> </行为> <扩展名> <行为扩展> <添加名称=“interceptorBehaviorExtension”类型=“AuthenticationAndAuthorization.Extensions.IDispatchMessageInspector.InterceptorBehaviorExtension,AuthenticationAndAuthorization,版本= 1.0.0.0,文化=中性”/> </行为扩展> </扩展名> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel>
5. Cookie 加密。
我们的 cookie 包含可由 HTTP 检查实用程序(如 Fiddler)轻松读取的信息。这使得cookie信息容易受到安全威胁。
FormsAuthenticationTicket :System.Web.Security 命名空间为我们提供了一个方便的类。我们可以将用户名和角色信息存储在此类实例中。票证类别还提供过期和加密设施。
私人FormsAuthenticationTicket CreateFormsAuthenticationTicket(AuthenticatingEventArgs e,字符串角色)=>新FormsAuthenticationTicket(1,e.UserName,DateTime.Now,DateTime.Now.AddHours(24),true,角色,FormsAuthentication.FormsCookiePath);
字符串加密值 = FormsAuthentication.Encrypt(CreateFormsAuthenticationTicket(e, 角色));私人 FormsAuthenticationTicket GetDecryptTicket(string cryptoTicket) => FormsAuthentication.Decrypt(encryptedTicket);
私有 HttpResponseMessageProperty SetSetCookieInResponseChannelHeaders(string cookieValue) { HttpResponseMessageProperty 响应 = new HttpResponseMessageProperty(); response.Headers[HttpResponseHeader.SetCookie] = FormsAuthentication.FormsCookieName + "=" + cookieValue; 返回响应; }
<身份验证模式=“表单”> <forms movingExpiration="true" name="AuthCookie"protection="All" timeout="20"/> </认证> <machineKey解密=“AES”验证=“SHA1”解密Key=“1523F567EE75F7FB5AC0AC4D79E1D9F25430E3E2F1BCDD3370BCFC4EFC97A541” validationKey="33CBA563F26041EE5B5FE9581076C40618DCC1218F5F447634EDE8624508A129"/>
6. 在客户端应用程序中实现拦截器。
以下是此步骤涉及的活动。
在 Client App.config 中添加拦截器行为
创建拦截器行为类。 (见项目)
创建CookieMessageInspector类。 (见项目)
<行为> <端点行为> <行为名称=“InterceptorBehavior”> <拦截器行为扩展/> </行为> </端点行为> </行为>
<端点地址=“http://localhost:8046/ExecuteOperationsService.svc”绑定=“basicHttpBinding”绑定配置=“BasicHttpBinding_IExecuteOperationsService”契约=“ExecuteOperationsServiceReference.IExecuteOperationsService”名称=“BasicHttpBinding_IExecuteOperationsService”behaviorConfiguration=“InterceptorBehavior”/>