At some point in the life cycle of an authenticated ASP.NET request the IdentityUser is retrieved from the backing store (either Entity Framework or otherwise). I'd like to hook into that process. The reason is that the user has some collection properties and I'd like to retrieve those as well with one call to the database (using IQueryable<T>.Include).
Is this possible in ASP.NET identity?
I think you probably want to implement a ClaimsAuthenticationManager
The claims authentication manager provides a place in the claims processing pipeline for applying processing logic (filtering, validation, extension) to the claims collection in the incoming principal before execution reaches your application code.
Since what you're looking for sounds like extension to me. You override the Authenticate method that has this signature:
public virtual ClaimsPrincipal Authenticate(
string resourceName,
ClaimsPrincipal incomingPrincipal
)
You probably want to override UserStore and override all of the FindXXX methods that return a User do add whatever Includes that you wanted.
Related
I am developing an application with multiple tenants. Each tenant can be associated with a user to identify the database that it will have access to, through the connection string that is stored in the database.
The problem I am having is that I only identify this connection string at the moment the user logs in, however I need to register this connection string when the StartUp class is executed.
I tried to do this using session variables, I got the ConfigureServices method of the StartUp class to run again with the correct value, but I can not get this new configuration to take effect.
services.AddScoped<IDapperContext>(s => new DapperContext(connectionString));
I guess I need to rebuild for the new setting to take effect.
How can I do this?
Am I on the right path?
Is there any other way to solve this problem?
I recently read this article, which talks about injecting the HTTPContext into your service.
https://www.strathweb.com/2016/12/accessing-httpcontext-outside-of-framework-components-in-asp-net-core/
Once you have the context, you can get the authenticated user, and retrieve your connection string from a second DB or source that maps users to databases. You would have to configure your context options during construction of the context, in order to control the connection string for the context as a scoped service.
You might want to consider using a context factory instead that does this for you.
The code in startup.cs would add a context for the database with your connection strings, and then your factory would accept that as an injected dependency. Your factory would also take in IHttpContextAccessor as a dependency giving you access to the user in the context. Together you could then obtain the connection string, and wire up the DbContextOptions to pass to a new instance of your context.
This seems like the easiest approach for DI to me.
I am having troubles wrapping my head around the concept of multi tenancy in combination with websecurity (webmatrix framework from microsoft). I am building a mutli tenant website with:
mvc4
entityframework6
websecurity (from webmatrix)
Authenticate
I can allow users to register & login using the WebSecurity methods. I can verify if a user is logged in / is authenticated via User.Identy.IsAuthenticated.
Determine Tenant
I determine the tenant via the url ([companyname].domain.com).
Register a new customer
A new customer can create a tenant via the registering form in my application. If a user registers (without having a companyname present in the url) he will have to give some account inputs as some company inputs. He will then create a new alias which is conform companyname.domain.com. So, long story short, a Tenant is always coupled to 1 or more user(s) (1-N).
Requirement
I need to guarantee that a user from Tenant 'abc' will never be able to login to Tenant 'xyz'. (Therefore I also don't like the WebSecurity framework too much, as it seems a shared database for all my tenants (or am I wrong?)).
My question
Could you guys share some insights in how to handle the check on "tenant" and "authenticated user" in real world multi tenant applications?
The hot topics for me:
Do you validate the tenant + authenticated user once, or in every action in every controller?
Is it safe to rely on the default websecurity class or would I be better of designing my own user tables or are customer MembershipProviders the better alternative?
Should I use cookies or is that a very bad choice.
I would be very much helped if you could share some documentation where I can read all about these questions. I have the strong desire to see some more in detail documentation about multi tenancy, that dives into the actual design (maybe even code examples).
I already read through most of the "general documentation" / "commericial presentations":
http://msdn.microsoft.com/en-us/library/aa479086.aspx
http://www.businesscloud9.com/content/identifying-tenant-multi-tenant-azure-applications-part-2/10245
http://msdn.microsoft.com/en-us/library/windowsazure/hh689716.aspx
http://www.developer.com/design/article.php/3801931/Introduction-to-Multi-Tenant-Architecture.htm
If needed I'll rephrase / add code / do whatever is needed to get help.
Many thanks in advance.
Each solution you could get here would be dependent on what your app does and how it works with data, if you use repository pattern, if you use IoC etc. You might consider instantinating your repository by passing userid to repository class and doing filtering everytime application needs data, you can do that in your controller - this approach is used very often (even in VS SampleProjects - like "SinglePage Application" you might want to download some open source projects and just see how it's done there.
What I do in some of my projects where nothing "really fancy" is required and I don't expect a huge load is this:
- I setup BaseController that every other controller needs to implement
- in onActionExecuting event of the BaseController I do
public Employee CurrentEmployee { get; set; }
protected override void OnActionExecuting(ActionExecutingContext ctx)
{
base.OnActionExecuting(ctx);
string authenticatedUser = User.Identity.Name;
CurrentEmployee = mortenDb.Employees.FirstOrDefault(e => e.Account.Login == authenticatedUser );
}
so in all other controllers I'm able to refer to an Employee object that belongs to currently logged in user. You could do the same with your Company object. So I assume you would query Employees like I do and retrieve the Company reference and pass it to public property on your BaseController. It's maybe not the best solution, but it's rather secure as long as you remember to pull out data via Company object navigation properties (eg. Employees, Tickets, Requests etc. whatever you have in your Model )
I have a login.java servlet and, as its name says, it provides login facilities to my web application.
I'm a newbie and I'm using EJB 3.1 and EE 6. In my LoginBean.java EBJ I have a no-arguments constructor and another one that has some parameters (email, password, etc).
At certain point in the servlet code I have the calling to instantiate my EJB:
#EJB LoginBean loginBean;
I'd like to know if it's possible (and how) to call the other constructor instead of the zero-arguments one.
Thanks a lot.
Cheers.
You don't want to do that. The one and same servlet is shared among all users, so the EJB is also shared among all users. You don't want to store user-specific data as instance variable of the servlet or EJB class. It would be shared among all webpage visitors.
Rather move the arguments to a EJB method which you invoke in the doPost() method of the login servlet.
User user = loginBean.login(username, password);
and then store this in the HTTP session when it went successful
request.getSession().setAttribute("user", user);
so that the rest of your webapp can intercept on this to determine if the user is logged in or not.
if (request.getSession().getAttribute("user") != null) {
// User is logged in.
} else {
// User is not logged in.
}
I 100% agree with BalusC. In addition to his answer I would like to add that you normally* never explicitly reference the constructor of an EJB bean, even if doing so would theoretically make sense (e.g. when passing in some dependencies, or some configuration parameter).
EJB beans are managed objects and what you are getting in your #EJB annotated field is not the actual object but a stub (proxy). The actual object instance to which the stub points is most likely constructed long before you get this stub to it and also very likely comes from a pool.
(*)Some kind of units tests may be an exception to this rule.
I'm creating a multi-tenant ASP.NET application using NHibernate (shared schema). I had intended to use NHibernates Event Listeners to inspect/modify entities prior to saving to ensure that the current tenants ID was being saved against the entity.
The authentication token containing the tenant ID is managed higher up and passed down into the data layer.
My problem is that Event Listeners are configured against an NHibernate Configuration rather than a specific ISession. This means that there's no way to pass in any identifiers for it to use, although I can access the ISession that caused the event to fire.
How can I go about passing ISession specific data into the Event Listener?
You might be able to do this with an IInterceptor implementation because ISessionFactory has an overloaded OpenSession method that accepts an IInterceptor. Usage would be something like:
var interceptor = new MyInterceptor(tenantId);
var session = factory.OpenSession(interceptor);
Unfortunately there's no overload that accepts listeners.
I am building an application using asp.net mvc, DI, IoC, TDD as a bit of a learning exercise.
For my data access I am using the repository pattern. Now I am looking at membership and how this can work with the repository pattern. I am currently using a Linq to Sql repository but don't want to be tied to SQL Server for membership.
Secondly, I am looking to split out membership into a number of services:
AuthenticationService - identify the user
AuthorizationService - what can they do
PersonalizationService - profile
The personalization service will be what really defines a "customer" in my application and each customer will have a unique id/username that ties back to the AuthenticationService - thus, allowing me to use the default ASP.NET Membership provider, roll my own or use something like Open ID.
Is this a good approach? I don't want to reinvent the wheel but would rather these important parts of my application follow the same patterns as the rest.
Thanks
Ben
Take a look at the RIA Authentication, Roles, and Profiles services.. no need to reinvent the wheel.
To be honest, to achieve what I wanted was quite a simple process. I haven't implemented the AuthorizationService yet but this will follow a similar pattern.
My authentication service is quite simple:
public interface IAuthenticationService
{
bool IsValidLogin(string username, string password);
}
There will be a CreateUser method but I haven't implemented this yet.
Creating an authentication service using the standard membership provider is a simple task:
public class AspNetAuthenticationService : IAuthenticationService
{
public bool IsValidLogin(string username, string password)
{
return Membership.ValidateUser(username, password);
}
}
If I want to swap out the default SqlMembershipProvider with my own then I just need to change web.config. In order to support different types of authentication (perhaps forms auth and open id) I can just create a controller action for each and call the appropriate IAuthenticationService.ValidateUser implementation before setting an auth cookie.
The authentication process if for identifying the "user". In order to get the "Customer" I am using a PersonalizationService. The interface for this is again quite simple:
public interface IPersonalizationService {
Customer GetCustomer(string username);
}
This returns my customer (with addresses, past orders - the stuff we really care about). The GetCustomer method will create a customer object if one doesn't exist with the passed in username. So if using standard forms auth a customer will be created anyway during registration. If using something like OpenID, the first time they login a customer object will be created and linked to their OpenID username (hence the reason for separating what an authenticated "user" is from a "customer".
This process also works well for anonymous checkout since I can create an in memory customer object for "guest" customers, and finally persist this to the database if they make a purchase. In this case, I don't have a user (cause they didn't authenticate) but I do have a customer.
I am quite happy with this implementation. I think I will roll my own Membership Provider (since it's not really that difficult) and I would like to use the repository pattern for the data access. Interested to hear any opinions / suggestions on this approach.
Some resources I have used:
http://noahblu.wordpress.com/2009/02/19/custom-membershipprovider-using-repository-dependency-injection-pattern-magic/
http://davidhayden.com/blog/dave/archive/2007/10/11/CreateCustomMembershipProviderASPNETWebsiteSecurity.aspx
http://pbdj.sys-con.com/node/837990/mobile
http://mattwrock.com/post/2009/10/14/Implementing-custom-Membership-Provider-and-Role-Provider-for-Authinticating-ASPNET-MVC-Applications.aspx