0

I'm trying to do remote authentication using C# CSOM. I referred this URL Remote Authentication using C# CSOM. It works fine, if I logged in once to SharePoint Online site. If I clear my cookies and try to execute the code, then it shows "Access is denied". How to mitigate this? Appreciate your help. Below is the code.

            string targetSite = "https://abc.sharepoint.com/teams/sitename";
        using (ClientContext ctx = ClaimClientContext.GetAuthenticatedContext(targetSite))
        {
            if (ctx != null)
            {
                ctx.Load(ctx.Web); // Query for Web
                ctx.ExecuteQuery(); // Execute
                Console.WriteLine(ctx.Web.Title);
            }
        }


    public static ClientContext GetAuthenticatedContext(string targetSiteUrl)
    {
        return (GetAuthenticatedContext(targetSiteUrl, 0, 0));
    }           

    public static ClientContext GetAuthenticatedContext(string targetSiteUrl, int popUpWidth, int popUpHeight)
    {
        CookieCollection cookies = null;
        cookies = ClaimClientContext.GetAuthenticatedCookies(targetSiteUrl, popUpWidth, popUpHeight);
        if (cookies == null) return null;

        ClientContext context = new ClientContext(targetSiteUrl);
        try
        {
            context.ExecutingWebRequest += delegate(object sender, WebRequestEventArgs e)
            {
                e.WebRequestExecutor.WebRequest.CookieContainer = new CookieContainer();
                foreach (Cookie cookie in cookies)
                {
                    e.WebRequestExecutor.WebRequest.CookieContainer.Add(cookie);
                }
            };
        }
        catch
        {
            if (context != null) context.Dispose();
            throw;
        }

        return context;
    }

    public static CookieCollection GetAuthenticatedCookies(string targetSiteUrl, int popUpWidth, int popUpHeight)
    {
        CookieCollection authCookie = null;
        using (ClaimsWebAuth webAuth = new ClaimsWebAuth(targetSiteUrl, popUpWidth,popUpHeight))
        {
            authCookie = webAuth.Show();
        }
        return authCookie;
    }

    public CookieCollection Show()
    {
        if (string.IsNullOrEmpty(this.LoginPageUrl)) throw new ApplicationException(Constants.MSG_NOT_CLAIM_SITE);

        // navigate to the login page url.
        this.webBrowser.Navigate(this.LoginPageUrl);

        DisplayLoginForm = new Form();
        DisplayLoginForm.SuspendLayout();

        // size the login form
        int dialogWidth = Constants.DEFAULT_POP_UP_WIDTH;
        int dialogHeight = Constants.DEFAULT_POP_UP_HEIGHT;

        if (PopUpHeight != 0 && PopUpWidth != 0)
        {
            dialogWidth = Convert.ToInt32(PopUpWidth);
            dialogHeight = Convert.ToInt32(PopUpHeight);
        }

        DisplayLoginForm.Width = dialogWidth;
        DisplayLoginForm.Height = dialogHeight;
        DisplayLoginForm.Text = this.fldTargetSiteUrl;

        DisplayLoginForm.Controls.Add(this.webBrowser);
        DisplayLoginForm.ResumeLayout(false);

        Application.Run(DisplayLoginForm);

        // see ClaimsWebBrowser_Navigated event
        return this.fldCookies;
    }

    private void GetClaimParams(string targetUrl, out string loginUrl, out Uri navigationEndUrl)
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(targetUrl);
        webRequest.Method = Constants.WR_METHOD_OPTIONS;
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);
        try
        {
            WebResponse response = (WebResponse)webRequest.GetResponse();
            ExtraHeadersFromResponse(response, out loginUrl, out navigationEndUrl);
        }
        catch (WebException webEx)
        {
            ExtraHeadersFromResponse(webEx.Response, out loginUrl, out navigationEndUrl);
        }
    }

    private bool ExtraHeadersFromResponse(WebResponse response, out string loginUrl, out Uri navigationEndUrl)
    {
        loginUrl = null;
        navigationEndUrl = null;

        try
        {
            navigationEndUrl = new Uri(response.Headers[Constants.CLAIM_HEADER_RETURN_URL]);
            loginUrl = (response.Headers[Constants.CLAIM_HEADER_AUTH_REQUIRED]);
            return true;
        }
        catch
        {
            return false;
        }
    }

    private CookieCollection ExtractAuthCookiesFromUrl(string url)
    {
         Uri uriBase = new Uri(url);
        Uri uri = new Uri(uriBase, "/");
        // call WinInet.dll to get cookie.
        string stringCookie = CookieReader.GetCookie(uri.ToString());
        if (string.IsNullOrEmpty(stringCookie)) return null;
        stringCookie = stringCookie.Replace("; ", ",").Replace(";", ",");
        // use CookieContainer to parse the string cookie to CookieCollection
        CookieContainer cookieContainer = new CookieContainer();
        cookieContainer.SetCookies(uri, stringCookie);
        return cookieContainer.GetCookies(uri);
    }

    private void ClaimsWebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
    {
        // check whether the url is same as the navigationEndUrl.
        if (fldNavigationEndUrl != null && fldNavigationEndUrl.Equals(e.Url))
        {
            this.fldCookies = ExtractAuthCookiesFromUrl(this.LoginPageUrl);
            this.DisplayLoginForm.Close();
        }
    }
  • How do you clear cookies? – Denis Molodtsov Sep 20 '17 at 20:31
  • I cleared manually because I wanted to deploy this into another server once done. So to check before deploying into another server, I cleared manually in my machine and wanted to check the authentication works or not. – Srini K Sep 20 '17 at 20:38
  • Can you add the code you are using to the question? – Denis Molodtsov Sep 20 '17 at 20:39
  • Just followed this URL code.msdn.microsoft.com/remote-authentication-in-b7b6f43c – Srini K Sep 20 '17 at 20:44
  • I don't really think you need to use this code you used. Also, it helps if you add the code to the question. this way more people can help you. Not everyone will want to download a project, unzip it and look in the code this way. – Denis Molodtsov Sep 20 '17 at 20:53
3

I'm not sure I understand your problem with cookies, but here is a sample code that you can use to authenticate against SharePoint Online:

using (var context = new ClientContext(webUrl))
{
   context.Credentials = new SharePointOnlineCredentials(userName,password);
   context.Load(context.Web, web => wweb.Title);
   context.ExecuteQuery();
   Console.WriteLine("Your site title is: " + context.Web.Title);
}

If you clear your browser cookies it should not affect the way this code works.

Update:

I didn't see your code and I'm not sure you tried this:

var context = new ClientContext(sendToSiteURL);
var credentials = CredentialCache.DefaultNetworkCredentials;
context.Credentials = credentials;

Hopefully, it will pickup the current credentials of the current process you are going to run this code in.

  • I don't want to hardcode the user name and password. I'm not using APP model. I'm writing C# managed CSOM and planning to execute using Task Scheduler. Your piece of code works fine. But I don't want to do like this. Is there any other option available without hard coding usrname and pwrd ? – Srini K Sep 20 '17 at 20:42
  • updated the answer – Denis Molodtsov Sep 20 '17 at 20:49
  • Added code in my question. The update you provided, I'm getting as 403 forbidden error. FYI I'm using SharePoint Online site. – Srini K Sep 20 '17 at 21:19
  • Then you need to hardcode the login and password. Or put it to the config file. You won't get Single sign on with SharePoint Online. That's your answer :) – Denis Molodtsov Sep 20 '17 at 22:19
  • 1
    Thank you very much Denis :) So I'm concluding, no option to get the SPO context without using APP model or hardcoding credential..! – Srini K Sep 20 '17 at 22:33
0

The only way to access the SPO context is with username and password without this you can't access any site inside c# application.

  • 2
    You can use clientid and clientsecret from an app registration to login from C# console application – Anders Aune Sep 21 '17 at 6:53
  • Hi @AndersAune please can you provide some link to this or any idea how this can be implemented. – Atul Gupta Oct 4 '17 at 10:20
  • @AtulGuptra Looks like this post should get you there – Anders Aune Oct 4 '17 at 10:45

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.