Usuário com melhor resposta
autorização wcf

Pergunta
-
Estou com um problema de autorização utilizando o wcf.
Tenho um serviço wcf utilizando a seguinte configuração:<system.serviceModel>
<services>
<service name="bjbs.fwk.wcf.servicos.FwkServiceFactory" behaviorConfiguration="FwkServiceFactoryBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:30000/FwkServiceFactory/fwkservice" />
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" bindingConfiguration="FwkBinding" contract="bjbs.fwk.wcf.interfaces.IFwkServiceFactory" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="FwkBinding">
<security mode="Transport" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="FwkServiceFactoryBehavior">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
<serviceCredentials>
<windowsAuthentication allowAnonymousLogons="false" includeWindowsGroups="true" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Eu gostaria que os clientes deste serviço utilizassem uma credencial do tipo Windows para se autenticar e fossem autorizados por um grupo de acesso do AD.
A parte da autenticação parece estar ok. Porém quando se trata da autorização, na estação de desenvolvimento ok, mas no servidor W2003 só me retorna Access is denied.
A assinatura dos métodos do contrato estão da seguinte forma:
[PrincipalPermission(SecurityAction.Demand, Role = @"dominio\grupo")]
public DataSet ExecSyncDataSet()
Alguém saberia o motivo pelo qual o serviço não faz a autorização no servidor?
Respostas
-
Boas Afonso,
O que faz dentro do método (operação)? Já tentou ligar o trace para ver exatamente o que está havendo?
http://www.israelaece.com- Sugerido como Resposta Israel AeceModerator quarta-feira, 27 de janeiro de 2010 18:44
- Marcado como Resposta Afonso.Costa quarta-feira, 27 de janeiro de 2010 21:02
Todas as Respostas
-
Boas Afonso,
Tente fazer o impersonation:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
[PrincipalPermission(SecurityAction.Demand, Role = @"dominio\grupo")]
public DataSet ExecSyncDataSet() { }
http://www.israelaece.com -
Eu tentei, agora mesmo na estação de desenvolvimento está retornando o erro: "Attempted to perform an unauthorized operation."
No lado cliente estou passando as credenciais da seguinte forma:
InstanceContext myContext = new InstanceContext(new FwkServiceFactoryCallBack());
ChannelFactory<ServiceReference1.IFwkServiceFactory> myChannelFactory = new DuplexChannelFactory<ServiceReference1.IFwkServiceFactory>( myContext, "NetTcpBinding_IFwkServiceFactory");
myChannelFactory.Credentials.Windows.ClientCredential.Domain =
"dominio";
myChannelFactory.Credentials.Windows.ClientCredential.UserName =
"usuario";
myChannelFactory.Credentials.Windows.ClientCredential.Password =
"senha";
ServiceReference1.
IFwkServiceFactory proxy = myChannelFactory.CreateChannel();
Obrigado,
Afonso Costa -
Boas Afonso,
Tente definir o atributo clientCredentialType para Windows na configuração do serviço e do cliente:
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
Teoricamente você não precisa definir as credenciais através da factory, pois ele automaticamente pegará o usuário logado naquele momento.
http://www.israelaece.com -
Criei a mesma configuração para o cliente e o serviço conforme descrito acima, mas mesmo desta forma não funcionou. O erro permaneceu o mesmo.
Quando eu tiro a opção do impersonation, ao menos na estação de desenvolvimento funciona corretamente.
O que eu não consigo entender é pq o serviço tem comportamento diferente no servidor windows 2003. Deveria funcionar da mesma forma já que o serviço foi instalado na estação de desenvolvimento.
Obrigado,
Afonso C. A. Costa -
Boas Afonso,
Me passa a stack trace completa.
Onde você está hospedando o serviço em um Windows Service? Na sua estação de desenvolvimento funciona, mas lá está autenticando no AD ou somente no Windows local? E está consumindo esse serviço a partir de que tipo de aplicação Windows/Web?
http://www.israelaece.com -
Israel, em primeiro lugar agradeço sua atenção.
Seguem os dados:
O serviço está hospedado no windows service com uma conta de usuário específica.
Na estação de desnvolvimento funciona sem o impersonation e está validadndo no AD (dominio\grupo).
O serviço está sendo consumido por um componente que está sendo instanciado por uma aplicação windows.
app.config do cliente:
<?xml version="1.0" encoding="utf-8" ?><
configuration>
<
system.web>
<
compilation debug="true"/>
</
system.web>
<
connectionStrings>
<
add name="framework_infra" connectionString="Server=server;Database=FWK_INFRA;Trusted_Connection=True" providerName="System.Data.SqlClient"/>
</
connectionStrings>
<
appSettings>
<
add key="numTentativas" value="3"/>
<
add key="NivelLog" value="0"/>
<
add key="TipoSaida" value="2"/>
<
add key="ArquivoSaida" value="LogFile.txt"/>
<
add key="PadraoSaida" value="data tipo guid contexto"/>
</
appSettings>
<
system.serviceModel>
<
bindings>
<
netTcpBinding>
<
binding name="NetTcpBinding_IFwkServiceFactory" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<
readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<
reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<
security mode="Transport">
<
transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<
message clientCredentialType="Windows" />
</
security>
</
binding>
</
netTcpBinding>
</
bindings>
<
client>
<
endpoint address="net.tcp://serverW2003:30000/FwkServiceFactory/fwkservice"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IFwkServiceFactory"
contract="ServiceReference1.IFwkServiceFactory" name="NetTcpBinding_IFwkServiceFactory">
<
identity>
<
userPrincipalName value=user@domain.ad />
</
identity>
</
endpoint>
</
client>
</
system.serviceModel>
</
configuration>
Contrato do serviço:
[ServiceContract(Namespace = "http://Bjbs.Fwk.Infra.Servicos",CallbackContract=typeof(IFwkServiceFactoryCallBack),SessionMode=
SessionMode.Required,ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign)]
public interface IFwkServiceFactory
{
[
OperationContract]
[
FaultContract(typeof(bjbs.fwk.wcf.falhas.FaltaServicoBN))]
DataSet ExecSyncDataSet(string pServico,string pBarramentoServico, string pUsuario,string pHashSenha, string pXmlArgs);
}
Classe de implementação:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]public class FwkServiceFactory : IFwkServiceFactory
{
[
PrincipalPermission(SecurityAction.Demand, Role = @"domain\group")]
public DataSet ExecSyncDataSet(string pServico, string pBarramentoServico, string pUsuario, string pHashSenha, string pXmlArgs){ }
}
Dados do erro:
Mensagem: Access is denied.Server stack trace:
em System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
em System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
em System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
em System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
em System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
em System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)Exception rethrown at [0]:
em System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
em System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
em bjbs.fwk.wcf.proxy.ServiceReference1.IFwkServiceFactory.ExecSyncDataSet(String pServico, String pBarramentoServico, String pUsuario, String pHashSenha, String pXmlArgs)
em bjbs.fwk.wcf.proxy.ServicosPXY.Executar(eTipoExecucao pTipoExecucao) na C:\Projetos\Teste\bjbs.fwk.wcf.proxy\bjbs.fwk.wcf.proxy\ServicosPXY.cs:linha 124
Grato,
Afonso C. A. Costa -
Boas Afonso,
O que faz dentro do método (operação)? Já tentou ligar o trace para ver exatamente o que está havendo?
http://www.israelaece.com- Sugerido como Resposta Israel AeceModerator quarta-feira, 27 de janeiro de 2010 18:44
- Marcado como Resposta Afonso.Costa quarta-feira, 27 de janeiro de 2010 21:02
-
Putz, não acredito que não me atentei para isso. Na verdade o serviço estava autorizando e tomava erro em outro em um reflection que fazia no corpo do método.
Agradeço muito a ajuda e peço desculpas por não ter visto isso.
É duro ficar com uma idéia fixa.
Grato,
Afonso C. A. Costa