<cite>ismcagdas: </cite> Hi,
You can create a custom AuthorizeFilter for MVC or WebAPI and check the request here in that. Please see this issue <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1256">https://github.com/aspnetboilerplate/as ... ssues/1256</a>
I think I followed the instructions but the Log In page still displays. This is what I did:
I implemented a class called MyAuthorizeFilter and derived it from AbpMvcAuthorizeFilter. Then I overrode OnAuthorization to create the ClaimsPrincipal and attach it to the HttpContext.User.
public override void OnAuthorization(AuthorizationContext filterContext)
{
var empid = filterContext.HttpContext.Request.Headers["employeeid"];
if (empid == null) empid = "123456"; // for local testing
ClaimsPrincipal currentPrincipal = new ClaimsPrincipal(
new ClaimsIdentity(
new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, empid),
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", empid)
}, "wsso"
)
);
Thread.CurrentPrincipal = currentPrincipal;
filterContext.HttpContext.User = currentPrincipal;
base.OnAuthorization(filterContext);
}
Then I added my class to the GlobalFilters by overriding the PostInitialize of MyProjectWebModule, per instructions.
public override void PostInitialize()
{
GlobalFilters.Filters.Remove(GlobalFilters.Filters.Single(f => f.Instance is AbpMvcAuthorizeFilter));
GlobalFilters.Filters.Add(IocManager.Resolve<MyAuthorizeFilter>());
base.PostInitialize();
}
In the debugger, I see all the code get executed. Why isn't this enough to prevent the Log in page from appearing?
Oh yes, I do have the same employeeid in the Abp Users. The user properties User name: 123456 Full name: pnw Email address: <a href="mailto:[email protected]">[email protected]</a> IsActive: Yes Password: "1"
Then, when I try to log in, using Log in page and 123456/1 an error dialog appears "Empty or invalid anti forgery header token". What's that??
In my company, all on premises web servers are behind a web-based authenticator (web single sign on). Once signed on, my request header comes with my employee id. e.g. var userid = HttpContext.Current.Request.Headers['employeeid']. If the header exists and is not blank, that means authentication is successful.
How do I inform AbpZero that authentication is complete and to find my userid in the headers, and also thereby to not display the login page?
I have a class that isn't an ApplicationService but still needs to use one of my repositories. I can't have a constructor so I figured to use manual resolving.
public class Q : ISingletonDependency
{
public IThingRepository thingRepository { get; set; }
public Q()
{
this.thingRepository = IocManager.Instance.Resolve<IThingRepository>();
}
[UnitOfWork]
public List<Thing> GetDbThings(List<Thing> claims, long uid)
{
// look up more things in the database
var thingQ = from t in thingRepository.GetAll()
where t.UserID == uid
select new UOR { ...properties... };
foreach (var t in thingQ)
{
// do things with t
}
return newlistofthings;
}
}
The problem is that when I use thingRepository, I get the following exception:
The operation cannot be completed because the DbContext has been disposed
There must be something simple I'm missing?
Not using module-zero. It doesn't support my company org structure.
Somehow I was inheriting from DbContext. Once I switched to AbpDbContext my repositories were happy.
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
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?
<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?
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>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.