iSeller Commerce
iSeller POS Retail
iSeller POS F&B
iSeller POS Express
Crosslight
WebUI
ClientUI
What's New
Download Trial
Web Solution
Mobile Solution
Enterprise Solution
Custom Development
Blog
Community
Latest Development Blogs
ForumPostTopic
Browse By Tag
Hey Guys,
We are fairly new to Web API, and based on Crosslight's business template, we have no idea how we can configure this template to connect to a database depending on which client is requesting access. We have an existing WCF web service, wherein each method has a parameter called CompanyCode. Ideally we should be able to pass in a CompanyCode, and based on this CompanyCode the connection string will be dynamically created and passed on to the constructor of the database context or entity at runtime. But the same idea doesn't fit with the account and authentication services, nor any other services from the business template because it is tightly-coupled to a single database, initially.
So, kindly advise how we can extend the business template and services to allow an application to connect to a specific database at runtime. We don't want to move astray from Crosslight templates by creating our own services... so please shed some light to our concern and we are hoping you could provide a sample project as a solution.
Hey guys, any thoughts on this?
Thanks!
Hey guys, any thoughts on this?Thanks!
Hey Guys! Awesome release on Update 3. I understand you might be very busy, and deserves quite a break after that great new update release BUT I do hope you find time to give us some advice regarding this issue. Now that we are really trying take advantage of Crosslight feature, we would really appreciate you taking time helping us out with this one. Here are few insights that we have:
BUT, we're looking forward to getting a response from you. Your feedback regarding this matter is really appreciated. As always, many thanks!
Apologize for the delay in sending this.
For such scenario, we can separate the tasks into two parts.
Modify the server side (WebAPI)
In this part, we are going to modify the WebAPI so it will understand how to process HTTP requests from the client with custom routing.
First we will need to modify the Web API routes in WebApiConfig.cs file. We can start by modifying following code:
public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DataApi", routeTemplate: "data/{controller}/{action}" ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
into:
public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DataApi", routeTemplate: "data/{controller}/{action}/{companyCode}", defaults: new { companyCode = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{companyCode}/{id}", defaults: new { id = RouteParameter.Optional, companyCode = RouteParameter.Optional } ); }
Next, we will need to add a controller-action method that will handles the HTTP request with following pattern: data/{controller}/{action}/{companyCode}.
We can use the Login action-method for reference.The function can be something like following:
[HttpGet] public virtual HttpResponseMessage Login(string userName, string password, string companyCode) { ... }
Now, we have done the first part. When there is HTTP request such as: http://sitename.com/data/identity/Login/GlobalTechInc?userName=JohnDoe&password=p@55w0rd, the server (WebAPI project) knows which action-method that should handle the request.
Modify the client side (Crosslight part)
In this part, we need to modify the rest request in order to be able to access the above web service.
Let’s start by modifying login process. Using AppFramework, the login process uses UserService and UserRepository to connect to the IdentityController (WebApi).
Following snippet code is the method which performs login process using user account asynchronously in UserRepository.
public async Task<bool> LoginAsync(IAccount account) { var request = this.InitializeLoginAsyncRequest(account); var response = await this.ExecuteAsync(request); return this.OnLoginAsyncCompleted(response); }
We need to modify the request by overriding InitializeLoginAsyncRequest (to add companyCode parameter). Create a new class, for example: CustomUserRepository; inherit UserRepository class; and override InitializeLoginAsyncRequest method. These can be done in AppService.cs file under Infrastructure folder of Core project.
These changes are shown in the following snippet code.
public class CustomUserRepository : UserRepository { protected override IRestRequest InitializeLoginAsyncRequest(IAccount account) { RestRequest request = new RestRequest(this.LoginActionName + "/" + this.GetCompanyCode(), HttpMethod.GET); request.RequestFormat = RequestDataFormat.Json; request.AddParameter("username", account.Username); request.AddParameter("password", account.GetProperty(Account.PasswordHash)); // ensure no account is associated in login request this.RestClient.Account = null; return request; } }
Please note that we need to repeat the steps above for the other method in the repository class.
Last, modify the registered data repositories by replacing the default UserRepository registration with the new one, CustomUserRepository.
Hope this help.
Hi Yudi,
As always, you do provide great help. Now that we have established connection with identity services, how does crosslight actually use the BasicAuthHttpModule module? By that, I mean how are the passwords being hashed? Is it the ASP.NET identity that is doing the hashing? If not, how do we customize PasswordHash in order to use our own, since our user accounts were created using a different hash algorithm. In addition, how do you pass a CompanyCode to BasicAuthHttpModule in order to dynamically create a valid connection string to the IdentityContext() within that module? Is there a way to do that with the existing implementation?
Many thanks!
Q : ...how does Crosslight actually use the BasicAuthHttpModule module? By that, I mean how are the passwords being hashed? Is it the ASP.NET identity that is doing the hashing?
A : Yes, it is using ASP.NET identity to do the hashing.
Q : how do you pass a CompanyCode to BasicAuthHttpModule in order to dynamically create a valid connection string to the IdentityContext() within that module? Is there a way to do that with the existing implementation?
A : You can create a valid connection string in the controller-action method that will handle the HTTP request.
[HttpGet] public virtual HttpResponseMessage Login(string userName, string password, string companyCode) { ... //you can use the company code here to initialize the EntityContext based on CompanyCode }
Well, I believe my question regarding the EntityContext is for the BasicAuthHttpModule dirently instantiating the IdentityContext() object. In which case we can't see any method to pass in the CompanyCode into the request before it even authenticates the user. Sure the controllers can be manipulated since these things do accept parameters, but that's not the case for the BasicAuthHttpModule. Or we could be wrong.
The only way I see how to pass a company code to that module is to concatenate it with the password, assuming it is being submitted in plain text (not already hashed). Then, parse that password to get the company code from there and create a connection string, before the AuthenticateWebApiUser(string credentials) even retrieves the UserManager from the IdentityContext using the default connection.
Does that make any sense? Or is there another way of doing it? Our enterprise application do serve multiple clients, so please bear with us in this matter. We are thinking of creating separate IIS Virtual Applications for each client to get rid of this predicament, but that's gonna cause huge deployment resources.
Well, let us know what you think. We do value your advice, so please do keep 'em coming. As always, thanks!
or
Choose this if you're already a member of Intersoft Community Forum. You can link your OpenID account to your existing Intersoft Social ID.
Choose this if you don't have an Intersoft account yet. Your authenticated OpenID will be automatically linked to your new Intersoft account.
Enter your Wordpress Blogname