ASP.NET Membership - 当您在同一个 WebApp 中调用 WebService 时,经过身份验证的用户会丢失

Posted

技术标签:

【中文标题】ASP.NET Membership - 当您在同一个 WebApp 中调用 WebService 时,经过身份验证的用户会丢失【英文标题】:ASP.NET Membership - Is authenticated user lost when you call a WebService in the same WebApp 【发布时间】:2010-10-31 03:45:19 【问题描述】:

我正在使用 ASP.NET 登录控件进行身份验证。

我有一些用户,他们能够成功登录。经过身份验证后,我重定向到页面 helloworld.aspx。在 Page_Load 方法中,我首先调用 Membership.GetUser()。这将正确返回经过身份验证的用户。然后,我调用驻留在同一个 WebApplication 中的简单 WCF Web 服务。我的 WebService 调用的第一行是相同的 Membership.GetUser()。这次虽然返回 NULL。

有什么想法吗?

谢谢, 贾斯汀

这是一些代码sn-ps

贾斯汀佩奇.aspx

public partial class JustinPage : System.Web.UI.Page

    protected void Page_Load(object sender, EventArgs e)
    
        MembershipUser user = Membership.GetUser();
        // user is a valid user

        JustinService.JustinTestServiceClient justin = new CMS.WEB.JustinService.JustinTestServiceClient();
        justin.DoWork();
    

JustinTestService.svc.cs

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class JustinTestService

    [OperationContract]
    public void DoWork()
    
        MembershipUser user = Membership.GetUser();
        // user is NULL ???  Why?
        return;
    

如前所述,服务源代码与端点所见的 Justin.aspx 位于同一 WebApplication 中(注意我的应用程序固定在端口 19003 上)...

端点地址="http://localhost:19003/Services/JustinTestService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_JustinTestService" contract="JustinService.JustinTestService" name="BasicHttpBinding_JustinTestService" /

绑定看起来像这样...

安全> 绑定>

也许它与 ???

有关

【问题讨论】:

【参考方案1】:

获取 fiddler 并查看身份验证 cookie 是否正在通过网络发送。

如果不是,您可能需要将其捆绑在您对服务的请求中。

类似的东西

Service1Client ws = new Service1Client(); // Name of webclient proxy
            using (OperationContextScope scope = new OperationContextScope(ws.InnerChannel))
            
                HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty();
                OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest);

                HttpCookieCollection cc = Page.Request.Cookies;
                if (Request.Cookies[".ASPXAUTH"] != null)
                
                    HttpCookie aCookie = Request.Cookies[".ASPXAUTH"];
                    String authcookieValue = Server.htmlEncode(aCookie.Value);
                    httpRequest.Headers.Add("Cookie: " + ".ASPXAUTH=" + authcookieValue);
                

                // Make call to webservice here
                ws.MyWCFCall();

                HttpResponseMessageProperty response = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name];
             

【讨论】:

【参考方案2】:

问题在于 Web 服务调用并非源自用户经过身份验证的浏览器。相反,您是从您的应用程序发起 Web 服务调用(您的 Web 服务器正在向您的 Web 服务器创建一个 HTTP 请求!)。

【讨论】:

嗯...好的,同意。我故意这样做是因为我想创建一个所有客户都可以与之交流的通用合同。我不想仅仅因为这个 WebApp 驻留在同一个应用程序中,就授予这个 WebApp 对业务层的特殊访问权限。所有客户端应用程序都应通过相同的 API。那么推荐的解决方案是直接调用服务吗?我已经知道这可行,但试图保持一致可能不正确。 我假设您可以获得当前登录用户的凭据并将其发送到 Web 服务,但我不确定这是否安全。您的网络服务是对外开放还是仅对内部开放?

以上是关于ASP.NET Membership - 当您在同一个 WebApp 中调用 WebService 时,经过身份验证的用户会丢失的主要内容,如果未能解决你的问题,请参考以下文章

Membership 介绍

ASP.NET Membership 作为用户登录

ASP.NET MVC2 Membership:如何获取登录用户的 userID 和 roleID?

ASP.net Membership角色与权限管理

ASP.NET Membership 是不是具有生成密码重置 URL 的机制?

membership与成员资格