Base solution for your next web application

Activities of "pnw"

I upgraded to ABP 0.6.3.1 and Zero 0.6.3.4 and now I get an HTTP 500 at userManager.LoginAsync of AccountController.cs that carries this in the Response Body:

Exception Details: System.Data.SqlClient.SqlException: Invalid column name 'AuthenticationSource'.

I ran the 'update-database [connect string]' command in Package Manager to create a whole new database so I could compare the columns to my production database. I found I needed to add AuthenticationSource:

ALTER TABLE dbo.AbpUsers ADD AuthenticationSource nvarchar(64) NULL

Question

I got the idea from reading other posts in this forum that I can provide Identity & Authorization to ABP using my own interface implementations instead of using Zero. My User and Role stuff isn't quite like what Zero wants. I see that there are two articles in ABP's documentation that hint at what I need to do but I still don't know exactly what to do. I also have the idea that if I implement the interfaces correctly, I can use ABP's declarative permissions approach on the Application Services.

One of the core problems I have with the Zero table structure is that it assumes a User has a Role. In my company, a User may belong to more than one Organization and they may not have the same role in each Org. The Zero table structure and Permission methods don't take Organization into account.

For example, this method in AbpUserManager just needs User and Permission.

public virtual async Task<bool> IsGrantedAsync(long userId, string permissionName)

A method that I need would look like this

public virtual async Task<bool> IsGrantedAsync(long userId, int organizationId, string permissionName)

To completely replace AbpZero is too much work since it does a lot and is hard to follow. I hope that implementing _just_what ABP needs will be simpler. My table structures to support User-Organization-Role already exist.

While waiting for a response, I'll watch some Pluralsight courses on ASP.NET Identity & Authorization.

Answer

<cite>bogdan: </cite>

I've made the same conclusion some time ago and have made a wrapper around the ASP.Net Identity.

To use this data you need a custom implementation of IPermissionChecker interface which will be able to handle permissions in the form "Organisation=1234". You can use this permisson either by an attiribute [AbpAuthorize("Organisation=1234")] or by injecting IPermissionChecker and using it directly.

That is exactly what I'm looking for. I see how IPermissionsManager and IPermissionChecker work but where I do set up the claims and integrate the Identity and claims into AbpSession? There must be another class for that?

In my case, the Identity is determined before my app even starts. Our corporate STS puts our identity in a cookie. I guess I'm looking for the Abp version of the ClaimsTransformation - where I have access to the cookies and the database so I can assemble all the claims together.

The documentation [http://aspnetboilerplate.com/Pages/Documents/Abp-Session]) says I can implement my own AbpSession but it doesn't say how to register it.

As a side note, I need to retrieve the authenticated user id which is in a cookie. Is the session the right place to do this?

I implemented it like this

public class AbpSession : IAbpSession
    {
        public Abp.MultiTenancy.MultiTenancySides MultiTenancySide
        {
            get { return Abp.MultiTenancy.MultiTenancySides.Host; }
        }

        public int? TenantId
        {
            get { return 1; }
        }

        public long? UserId
        {
            get 
            {
                return 12345; // TODO how to get this from cookie!
            }
        }
    }

but now when I inject IAbpSession in an ApplicationService, an error is thrown; part of which is pasted below.

"innerException":{"message":"An error has occurred.","exceptionMessage":"Can't create component 'Scorecard.UserDomain.UserApplicationService' as it has dependencies to be satisfied.\r\n\r\n'Scorecard.UserDomain.UserApplicationService' is waiting for the following dependencies:\r\n- Service <span style="color:#FF0080">'Abp.Runtime.Session.IAbpSession' which was not registered</span>.\r\n",

<cite>hikalkan: </cite> Hi,

IAbpSession only requires getting current UserId. You can get it from any source. Just provide it. Best method is to set userId (as lon integer) as encrypted to a cookie and get it from this cookie on next requests. You can also learn and use Microsoft's ASP.NET Identity Framework for membership management.

Since IAbpSession only defines a getter for UserId, the assumption must be that initializing the value happens in AbpSession??

I implemented AbpSession and now I just need to return a value from UserId. The value I need is in a cookie but HttpContext is not available in AbpSession. You mention providing it from a cookie but how do I get access to the cookies?

Question

In Global.asax, I create a name claim and set it to the Thread and HttpContext principals.

Before leaving BeginRequest, I confirm that p.Identity is a ClaimsIdentitythat has Name = "45678" and IsAuthenticated=true.

protected override void Application_BeginRequest(object sender, EventArgs e)
        {
            SetupPrincipal();
            base.Application_BeginRequest(sender, e);
        }

        private static void SetupPrincipal()
        {
            var uid = HttpContext.Current.Request.Headers["userid"];
            if (uid == null) uid = "45678";

            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, uid)
            };
            var id = new ClaimsIdentity(claims, "wsso");
            var p = new ClaimsPrincipal(id);
            Thread.CurrentPrincipal = p;
            HttpContext.Current.User = p;
        }

Then I have my custom AbpSession that DI creates after BeginRequest. When I access the UserId:

public long? UserId
        {
            get
            {
                var cp = ClaimsPrincipal.Current;

                return 12345; // TODO how to get this from cookie!
            }
        }
ClaimsPrincipal.Current.Identities

is of WindowsIdentityand Name="" and IsAuthenticated=false. The claims collection is empty.

Why did APB destroy my Principal? How am I supposed to feed my user id into AbpSession?

Question

Recently, I started over with the ABP project generator in order to excise ABPZero from my solution. I created a brand new solution and added all my files back. Something went wrong and now my repositories won't work because of the following runtime error. What does it mean?

An unhandled exception of type 'Castle.MicroKernel.ComponentNotFoundException' occurred in Castle.Windsor.dll

Additional information: No component for supporting the service Scorecard.EntityFramework.ScorecardDbContext was found
Answer

Somehow I was inheriting from DbContext. Once I switched to AbpDbContext my repositories were happy.

Answer

Not using module-zero. It doesn't support my company org structure.

Showing 1 to 10 of 23 entries