Sobre as tecnologias de aplicação e operação:
Linguagem de programação: C#
Lado FrontEnd: Windows Presentation Foundation (WPF) - .NET Framework 4.6.1
Lado BackEnd: Windows Communication Foundation (WCF) - .NET Framework 4.6.1
Restaure os pacotes necessários no projeto selecionado, execute o seguinte comando no PM Console
Update-Package -reinstall
Nesta aplicação, vou mostrar como usar autorização e autenticação usando um serviço WCF nos padrões do Enterprise Architecting.
WCF
Serviço de autenticação ASP.NET
Autenticação personalizada
Cookies HTTP
Atributo PrincipalPermission de autorização
Tópico CurrentPrincipal
Interceptadores de mensagens
Crie um aplicativo de serviço WCF.
Adicione um AuthenticationService.svc reutilizando o serviço de autenticação ASP.NET.
Crie a classe Validador de Usuário.
Habilite a autenticação personalizada em Global.asax.
Retorne o cookie se for um usuário válido.
Modifique a configuração do serviço.
Crie um ExecuteOperationsService.svc com três métodos diferentes chamados SumOperation, ReadOperation e WriteOperation.
Decore métodos de serviço com atributo PrincipalPermission somente para acesso autorizado.
Decore a classe ExecuteOperationsService com o atributo AspNetCompatibilityRequirements.
Implemente interceptores no aplicativo de servidor.
Implemente o código de configuração de identidade para interceptadores no aplicativo de serviço.
Modifique o código do lado do serviço para incluir Função em vez de Nome.
Use ticket criptografado para armazenar nomes de usuário e funções.
Crie o Aplicativo Cliente e adicione referências a ambos os serviços.
Implemente interceptores na aplicação cliente.
Crie uma instância do Authentication Service e invoque o método Login().
Receba o cookie e armazene-o.
Crie uma instância ExecuteOperationsService e invoque SumOperation, ReadOperation e WriteOperation.
Anexe o cookie ao cliente ExecuteOperationsService
1. Adicione um AuthenticationService.svc reutilizando o serviço de autenticação ASP.NET.
Adicione um novo serviço WCF e nomeie-o como AuthenticationService.svc. Exclua os arquivos associados, pois iremos expor o serviço de autenticação ASP.NET.
Excluir AuthenticationService.cs
Excluir IAuthenticationService.cs
<%@ ServiceHost Language="C#" Service="System.Web.ApplicationServices.AuthenticationService" Factory="System.Web.ApplicationServices.ApplicationServicesHostFactory" %>
2. Habilite a autenticação personalizada em Global.asax e retorne um cookie se for um usuário válido.
Adicione um novo item Web > Global Application Class ao projeto.
protegido void Application_Start (objeto remetente, EventArgs e) { AuthenticationService.Authenticating += AuthenticationService_Authenticating; }
private void AuthenticationService_Authenticating (remetente do objeto, AuthenticatingEventArgs e) { string role = string.Empty; e.Authenticated = UserIsValid(e, funções de referência); e.AuthenticationIsComplete = verdadeiro; if (e.Authenticated) { string criptografadoValue = FormsAuthentication.Encrypt(CreateFormsAuthenticationTicket(e, funções)); OperationContext.Current.OutgoingMessageProperties[HttpResponseMessageProperty.Name] = SetSetCookieInResponseChannelHeaders(encryptedValue); } }
O método extrai o nome de usuário e a senha do objeto Credencial personalizada do argumento do evento de autenticação. Em seguida, valida o nome de usuário e a senha com nossa classe UserValidator.
A propriedade Authenticated representa verdadeiro/falso se um usuário é válido ou não respectivamente.
3. Habilite o serviço de autenticação e compatibilidade com ASP.NET
Agora precisamos modificar o arquivo web.config para incluir o seguinte:
Habilitar serviço de autenticação
Habilitar compatibilidade com ASP.NET
<system.web.extensões> <script> <serviçosweb> <authenticationService habilitado="true"/> </webServices> </script> </system.web.extensions>
4. Implementar interceptores na aplicação do servidor.
Isso ocorre porque o código acima de anexar um cookie ao Contexto de Operação parece ser uma tarefa tediosa toda vez que precisamos fazer uma chamada de serviço. Podemos mover essas tarefas para segundo plano usando interceptadores WCF.
MSDN: WCF Data Services permite que um aplicativo intercepte mensagens de solicitação para que você possa adicionar lógica personalizada a uma operação. Você pode usar essa lógica customizada para validar dados em mensagens recebidas. Você também pode usá-lo para restringir ainda mais o escopo de uma solicitação de consulta, como inserir uma política de autorização personalizada por solicitação.
A seguir estão as atividades envolvidas nesta etapa.
Adicione o comportamento do interceptador dentro do servidor web.config.
Crie a classe Comportamento do Interceptor. (Veja no projeto)
Crie a classe IdentityMessageInspector . (Veja no projeto)
<system.serviceModel> <serviços> <service name="AuthenticationAndAuthorization.ExecuteOperationsService" behaviorConfiguration="InterceptorBehavior" /> </serviços> <comportamentos> <comportamentos de serviço> <comportamento> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> <nome do comportamento="InterceptorBehavior"> <serviceDebug includeExceptionDetailInFaults="true" /> <interceptorBehaviorExtension /> </behavior> </serviceBehaviors> </comportamentos> <extensões> <comportamentoExtensões> <add name="interceptorBehaviorExtension" type="AuthenticationAndAuthorization.Extensions.IDispatchMessageInspector.InterceptorBehaviorExtension, AuthenticationAndAuthorization, Versão=1.0.0.0, Culture=neutral"/> </behaviorExtensions> </extensões> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel>
5. Criptografia de cookies.
Nosso cookie contém informações que podem ser facilmente lidas por utilitários de exame HTTP como o Fiddler. Isso torna as informações do cookie sujeitas a ameaças à segurança.
FormsAuthenticationTicket : O namespace System.Web.Security fornece uma classe conveniente para nós. Podemos armazenar as informações de nome de usuário e funções dentro desta instância de classe. A classe de ticket também fornece recursos de expiração e criptografia.
private FormsAuthenticationTicket CreateFormsAuthenticationTicket(AuthenticatingEventArgs e, string role) => new FormsAuthenticationTicket(1, e.UserName, DateTime.Now, DateTime.Now.AddHours(24), true, role, FormsAuthentication.FormsCookiePath);
string criptografadaValue = FormsAuthentication.Encrypt(CreateFormsAuthenticationTicket(e, funções)); private FormsAuthenticationTicket GetDecryptTicket(string criptografadaTicket) => FormsAuthentication.Decrypt(encryptedTicket);
private HttpResponseMessageProperty SetSetCookieInResponseChannelHeaders(string cookieValue) { resposta HttpResponseMessageProperty = new HttpResponseMessageProperty(); resposta.Headers[HttpResponseHeader.SetCookie] = FormsAuthentication.FormsCookieName + "=" + cookieValue; resposta de retorno; }
<modo de autenticação="Formulários"> <forms slideExpiration="true" name="AuthCookie" proteção="All" timeout="20"/> </autenticação> <machineKey descriptografia = "AES" validação = "SHA1" decryptionKey = "1523F567EE75F7FB5AC0AC4D79E1D9F25430E3E2F1BCDD3370BCFC4EFC97A541" validaçãoKey="33CBA563F26041EE5B5FE9581076C40618DCC1218F5F447634EDE8624508A129"/>
6. Implementar interceptores na aplicação cliente.
A seguir estão as atividades envolvidas nesta etapa.
Adicionar comportamento do interceptor dentro do Client App.config
Crie a classe Comportamento do Interceptor. (Veja no projeto)
Crie a classe CookieMessageInspector . (Veja no projeto)
<comportamentos> <endpointBehaviors> <nome do comportamento ="InterceptorBehavior"> <interceptorBehaviorExtension /> </behavior> </endpointBehaviors> </comportamentos>
<endpoint address="http://localhost:8046/ExecuteOperationsService.svc" binding="basicHttpBinding" bindConfiguration="BasicHttpBinding_IExecuteOperationsService" contract="ExecuteOperationsServiceReference.IExecuteOperationsService" name="BasicHttpBinding_IExecuteOperationsService" behaviorConfiguration="InterceptorBehavior"/>