我正在开发一个在公司中心运行的Web应用程序。此Web应用程序需要调用服务,该服务是第二个Web应用程序的一部分。
在中央网络应用程序中,我有这段代码;
var clientUri = "http://website.localhost/Services/Info.svc/account";
var uri = new Uri(clientUri);
var networkCredentials = new NetworkCredential(_configuration.ServiceUserName, _configuration.ServicePassword);
var httpClient = new HttpClient();
httpClient.DefaultHeaders.Authorization = Credential.CreateBasic(_configuration.ServiceUserName, _configuration.ServicePassword);
httpClient.TransportSettings.PreAuthenticate = true;
HttpResponseMessage respone = httpClient.Get(uri);
HttpContent content = respone.Content;
在另一个应用程序的Web服务中,即(Info.svc),我在服务的构造函数中有以下代码。
var validator = new UserNamePasswordValidator();
var cred = System.Net.CredentialCache.DefaultCredentials; //this one is empty, maybe a solution?
validator.Validate("Username", "Password");
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
//This throws a 401 unauthorize, which is shown as a 500 error in the central application
throw new WebProtocolException(HttpStatusCode.Unauthorized, "You must be authorized to perform this action.", null);
}
else
{
_userIsAbleToUseService = true;
}
我想使用从其他网络服务发送的网络凭据,而不是验证功能中的用户名和密码,这可以实现吗?如何?欢迎任何其他建议!我现在可以在验证功能中对密码进行编码,但这不是我想要的。
- UPDATE-- 这是中央应用程序的web.config中的配置
<authorization>
<allow roles="administrators"/>
<deny roles="datareaders"/>
<deny users="?"/>
</authorization>
<authentication mode="Forms">
<forms loginUrl="~/Logon/Logon" timeout="2880"/>
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="CentralApplication"/>
</providers>
</membership>
这部分是针对第二个webapplication中的web.config
<authentication mode="Forms">
<forms name="AllPages" loginUrl="~/Logon/" timeout="360" enableCrossAppRedirects="false" />
</authentication>
<authorization>
<!-- NOTE: See Web.config under Private folder for specifics on secure pages. -->
<deny users="?" />
</authorization>
<membership defaultProvider="NHMembershipProvider">
<providers>
<clear />
<add name="NHMembershipProvider" applicationName="Website" type="Website.Security.Authentication.Membership.CmsMembershipProvider" description="Stores and retrieves membership data from SQL server using Nhibernate" connectionStringName="NHibernate" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="NHRoleProvider">
<providers>
<clear />
<add name="NHRoleProvider" applicationName="Website" type="Website.Security.Authentication.Membership.CmsRoleProvider" />
</providers>
</roleManager>
已经使用成员资格提供程序登录到中央应用程序我正在尝试使用简单的超链接从那里调用Web服务(仅适用于此)。中央管理员调用的Web服务收集一些数据并将其发送到第二个应用程序的Web服务的URL。这两个应用程序都是webapplications(包含webservices),这就是为什么身份验证模式设置为Forms。
答案 0 :(得分:0)
花了将近2天,但现在我按照自己的意愿完成了一切。我发现WcfRestContrib允许我通过稍微修改我的webconfig并使用此类中的一些属性来实现对服务的身份验证。我使用服务和控制台应用程序构建了一个快速测试应用程序,并且身份验证工作正常。
我将以下部分添加到我的web.config;
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="webAuthentication" type="WcfRestContrib.ServiceModel.Configuration.WebAuthentication.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
<add name="errorHandler" type="WcfRestContrib.ServiceModel.Configuration.ErrorHandler.BehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
<add name="webErrorHandler" type="WcfRestContrib.ServiceModel.Configuration.WebErrorHandler.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.6.107, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="Rest">
<webAuthentication requireSecureTransport="false" authenticationHandlerType="WcfRestContrib.ServiceModel.Dispatcher.WebBasicAuthenticationHandler, WcfRestContrib" usernamePasswordValidatorType="CMS.Backend.Services.SecurityValidator, CMS.Backend" source="CMS.Backend"/>
<!--<webAuthentication requireSecureTransport="false" authenticationHandlerType="CMS.Backend.Services.WebBasicAuthenticationHandler, CMS.Backend" usernamePasswordValidatorType="CMS.Backend.Services.SecurityValidator, Website.Backend" source="CMS.Backend"/>-->
<errorHandler errorHandlerType="WcfRestContrib.ServiceModel.Web.WebErrorHandler, WcfRestContrib"/>
<webErrorHandler returnRawException="true" logHandlerType="Website.Backend.Services.LogHandler, Website.Backend" unhandledErrorMessage="An error has occured processing your request. Please contact technical support for further assistance."/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
之后我将服务界面修改为这样;
[ServiceContract]
public interface ICmsInfo
{
[OperationContract]
[OperationAuthentication]
[WebInvoke(UriTemplate = "account", Method = "GET")]
AccountDTO GetAccountInfo();
我采取的最后一步是在服务本身添加2个attritubes;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceConfiguration("Rest", true)]
public class Cmsinfo : ICmsInfo
{
//foo
}
WcfRestContrib通过添加这种身份验证技术帮助了我很多,而且效果很好。我只需要确保我也使用了授权标题。
在此之后,我在使用Forms身份验证的webapplication中验证web服务时遇到了问题。此问题在另一个topic中指定。