Base solution for your next web application

Activities of "byteplatz"

We are using azure ad through wsfederation and it's working fine for quite a while...

We also made it work with on premises adfs...

It's basically simple in the code view...

You just need to authorize he app on azuread and configure abp basically with few options

I will take a look at your pr

Bruno

Hello Halil, how are you ?

I was wondering if is possible for you to share the MultiProjectTemplate used to create AspNetZero solutions. I ask because we need to develop several separated modules and this is a tedious task.

I think youre using SideWaffle (as I saw question from someone using this to help you to create the multiproject template).

My intention is to customize this template for new module: File\NewProject\MyServiceModule and this will create the infrastructure needed (core, app, etc)

Thanks in advance

Bruno

One more catch, if you use WS-Federation + ADFS (or AzureAD) you don't need LDAP Auth. ADFS does that for you

Bruno

I would avoid windows authentication (its not designed for SSO). Instead you should use WS-Federation External Auth (It works fine with Abp, we have it in place).

Then you can use either AzureAD + Sync with your internal AD OR Install ADFS (Active Directory Federated Services) and use Abp with OWIN/External Auth WS-Federation ...

This is the standard for the SSO on windows

Bruno

Hello Halil,

Im testing the migration path we will use for our application. For a while, we will need to have both (legacy MVC and new AspNetZero Mvc) workin in parallel.

I would like to setup Owin shared cookie between AspNetZero and legacy MVC but I need to understand few things from your side.

If you create a solution with 02 different web projects (called Web1 and Web2) and leave the defaults for OWIN, both apps share same cookie authentication: if you decorate with [Authorize] and create user in Web1 then access Web2, Web2 will allow the request even if the user does not exists there. Thats okay and expected behavior (the cookie name are the same and the machine are the same as well).

This scenario creates (by using google chrome) one cookie "LocalStorage" for each webapp:

http://localhost:58830 - Web1
http://localhost:58831 - Web2

So far so good. This behavior is what Im trying to setup between AspNetZero and my legacy MVC app.

Now, from AspNetZero: When I start google chrome and navigate to aspnetzero home page (no logged in user yet) it does not create the "localstorage" cookie (like Web1 and Web2). Instead it creates the ASP.Net_SessionId and VerificationToken...

Thats okay for me...

But Im trying to understant what should I need to do to "SHARE" AspNetZero Cookie with Web1 and Web2. I've tried to set the same cookie name for all 3 apps but that didn't work.

I believe is something related to session or something.

Do you have any customization on owin/katana/session (besides AbpSession) that manage to change cookies ?

Can you help me on this issue ?

Bruno

I have opened an issue on GitHub regarding transaction and UoW on EventBus when using 02 dbcontexts (from separated module)

[https://github.com/aspnetzero/aspnet-zero/issues/85])

I need this in a certain level of priority. If you could take a look I would greatly appreciate.

Bruno

By removing the EntityChangedEventData handler it Works fine.

My understanding for this behavior (listening both parente/child event when inheriting) this will be the flow:

The lower level event handler get called, in this case it should be EntityCreatedEventHandler....then, because of the inheritance, EntityChangedEventHandler...

But the EntityCreatedEventHandler is called twice...

Thoughts Halil ?

Bruno

Debugging Abp, I can see that this is the flow:

  • Creating a new entity:

  • Breakpoint hit in EntityChangedEventHelper.TriggerEntityChangeEvent

  • Breakpoint hit in HandleEvent(EntityCreatedEventData<MyEntity> eventData)

  • Breakpoint hit in HandleEvent(EntityCreatedEventData<MyEntity> eventData) -- second time

  • Breakpoint hit in EntityChangedEventHelper.TriggerEntityChangeEvent

By looking at the code I found this:

public void Trigger(Type eventType, object eventSource, IEventData eventData)
        {
            //TODO: This method can be optimized by adding all possibilities to a dictionary.

            eventData.EventSource = eventSource;

            foreach (var factoryToTrigger in GetHandlerFactories(eventType))
            {
                var eventHandler = factoryToTrigger.GetHandler();
                if (eventHandler == null)
                {
                    throw new Exception("Registered event handler for event type " + eventType.Name + " does not implement IEventHandler<" + eventType.Name + "> interface!");
                }

                var handlerType = typeof(IEventHandler<>).MakeGenericType(eventType);

                try
                {
                    handlerType
                        .GetMethod("HandleEvent", BindingFlags.Public | BindingFlags.Instance, null, new[] { eventType }, null)
                        .Invoke(eventHandler, new object[] { eventData });
                }
                finally
                {
                    factoryToTrigger.ReleaseHandler(eventHandler);
                }
            }

This code get executed when creating entity (perfectly sense), but the foreach get called twice for my handler (maybe registered twice) :

handlerType
                        .GetMethod("HandleEvent", BindingFlags.Public | BindingFlags.Instance, null, new[] { eventType }, null)
                        .Invoke(eventHandler, new object[] { eventData });

This is my Handler code (Im listening for the Changed eventdata as well and I thinkg this might be the problem with the generic event dispatcher):

class MyEntityEventDataHandler : ITransientDependency,
        IEventHandler<EntityCreatedEventData<MyEntity>>,
        IEventHandler<EntityUpdatedEventData<MyEntity>>,
        IEventHandler<EntityChangedEventData<MyEntity>>,
        IEventHandler<EntityDeletedEventData<MyEntity>>
    {
        public ILogger Logger { get; set; }

        public void HandleEvent(EntityDeletedEventData<MyEntity> eventData)
        {
            Logger.Debug("EntityDeleted");
        }

        public void HandleEvent(EntityChangedEventData<MyEntity> eventData)
        {
            Logger.Debug("EntityChanged");
        }

        public void HandleEvent(EntityUpdatedEventData<MyEntity> eventData)
        {
            Logger.Debug("EntityUpdated");
        }

        public void HandleEvent(EntityCreatedEventData<MyEntity> eventData)
        {
            Logger.Debug("EntityCreated");
        }
    }

I will remove the entityChanged and try again

Bruno

Both triggers are exactly the same...

Cant find why the event is being triggered twice...

The event handler is located in a separated module.

I can see that the event is being triggered one for each dbcontext (MainApp and CustomModule)

Can you help me on that ?

Bruno

Thank you !

I will try to implement a login flow without field for tenancy name (using tenant detection by username on Login action)...

Quick question : Why there are no method to FindAllAsync (Users) and only exists for (External) Logins ?

[UnitOfWork]
        public virtual Task<List<TUser>> FindAllAsync(UserLoginInfo login)
        {
            var query = from userLogin in _userLoginRepository.GetAll()
                        join user in _userRepository.GetAll() on userLogin.UserId equals user.Id
                        where userLogin.LoginProvider == login.LoginProvider && userLogin.ProviderKey == login.ProviderKey
                        select user;

            return Task.FromResult(query.ToList());
        }
public virtual Task<TUser> FindAsync(int? tenantId, UserLoginInfo login)
        {
            var query = from userLogin in _userLoginRepository.GetAll()
                join user in _userRepository.GetAll() on userLogin.UserId equals user.Id
                where user.TenantId == tenantId && userLogin.LoginProvider == login.LoginProvider && userLogin.ProviderKey == login.ProviderKey
                select user;

            return Task.FromResult(query.FirstOrDefault());
        }

They both go only in LoginRepository...Are there any specific reasons/arthicteture? Or it is just a matter of "not implemented" ?

Can I implement those methods for Users in UserManager.cs from my application ? Will that interfere with UoW or AuditLogs ?

Bruno

Showing 11 to 20 of 57 entries