1

I am trying to get a list of subsites that are accessible to the user. I was initially using,

var query = context.Web.Webs.OrderBy(x => x.ServerRelativeUrl)
var sites = context.LoadQuery(query);
clientContext.ExecuteQuery()

But I was getting UnauthorizedException. So I tried using the GetSubwebsForCurrentUser,

WebCollection webs = clientContext.Web.GetSubwebsForCurrentUser(null);
clientContext.Load(webs);
clientContext.ExecuteQuery();

However, here as well I am getting an Unauthorized Exception. Why am I getting an Unauthorized when GetSubwebsForCurrentUser should only return sites where current user has access?

Am I doing something wrong? Is there another way to achieve this?

Full Code:

    IEnumerable<Web> GetAllWebs(String username, String password, String url)
    {
        using (ClientContext clientContext = new ClientContext(url))
        {
            SecureString passWord = new SecureString();

            foreach (char c in password.ToCharArray()) passWord.AppendChar(c);

            clientContext.Credentials = new SharePointOnlineCredentials(username, passWord);

            Web web = clientContext.Web;

            clientContext.Load(web);

            clientContext.ExecuteQuery();

            Console.WriteLine(web.Title);


            WebCollection webs = clientContext.Web.GetSubwebsForCurrentUser(null);
            clientContext.Load(webs);
            clientContext.ExecuteQuery();

            return webs;
        }
    }
  • are you the admin ? If there is more code above, can you share that ? – Gautam Sheth Jan 24 '18 at 10:29
  • @GautamSheth Updated original post with full code. Hope it helps. – Hyperion Jan 30 '18 at 12:12
  • Your full code works as expected for Online or on-premise. I think the issue come from: 1. The username, password or url used are incorrect 2. The account used doesn't have enough permissions to query SharePoint by CSOM, at least the account must have "ViewPages" permission. – Vladimir Herrlein Jan 30 '18 at 15:21
  • Consider using CSOM search API, as it's faster abd probably you will not have described problems. You'll need full list of site urls to check them. – Rustam Ismagilov Feb 3 '18 at 14:10
0

I can't really comment (rep) and I don't have a real solution unfortunately, but I was recently having similar issues with my workflow.

Unauthorised Error Creating Sub Site with Workflow

I really found that there was little value to be had from the error responses. I got bad request for the incorrect URL call, but I got a 401 response as soon as any parameter was out of place anywhere.

All I can say is that the 401 Unauthorized error is not necessarily related to permissions as much as the action of the code itself is not permitted, so I would read it more like a runtime error.

  • No this is certainly related to permissions because as soon as I make the user member of the site, I stop getting an exception. – Hyperion Jan 30 '18 at 12:07
0

Have modified/fixed your code and changed couple of things:

1) Added passWord inside foreach loop. Currently, its outside

2) Also added AuthenticationMode and set it to default.

3) Added method to check whether user is present in the site collection by using EnsureUser method.

Please try with the below code:

IEnumerable<Web> GetAllWebs(String username, String password, String url)
{
    using (ClientContext clientContext = new ClientContext(url))
    {
        SecureString passWord = new SecureString();

        foreach (char c in password.ToCharArray())
        {
            passWord.AppendChar(c);
        }

        clientContext.Credentials = new SharePointOnlineCredentials(username, passWord);
        clientContext.AuthenticationMode = ClientAuthenticationMode.Default;

        var rootWeb = clientContext.Site.RootWeb;
        var ensureUser = rootWeb.EnsureUser(userName);
        clientContext.Load(ensureUser);
        clientContext.ExecuteQuery();

        Web web = clientContext.Web;

        clientContext.Load(web);

        clientContext.ExecuteQuery();

        Console.WriteLine(web.Title);

        WebCollection webs = clientContext.Web.GetSubwebsForCurrentUser(null);
        clientContext.Load(webs);
        clientContext.ExecuteQuery();

        return webs;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.