Base solution for your next web application

Activities of "meff"

Hello. First of all - thank you for your great work. ABP is awesome.

On already working ABP (AngularJS + EF) application I need to implement functionality where admin user of one tenant can act as any user of another tenant.

In order to replace IAbpSession.TenantId I have derived ClaimsAbpSession, registered it in module:

public class MyAbpSession : ClaimsAbpSession
{
  public MyAbpSession(IMultiTenancyConfig multiTenancy) : base(multiTenancy) {}
  private int? _tenantId;
  public int? SetCurrentTenantId
        {
            set { this._tenantId = value; }
        }
        public override int? TenantId
        {
            get
            {
                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                    return null;
                return this._tenantId ?? base.TenantId;
            }
        }  
}

But I still have MayHaveTenant filter problem. Is there any chance I could globally set filter parameter for all UnitsOfWork?

_unitOfWorkManager.AllUnitsOfWork.SetFilterParameter(AbpDataFilters.MayHaveTenant, AbpDataFilters.Parameters.TenantId, input.TenantId.Value);

And this has to be done from Impersonation method (any ApplicationService or AccountController in .Web), not from module initialization.

I can not disable AbpDataFilters.MayHaveTenant / AbpDataFilters.MustHaveTenant globally, because impersonator must see only data of Tenant, that she is impersonating.

What I have tried:

  1. To derive from EfUnitOfWork and override ApplyFilterParameterValue, but I could not inject MyEfUnitOfWork :-(
  2. Wanted to derive from class UnitOfWorkManager, but it is Internal, so no luck.

What would be the best solution to achieve my business requirement?

I am even thinking of creating identical AbpUsers (and synchronizing for password change and so on) for each tenant, that a user must have access to... Is ASP.NETZERO has fully implemented impersonation (on features it says "User and Tenant impersonation")?

Could you please provide some advise to this problem? Thank you in advance.

Hello, so I will ask my question shortly: is there any easy way to achieve a functionality, that user from one tenant could act on behalf of another tenant?

Thank you.

Thank you for your answer.

Background of a problem: companyM (lest call it tenantM) signed an business agreement, that users of companyM will work on behalf of companyS1, companyS2 and companyS3 (tenantS1, tenantS2, tenantS3 respectively), while still using they'r own logins into system.

My purpose is to let userM1 of tenantM to work as userM1 of tenanS1, and tenantS2 and so on.

If I follow your suggestion - I shall create DUMMY userS1, userS2, userS3 for every user of tenantM1, is that correct?

Answer

Hello, did you made it? I do also need to implement similar deployment schema.

Hello.

Short version of a question: How to force ABP web application to use dynamic WEB API, that is deployed on another server? It would be super, if I could simply change server name somewhere in Web.config :-)

Long version of a question: ABP (+Module Zero) based project, developed by me, with AngularJS + some cshtml GUI is used on client infrastructure.

Client uses internal network infrastructure and has some servers, that are open to public internet. The software was developed for internal usage.

Client decided to expose this system to public internet.

New requirements arrise:

  1. Software, that is exposed to public internet, must not contain any code for doing administrative tasks
  2. Server, that is exposed to public internet, cannot contain software directly accessing any database

With point No. 1 I have dealed using C# compiler directives. They eliminate chunks of C# code for administrative tasks.

How to deal with point No. 2?

I have to build infrastructure like this:

database_server <----> intranet_web_server_for_administrative_tasks_and_EXPOSED_DYNAMIC_WEB_API <----> public_internet_web_server_that_has_ONLY_GUI

How can I use Dynamic Web API from publicly accessible server? Both internal and public web servers should use ApplicationLayer in internal web server.

Answer

On the last two lines of your exception it is written:

WARN 2016-08-31 17:00:44,074 [7 ] nHandling.AbpApiExceptionFilterAttribute - There are 1 validation errors: WARN 2016-08-31 17:00:44,074 [7 ] nHandling.AbpApiExceptionFilterAttribute - The Name field is required. (input.Name)

Clearly you are missing input.Name parameter :-)

Going post by post in forum and found:

#739

Eager to try by myself :-)

Hello. Simply override SaveChanges in your DbContext class:

public override int SaveChanges()
        {
            try
            {
                return base.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                var errorMessages = ex
                    .EntityValidationErrors
                    .SelectMany(x => x.ValidationErrors)
                    .Select(x => x.ErrorMessage);
                var fullError = string.Join(Environment.NewLine, errorMessages);

                var exceptionMessage = string.Concat(ex.Message, Environment.NewLine, "Validations errors are:", Environment.NewLine, fullError);

                throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
            }

        }

Hello all. Once again thank you Halil for the wonderful framework.

Using ABP.Zero 1.5.1 I'm facing a real challenge: completely separate already created ABP + Module Zero software to run in 3 different servers: database, API and Web. The deployment schema should be:

  1. Database server
  2. Angular front end on on premise Web server + Web API for public front end
  3. Angular front end on publicly accessible Web server, that will not have access to database and should use API from server 2.

I read almost all this forum. My current problem is authentication: when I authenticate using AJAX from Login.js (into AccountController from my .Web project) everything works fine if API and Angular is on the same server. But if I call authenticate from another server - right after

AccountController from .Web project

AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = rememberMe }, identity);
return Json(new AjaxResponse {Success = true, TargetUrl = Request.ApplicationPath });

I get 401, that is converted by MVC to 302.

The full code: Login.js

$("#LoginButton").click(function(e) {
			e.preventDefault();
			abp.ui.setBusy(
				$("#LoginArea"),
				abp.ajax({
					url: "http://remoteAndInternallyAccesibleServer/Account/Login",
					//url: abp.appPath + "Account/Login",
					type: "POST",
					data: JSON.stringify({
						tenancyName: $("#TenancyName").val(),
						usernameOrEmailAddress: $("#EmailAddressInput").val(),
						password: $("#PasswordInput").val(),
						rememberMe: false
					})
				})
				.done(function(response) {
					abp.message.info("Login succeeded");
				})
				.fail(function(data) {
					abp.message.error(data.details, data.message);
				})
			);
		});

I always see "Login succeeded" message, I also get new record in AbpUserLoginAttempts table that login was successful. But after a few moments I get HTTP 302 (401, just as mentioned before, that was changed to 302 by MVC).

Everything is working fine from the SAME SERVER if I comment / un-comment this:

//url: "http://internallyaccesibleserver/Account/Login",
url: abp.appPath + "Account/Login",

This probably has something to do with CORS or authentication headers, or the cookie does not travel from my remoteAndInternallyAccesibleServer to my front end server, or some headers are missing from request or from response.

my Web.config part that deals with CORS

<httpProtocol>
		  <customHeaders>
			  <add name="Access-Control-Allow-Origin" value="*" />
			  <add name="Access-Control-Allow-Methods" value="GET, POST, HEAD, OPTIONS" />
			  <add name="Access-Control-Allow-Headers" value="Content-Type, x-xsrf-token" />
		  </customHeaders>
	  </httpProtocol>

Please help anyone, because I cannot solve this problem for a week already. What should I do to make authentication cookie to travel back to my browser from remote server using AJAX, then use this cookie to access all dynamically generated WebAPI functionality from my Angular front end (that is made completely with ABP)?

and the answer is: <a class="postlink" href="https://stackoverflow.com/questions/44287171/login-over-ajax-use-cookie-in-mvc-angular-cors">https://stackoverflow.com/questions/442 ... gular-cors</a>

Cookie-based authentication doesn't work cross-origin, because cookies are always domain-bound, regardless of your CORS settings. – Chris Pratt

Showing 1 to 10 of 11 entries