我发现很奇怪我能够在我公司的Exchange 2010服务器上使用在我的XP机器上运行的asp.net 4.0 Web应用程序在我的日历中创建约会,这甚至不是域的一部分!但是当我上传它时代码到我们公司的 生产环境 Web应用程序服务器(与Exchange服务器不同),然后我得到如下错误:
System.Net.WebException:远程服务器返回错误:(401)未经授权
我一直在使用Window的身份验证 . 使用 service.UseDefaultCredentials = true ;我无法为将要使用此应用程序的每位员工使用用户名/ paasword . 我认为 生产环境 Web应用程序服务器(Windows 2008 m / c)存在一些问题(权限/权限/禁用模拟)问题 . 我甚至通过选择它可能运行的所有内置帐户,但在IIS 7中使用应用程序池标识,但同样的错误 . 在调用 Appointment.Save() 之前,我可以清楚地看到它在我的Windows帐户下运行 . 我简要冒充使用登录用户's credentials and then removing the impersonation. I saw this technique elsewhere. But that doesn' t也有任何不同 .
这些是代码文件:
Default.aspx.cs
//(在标记页面Default.aspx中没有进行任何操作 . 因此不包括)
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Exchange.WebServices.Autodiscover;
using System.Web.Configuration;
namespace TestExchangeWebServices
{
public partial class _Default : System.Web.UI.Page
{
protected ExchangeService service;
protected void Page_Load(object sender, EventArgs e)
{
service = new ExchangeService(ExchangeVersion.Exchange2010);
service.UseDefaultCredentials = true;
service.Url = new Uri(WebConfigurationManager.AppSettings["EWSURL"]);
SetAppointment("Test", DateTime.Now, "Test");
}
public void SetAppointment(string Subject, DateTime AptDateTime, string Body)
{
Appointment apt = new Appointment(service);
apt.Subject = Subject;
apt.Body = Body;
apt.Body.BodyType = BodyType.HTML;
apt.Start = AptDateTime;
apt.End = apt.Start.AddMinutes(30.00);
apt.ReminderMinutesBeforeStart = 15;
apt.IsReminderSet = true;
HttpContext.Current.Trace.Write("Before Impersonation: System.Security.Principal.WindowsIdentity.GetCurrent().Name = " + System.Security.Principal.WindowsIdentity.GetCurrent().Name );
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = ((System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity).Impersonate();// //System.Threading.Thread.CurrentPrincipal.Identity
HttpContext.Current.Trace.Write("Before Saving Appointment. System.Security.Principal.WindowsIdentity.GetCurrent().Name = " + System.Security.Principal.WindowsIdentity.GetCurrent().Name);
//This is where the call is made and error occurs
apt.Save(SendInvitationsMode.SendToNone);
HttpContext.Current.Trace.Write("After Saving Appointment.");
impersonationContext.Undo();
}
}
}
Web.Config
<?xml version="1.0"?>
<configuration>
<appSettings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>0Sw7QiYFKoD65nCXfakXUhJrjapk4uyQ9u6aPBStxB1XBIIPtXbuZJZb/GyMxgl7Gi3sqIkoq66BKa+MSzjAkpkIfnZmOhMNVomKofC3rlEf9NeIAdCEvjcmENhfGyA6aEJj96mGDxRDBE/FP1iQ8Z3x8Rob+HG1sbD0YJy2rpA=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>HmmlAzyuedvlQ/+grwRKjTs5Z7sg5dYShHFYsFcI0q2ugkZ7oYYNTTEycyqzKyXmaaqwyE2lAsApApSvT+JDys021+sMrqLrF37xAkjRimKbPTylgznRZLQx2qKAZstb6qIis2mcLykgURtp2ytfoPl83jJzEU1y6PtB0loB/p4=</CipherValue>
</CipherData>
</EncryptedData>
</appSettings>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<identity impersonate="false"/>
<customErrors mode="Off"></customErrors>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows">
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpErrors errorMode="Detailed" />
<asp scriptErrorSentToBrowser="true"/>
</system.webServer>
</configuration>
1 回答
Configuring Exchange Impersonation之后解决了
和Impersonate a Specific User in Code
代码的完整解决方案在这里:http://social.msdn.microsoft.com/Forums/exchange/en-US/91f37df3-1372-41b5-ae33-a4bac2a699b7/exchange-web-service-managed-api-not-authorizing?forum=exchangesvrdevelopment#67186bcc-0d73-431b-8aa2-8efe47e5e4a4