Hi,
I work on a WCF service to manage groups members from an ASP.NET MVC web application hosted on IIS webserver with Windows Authentification enabled. Like that :
Client (web browser) -> Website (ASP.NET MVC 5) -> Webservice WCF -> AD
Users are connected successfully to the service with their identity but they can't change groups membership, Save() method of GroupPrincipal class returns "Access is denied" Exception.
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at GHESPAR_WEB.ServiceAPI.IGhesparService.AddMembersToGroup(String groupName, String[] users)
at GHESPAR_WEB.ServiceAPI.GhesparServiceClient.AddMembersToGroup(String groupName, String[] users)
at GHESPAR_WEB.Controllers.HomeController.AddUsersToGroup(String groupName, String[] users)
At the same time, user can update membership list without any problem with RSAT, so it isn't a "simple" permission issue.
The website works well on my computer with IIS Express and Visual Studio, with same AD and my Windows account. When I try with production server, access is denied too. So IIS is probably misconfigured or maybe my webservices.
Source code :
AddMembersToGroup() Method in WCF service :
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public void AddMembersToGroup(string groupName, string[] users)
{
string identity = ServiceSecurityContext.Current.WindowsIdentity.Name;
string domain = identity.Split('\\')[0];
using (HostingEnvironment.Impersonate())
{
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain))
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(context, groupName);
foreach (var user in users)
{
group.Members.Add(context, IdentityType.Name, user);
}
group.Save(); // <- Access is denied exception
}
}
}
ServiceSecurityContext server side properties values when user is connected seems good.
ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel =
Impersonation
ServiceSecurityContext.Current.WindowsIdentity.IsAuthenticated =
true
ServiceSecurityContext.Current.WindowsIdentity.AuthenticationType =
Negotiate
ServiceSecurityContext.Current.WindowsIdentity.Name = "
DOMAIN\USERNAME" (current connected user)
I have same values with Visual studio debugger on my desktop computer and IIS Express.
AddUsersToGroup() Controller Method in ASP.NET webapp :
[HttpPost]
[Route("addMembersToGroup")]
public ActionResult AddUsersToGroup(string groupName, string[] users)
{
try
{
GhesparServiceClient client = new GhesparServiceClient();
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
client.ChannelFactory.Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
client.AddMembersToGroup(groupName, users);
client.Close();
}
catch (FaultException<Fault> fault)
{
return Json(new { success = false, message = fault.Detail.Message });
}
catch (Exception e)
{
return Json(new { success = false, message = e.Message, trace = e.StackTrace });
}
return Json(new { success = true });
}
Configuration files on production server :
WCF web.config : https://pastebin.com/YCUFSbaY
ASP.NET web.config : https://pastebin.com/6FDPmPXH
IIS configuration on production server :
- I enabled ASP.NET Impersonation, Windows Authentification and disabled Anonymous Authentication for ASP.NET app.
- I enabled Windows Authentification and disabled Anonymous Authentication for WCF app.
- Switch Managed pipeline mode to "classic" and identity to ApplicationPoolIdentity for ASP.NET application pool.
- Switch Managed pipeline mode to "Integrated" and identity to ApplicationPoolIdentity for WCF application pool.
Did I forget something ? :)
Best regards.