The M-Files Community will be updated on Tuesday, April 2, 2024 at 10:00 AM EST / 2:00 PM GMT and the update is expected to last for several hours. The site will be unavailable during this time.

This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SSO authentication in M-Files client wrapper

Hi community and M-Files, 

I have been using MFWS Client wrapper in one custom developed sync application. It works well with username/pwd authentication. Due to security reasons and configuration of credentials, I would rather use SSO.

I have followed the setup from here. When I follow the sample code from there, it seems to work well. When I call the AuthenticateUsingSingleSignOn method in the wrapper, I am getting some strange errors (I can post tomorrow more details, basically that session is not opened correctly etc.). 

In Git repo, there is a additional note: 

"If using Windows Single Sign On, the application will use the current Windows identity that it is running under. Note that using Windows Single Sign On requires additional configuration."

As I am not working for the partner, I can read through it. Is there some additional config that I miss to use wrapper client (as said above I have follow the setup from developer forum and have enabled SSO, it works in web, and when using example from there)?

Any experience? 

Regards,

Dejan

Parents
  • The link to the partner portal (the document you point to) is about setting up Single Sign On in MFWA in general.  If SSO works in a browser with MFWA then this has already been done.

    Please do post details of the error you're getting, but it sounds like the wrapper is not provided with a session token by the endpoint that's used for SSO.  If this is the case then my current guess is that the application that is using the wrapper is not able to use SSO for some reason.

  • Hi Craig, 

    I am getting following error:

    Uncaught exception in M-Files Web:
    
    System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.ArgumentException: Bad path: Login_LoginFailed
    Parameter name: path ---> System.NullReferenceException: Object reference not set to an instance of an object.
       at MFiles.Web.Resources.LocalizedResources.GetString(String path)
       --- End of inner exception stack trace ---
       at MFiles.Web.Resources.LocalizedResources.GetString(String path)
       at MFWA.WebServiceSSO.Finalize(Boolean loginSuccessful)
       at MFWA.WebServiceSSO.Page_Load(Object sender, EventArgs e)
       at System.Web.UI.Control.OnLoad(EventArgs e)
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
       at System.Web.UI.Page.HandleError(Exception e)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
       at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
       at System.Web.UI.Page.ProcessRequest()
       at System.Web.UI.Page.ProcessRequest(HttpContext context)
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    And also this as warning from IIS:

    Event code: 3005 
    Event message: An unhandled exception has occurred. 
    Event time: 10/14/2021 11:23:08 AM 
    Event time (UTC): 10/14/2021 9:23:08 AM 
    Event ID: cf19e5eced2141579f04ec1515ecd982 
    Event sequence: 854 
    Event occurrence: 1 
    Event detail code: 0 
     
    Application information: 
        Application domain: /LM/W3SVC/1/ROOT-1-132786745426746108 
        Trust level: Full 
        Application Virtual Path: / 
        Application Path: C:\Program Files\M-Files\21.8.10524.3\Server\MFWA\ 
        Machine name: mfiles2 
     
    Process information: 
        Process ID: 6500 
        Process name: w3wp.exe 
        Account name: IIS APPPOOL\M-Files 21.8.10524.3 
     
    Exception information: 
        Exception type: ArgumentException 
        Exception message: Bad path: Login_LoginFailed
    Parameter name: path
       at MFiles.Web.Resources.LocalizedResources.GetString(String path)
       at MFWA.WebServiceSSO.Finalize(Boolean loginSuccessful)
       at MFWA.WebServiceSSO.Page_Load(Object sender, EventArgs e)
       at System.Web.UI.Control.OnLoad(EventArgs e)
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
    
    Object reference not set to an instance of an object.
       at MFiles.Web.Resources.LocalizedResources.GetString(String path)
    
     
     
    Request information: 
        Request URL: http://localhost/WebServiceSSO.aspx?popup=1&vault=92bcf9e9-0670-4fe2-8e46-cec804341cab 
        Request path: /WebServiceSSO.aspx 
        User host address: ::1 
        User: SG\iaeaAdmin 
        Is authenticated: True 
        Authentication Type: NTLM 
        Thread account name: IIS APPPOOL\M-Files 21.8.10524.3 
     
    Thread information: 
        Thread ID: 18 
        Thread account name: IIS APPPOOL\M-Files 21.8.10524.3 
        Is impersonating: False 
        Stack trace:    at MFiles.Web.Resources.LocalizedResources.GetString(String path)
       at MFWA.WebServiceSSO.Finalize(Boolean loginSuccessful)
       at MFWA.WebServiceSSO.Page_Load(Object sender, EventArgs e)
       at System.Web.UI.Control.OnLoad(EventArgs e)
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
     
     
    Custom event details: 
    

    I am running the tool on local server where M-Files is located. 

    This worries more though:

    "To be able to use Windows authentication, M-Files Web must belong to an intranet zone. By default, only sites accessed with the direct computer name count as intranet sites, for instance "">http://server" as opposed to "">http://server.example.com"."

    Does it mean if I have HTTPs certificate and I want to use SSO with windows credentials using DNS name this would not work? At least on the same server, if I use configured HTTPs certificate and valid DNS name, it does not work. It would be really bad to run it from outside over HTTP and with server name. I think from security reasons this would not be accepted.

    But first if you have an idea what could be wrong above, I would appreciate it.

    Thanks

    Dejan

  • Hi Dejan,

    Configuration of this isn't my area of expertise.  That said, I think the keyword there is "by default"; you can add any site you want to the intranet site group, and that configuration can even be pushed out via group policy and similar I believe.

    From the error I would assume that something is perhaps not configured properly.  It may be worth reaching out to your partner or account manager for some additional support here.

    It is entirely possible that there is a bug in the wrapper, of course (it is not an official tool, is provided "as is", and is thus only in an alpha state on NuGet).  That said, I am aware that a number of people are successfully using it, so my current gut instinct is that there's something not quite right on the server end.

    Regards,

    Craig.

  • Hi Craig, 

    I've checked out the code and have debugged it through. I can see as a response:

    "{\"Status\":403,\"URL\":\"/structure/valuelists/itemidbyalias\",\"Method\":\"POST\",\"Exception\":{\"Name\":\"UnauthorizedAccessException\",\"Message\":\"Login to vault failed\"},\"Stack\":\"Error reference ID: 33f1ef31-bee9-4674-96c9-2d4f450aa575\",\"Message\":\"Login to vault failed\",\"IsLoggedToVault\":false,\"IsLoggedToApplication\":false,\"ExceptionName\":\"UnauthorizedAccessException\"}"

    This is a code I run:

    var client = new MFWSClient("http://localhost");
    client.AuthenticateUsingSingleSignOn(Guid.Parse("{4CFFC0CF-2BE1-44D9-81D6-E5A7156CD08E}"));
    
    var valueLists = client.ValueListItemOperations.GetValueListItems(6);

    I see cookie get generated and set into CookieContainer on IRestClient. So, it seems fine for me, I see you are also reading through and printing that cookie. I tried different methods both GET and POST. It is definitely problem with authentication.

    When I run following code though, it works:

    class Program
    	{
     
    		private static IRestClient restClient = new RestClient("http://localhost");
     
    		static void Main(string[] args)
    		{
     
    			// Authenticate to the sample vault.
    			AuthenticateUsingSSO("C840BE1A-5B47-4AC0-8EF7-835C166C8E24");
     
    			// Get the object types.
    			var objectTypes = GetObjectTypes();
    			Console.WriteLine($"Got {objectTypes.Count} object types.");
     
    		}
     
    		private static void AuthenticateUsingSSO(string vaultGuid)
    		{
     
    			// Build a request to WebServiceSSO.aspx.
    			var request = new RestRequest($"/WebServiceSSO.aspx?popup=1&vault={vaultGuid}")
    			{
    				Credentials = CredentialCache.DefaultNetworkCredentials
    			};
     
    			// Execute the request.
    			var response = restClient.Get(request);
     
    			// Populate our cookie container with the cookies (i.e. session tokens)
    			// returned by the request to WebServiceSSO.aspx.
    			restClient.CookieContainer = new CookieContainer();
    			foreach (var cookie in response.Cookies)
    			{
    				restClient.CookieContainer.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
    			}
     
    		}
     
    		private static List<ObjType> GetObjectTypes()
    		{
    			// Issue a request for the object types and parse them into the expected structure.
    			// The structures come from https://developer.m-files.com/APIs/REST-API/Reference/samples.html
    			return restClient
    				.Get<List<ObjType>>(new RestRequest("/REST/structure/objecttypes")).Data;
     
    		}
     
    	}

    I don't see big difference I have to admit. Basically it is the same just without additional layers and wrapping.

    To anyone in community: does anyone use wrapper with SSO and got it working?

    To summarize:

    - Windows authentication is enabled and setup

    - SSO is enabled on server

    - SSO works in browser

    - SSO works with GET sample from developer portal

    x SSO is not working with wrapper client

    Perhaps I miss something. Any idea, help is welcome.

  • I agree that the cookie being provided to the REST API doesn't seem to relate to a valid session.  That is why your REST API call is getting a 403 response code.  Bear in mind, though, that the cookie will be provided back regardless of whether SSO is actually happening on the server; it's simply an ASP.NET Session ID.

    I'll leave your other questions to others in the forum.

Reply
  • I agree that the cookie being provided to the REST API doesn't seem to relate to a valid session.  That is why your REST API call is getting a 403 response code.  Bear in mind, though, that the cookie will be provided back regardless of whether SSO is actually happening on the server; it's simply an ASP.NET Session ID.

    I'll leave your other questions to others in the forum.

Children
No Data