从WebMethod获取Sitecore用户?

时间:2015-02-23 20:42:42

标签: sitecore

我想将一些Sitecore数据提供给非Sitecore页面。数据将由JQuery请求,并且应该是JSON格式。我们还需要更新项目,执行工作流程操作等。

我们在Sitecore 6.4上,所以,据我所知,我们没有ItemWebAPI或MVC作为选项。 .NET是版本4

我们尝试使用GET请求,查看查询字符串参数并分支到一个或多个函数。一个问题是查询字符串的默认最大大小对于我们传递的数据来说太小了,并且将其设置为允许的最大值(这显然违反了安全性最佳实践)也不够可靠。因此,出于这个原因和一些与缓存相关的问题,我们转向了POST。 JQuery似乎无法以页面想要的方式发送POST数据,因此我们必须引入一些代码来解析请求有效负载文本(即我们无法使用Request.Form [&#34] ;东西"])。我们确实让这个工作,但它很难看。在它和分支之间它是一个纠结。

我现在正在关注WebMethods。除了简化代码之外,WebMethods还为我们提供了一些免费的东西,例如json格式的错误消息,缺失参数的明智错误消息等。

我有一个测试页面设置为发出请求(只是HTML和JQuery)和一个ASPX页面来执行WebMethods。我将WebMethods页面的URL放在web.config的IgnoreUrlPrefixes中,如下所述:WebMethod not accessible in Sitecore。我可以使用Sitecore.Configuration.Factory.GetDatabase(databasename)访问Sitecore数据库。

因此,WebMethods整体似乎比我们以前更好地编写代码并且工作得更好。现在我可以阅读代码,我只是编写有效的函数,而不是花费大部分时间来弄清楚为什么事情不能正常工作和实现变通方法。

但我们确实失去了Sitecore上下文,如引用问题的答案中所述。我无法找到获取Sitecore用户的方法。

当我发出请求时,我会在Chrome开发者工具中看到有一个sitecore_userticket cookie。我已经尝试将该cookie的值(以及Sitecore.Web.Authentication.TicketManager.GetCurrentTicketId的结果)提供给Sitecore.Web.Authentication.Ticket.Parse,但我得到一个解析错误。有没有办法使用该cookie来获取用户?

或者有没有办法从ASP.NET_SessionId cookie中获取用户?

如果这些都不可行,那么管理登录信息的好方法是什么?我知道我可以通过编程方式登录用户,但不希望在浏览器中跟踪Sitecore用户名和密码,并在每次请求时发送它们。

我在Sitecore之外没有很多.NET经验。

2 个答案:

答案 0 :(得分:0)

目前你把一个普通的aspx页面做了。在sitecore中创建一个新项目,理想情况下应该在内容树的某个奇怪位置,如

/sitecore/content/home/services/handler

在上面的路径中,服务只是一个文件夹,处理程序只是另一个项目(可以基于样本模板)。应用一个布局到一个aspx页面(在这里你编码),你放置你的webmethods .. 这样它就成为Sitecore请求,如果登录(否则是匿名用户)将拥有sitecore上下文和上下文用户,并且您也不需要从工厂获取上下文数据库。 为了确保安全,您可以使用基于Sitecore的身份验证或您喜欢的任何身份验证。 例如: 下面确保页面上的请求已经过身份验证,否则会重定向到所需的页面。

protected override void OnInit(System.EventArgs arguments)
        {
            Assert.ArgumentNotNull(arguments, "arguments");
            checkSecurity(true);
            base.OnInit(arguments);
        }

其次是在页面加载时决定函数并调用它..

protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (Request.QueryString != null && Request.QueryString.Count > 0)
                {
                       string jobName = Request.QueryString["jobName"].ToString();
                       string cacheName = Request.QueryString["cacheName"].ToString();
                       StringBuilder sbAjax = null;
                    if (jobName!=null && jobName.Length > 0)
                    {
                             if (jobName="")
                        {
                           sbAjax=callSomething();
                        this.Page.Response.Clear();
                        if (sbAjax != null)
                            this.Page.Response.Write(sbAjax.ToString());
                        else
                            this.Page.Response.Write("");
                            this.Page.Response.End();
                        }
                     }
                }
           }
}
private StringBuilder callSomething()
{
//Do Something
}

答案 1 :(得分:0)

在重新阅读评论(Display original Sitecore username instead of what's currently typed in)中引用的问题@Gabber后,我有一个可行的解决方案。简而言之,我可以根据创建Sitecore帐户时设置的基础System.Web.Security.MembershipUser对用户进行身份验证。访问者可以使用他或她的Sitecore用户名和密码。然后我可以使用System.Web.Security.FormsAuthentication.SetAuthCookie设置AuthCookie,每当我需要Sitecore用户时,我都可以从HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]获取域名和用户名,并将其提供给Sitecore.Security.Accounts.User.FromName以返回Sitecore用户。

有一点不太明显,如果用户已经登录Sitecore,他们将不得不再次进行身份验证以设置MembershipUser的cookie(即我没有得到它来获取Sitecore身份验证对于当前登录的Sitecore用户)。我认为这对我的目的来说是可行的。大多数访问WebMethod-fed普通html页面的人无论如何都不会是CMS用户。但对于那些人来说,避免再次登录会很好。

[WebMethod]
public static bool login(string user, string password, string domain)
{
    bool valid = System.Web.Security.Membership.ValidateUser(domain + "\\" + user, password);
    if (valid)
    {
        System.Web.Security.FormsAuthentication.SetAuthCookie(domain + "\\" + user, true);
        return true;
    }
    return false;
}

[WebMethod]
public static string getuser()
{
    HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
    string u = ticket.Name;

    Dictionary<string, string> responseDict = new Dictionary<string, string>(); 

    User user = Sitecore.Security.Accounts.User.FromName(u,false);
    {
        responseDict["domain"] = user.Domain.Name;
        responseDict["user"] = user.Name;
        responseDict["displayname"] = user.DisplayName;
        responseDict["email"] = user.Profile.Email;
        responseDict["fullname"] = user.Profile.FullName;                
    }

    return JsonConvert.SerializeObject(responseDict, Formatting.Indented);
}

以下是我用来测试这些网络方法的简单html页面:

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>

    <p>domain <input type="text" name="domain" id="domain"/></p>
    <p>user <input type="text" name="user" id="user"/></p>
    <p>password<input type="text" name="password" id="password"/></p>
    <div class="gettoken button">
        <p>Get Token</p>
    </div>
    <p class="tokenresult">token result</p>

    <hr/>

    <div class="getuserinfo button">
        <p>Get User Info</p>
    </div>
    <p class="userresult">result</p>

    <hr/>

    <script>
    $('div.gettoken').click(function ()
    {
        var user = $('#user').val();
        var domain = $('#domain').val();
        var password = $('#password').val();

        $.ajax({
            type: "POST",
            url: "http://sitecore/apis/scitemapi.aspx/setauthcookie",
            data: '{"domain":"' + domain + '", "user": "' + user + '", "password":"' + password + '"}',
            contentType: "application/json; charset=utf-8",
            success: function (msg)
            {
                $("p.tokenresult").text(msg.d);
            }
        });
    });

    $('div.getuserinfo').click(function ()
    {
        $.ajax({
            type: "POST",
            url: "http://sitecore/apis/scitemapi.aspx/getuser",
            data: '{}',
            contentType: "application/json; charset=utf-8",
            success: function (msg2)
            {
                $("p.userresult").text(msg2.d);
            }
        });
    });


    </script>
    <style>

    html{
        font-family:tahoma;
        }

    .button{
        background-color:blue;
        color:white;
        border:1px solid black;
        border-radius:4px;  
        width:12em;
        text-align:center;
        margin-top:1em;
        padding:.5em;
        }

    </style>
</html>