bgmulinari / B1SLayer

A lightweight SAP Business One Service Layer client for .NET
MIT License
136 stars 47 forks source link

SSO with UI API #14

Closed sofdwere closed 1 year ago

sofdwere commented 2 years ago

Can you add the ability to login from UI API without username and password, by using _SBOApplication.Company.GetServiceLayerConnectionContext, like described in here ?

I have tested it successfully:

example of using:

string serviceLayerRoot = $"https://{Application.SBO_Application.Company.ServerName}:50000/b1s/v1";
var serviceLayer = new SLConnection(serviceLayerRoot, Application.SBO_Application.Company.GetServiceLayerConnectionContext, 30);
var bpList = await serviceLayer.Request("PriceLists").Filter("PriceListName eq '105900'").Select("PriceListNo").WithCaseInsensitive().GetAsync<List<PriceList>>();
int priceListNo = bpList.First().PriceListNo;

code add / changes:

#region Fields
Func<string, string> GetServiceLayerConnectionContext;

/// <summary>
/// Initializes a new instance of the <see cref="SLConnection"/> class.
/// Only one instance per company/user should be used in the application. 
/// </summary>
/// The Service Layer root URI. The expected format is https://[server]:[port]/b1s/[version]
/// <param name="GetServiceLayerConnectionContext">method from UI api</param>
/// <param name="sessionTimeout">session timeout value of ServiceLayer, see b1s.conf</param>
public SLConnection(string serviceLayerRoot, Func<string, string> GetServiceLayerConnectionContext, int sessionTimeout = 30) {
    ServiceLayerRoot = new Uri(serviceLayerRoot);
    CompanyDB = null;
    UserName = null;
    Password = null;
    Language = null;
    NumberOfAttempts = 3;
    LoginResponse = new SLLoginResponse {
        SessionTimeout = sessionTimeout
    };
    this.GetServiceLayerConnectionContext = GetServiceLayerConnectionContext;
    //
    FlurlHttp.ConfigureClient(ServiceLayerRoot.RemovePath(), client => {
        // Disable SSL certificate verification
        client.Settings.HttpClientFactory = new CustomHttpClientFactory();
        // Ignore null values in JSON
        client.Settings.JsonSerializer = new NewtonsoftJsonSerializer(new JsonSerializerSettings {
            NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
        });
    });
}

// Session still valid, no need to login again
if (DateTime.Now.Subtract(_lastRequest).TotalMinutes < _loginResponse.SessionTimeout)
    return expectReturn ? LoginResponse : null;
//
if(GetServiceLayerConnectionContext != null) {
    string connectionContext = GetServiceLayerConnectionContext(ServiceLayerRoot.ToString());
    Cookies = new CookieJar();
    string[] cookieItems = connectionContext.Split(';');
    foreach (var cookieItem in cookieItems) {
        string[] parts = cookieItem.Split('=');
        if (parts.Length == 2) {
            Cookies.AddOrReplace(new Flurl.Http.FlurlCookie(parts[0].Trim(), parts[1].Trim(), ServiceLayerRoot.ToString()));
        }
    }
    _loginResponse.LastLogin = DateTime.Now;
    return null;
}

I didn't find a way to get the ServiceLayer sessiontimeout value, which is defined in b1s.conf, so for the moment i have added it as parameter with default value (default 30 min). Do you have an idea how it can be done automatically?

bgmulinari commented 2 years ago

Hi, @sofdwere. SSO support is something I've considered in the past but haven't got around implementing it. It's definitely on my list of features to add next, so thanks again for your suggestion on this.

bgmulinari commented 2 years ago

As for the session control and timeout value, I'll have to look into it as I'm also not sure.

bgmulinari commented 2 years ago

Hey, @sofdwere, I just pushed a commit to the dev branch that contains the SSO implementation. I used your code suggestion as a base but changed a few things.

If you are able to download and test it, let me know if it works as intended.

sofdwere commented 2 years ago

I have tested the SSO in the current dev branch right now and it works as intended, thank you.

valkiara commented 1 year ago

Hi,

Is this feature going to be included in master branch?

Regards

bgmulinari commented 1 year ago

Hi, @valkiara. Sorry for the delay on this, I plan to merge this feature soon in an upcoming version.

I will update this issue when the new version is out.

valkiara commented 1 year ago

Hi Bruno,

Is there estiamte date when new version will be released?

Regards

bgmulinari commented 1 year ago

I apologize again for the delay. This feature is now (finally) available in version 1.3.0.

If you encounter any issue, please let me know.

@sofdwere, huge thanks for your suggestion on this.

valkiara commented 1 year ago

Thanks a lot Bruno! will let you know if there will be any problem.