Is it necessary to override the membership and the role providers? - asp.net-membership

I'm working on a web app and I don't want to store the connection strings in the web or app config because of the requirements.
So far I have found the only way to achieve this - to override the membership and the role providers.
I also don't fully understand why do I also have to override a role provider when all authentication is apparantely handled by the membership provider?
Thank you

While the SqlRoleProvider and SqlMembershipProvider are separate concerns, they both talk to the same database (typically).
They each have a distinct configuration section and require an instance of a connections string.
I approve of the strategy you discovered on the other question and if you wish to use roles you will have to do the same thing, configuration in code, as you are doing for membership.
You should link to the other question to give context and prevent getting flagged as a duplicate.

I have found a solution online, which is a bit of a hack, but saves me from overriding membership and role providers.
Solution is to set a connection string in global.asax through reflection:
protected void Application_PreRequestHandlerExecute()
{
try
{
SetProviderConnectionString(DllForConnectionStringManagement.GetConnectionString());
}
catch (Exception e)
{
// Log and throw
}
}
SetProviderCOnnectionString is a private method which sets the connections of membership and role provider through reflection.

Related

Bind manager credential on ActiveDirectoryLdapAuthenticationProvider Spring framework

On a JHipster application, I've added a custom authentication provider, to verify user and password of Active Directory users that have login inside. This custom component implements AuthenticationProvider, and inside "authenticate" method, istance an ActiveDirectoryLdapAuthenticationProvider object to get authentication and verify presense on specifical groups.
With a simple A.D. test environment I've no problem, but in production, my company ask me to bind a service account, and I cannot found any method to setup manager-ad and password. How can I get around this problem?
On Spring documentation I've read the phrase "There is no concept of a "manager" user."
My app use 5.1.8.RELEASE
Thanks!
Looking at the code, it validates the user's credentials by binding using the user's credentials. That's really the only way to validate credentials.
I assume, since it has already made a successful bind, it just continues on making whatever search it needs to.
There might be a way to use different credentials for reading the groups, but it all depends on what your current code looks like. But there really is little point in doing this. You have to bind using the user's credentials to validate their credentials. So you may as well continue using that same connection.

Wicket authorization: Grant access based on page model

I'm developing a fairly standard web application with Wicket, Spring & Hibernate. I've been using wicket-auth-roles and spring-security to authenticate users, and now want to add more fine grained authorizations to my applications.
In my applications users are members of groups, and groups have access to a subset of Hibernate objects that I use as wicket IModel objects. As such the decision whether or not a user may view certain page does not depend on the page path, but on the page model. (Most implementations of authorization for Wicket I've seen either grant access to a url or restrict it; they do not perform any checks on the model object.)
At present I've implemented this restriction as a custom IAuthorizationStrategy like this:
#Override
public boolean isActionAuthorized(final Component component, final Action action) {
if (!(component instanceof GenePage))
// We only check access to the GenePage for now
return true;
// Figure out from component what Gene the user is trying to view
Gene gene = (Gene) component.getDefaultModelObject();
User user = MySession.get().getUserModel().getObject();
return geneDAO.hasAccess(user, gene);
}
The problem with this implementation is that it fully composes the page and only in Page#onConfigure throws an uncaught UnauthorizedActionException. So far I've been unable to catch this exception, so it's logged as a problem even though it's part of the normal program flow. Fully composing the page also triggers a few actions in my page constructor and Page#onInitialize that I would only like to run if the user may actually view the Page.
Can anyone recommend me a better approach to restrict page access based on whether users have access to the Model object?
Solutions that tie in anywhere along the stack using Hibernate, Spring, Spring Security, Wicket and/or Wicket-Auth-Roles would be preferred. I know there are other wicket auth-integrations out there, so if you feel those could help in this instance, please let me know!
I feel that you expect a weird behaviour. This authz mechanism is designed to protect against Insecure Direct Object Reference Vulnerabilities. So you should not use it as a "part of the normal program flow". If you have kind of valid use cases then such kind of "hasAccess" failures should be handled somehow differently as valid behaviour, you should use some other mechanism, probably something custom built, as in most cases it will be very specific to your application.

IN MVC - is session handling & authentication to be handled by User Model?

I was wondering if session handling like authentication and signing in is best handled by the User Model (assuming a user model refers to a user) and has attributes such as email and password. Or should session handling be held by another model?
What exactly is the best way to do this - I have code pretty much strewn partially in controllers in function files and want to refactor my code to adhere more to MVC principles. My project is based on the Zend Framework.
In MVC concept, the model represents the business part of your application.
Manage authentication, saving, deleting, activating of an user are business issues.
So it makes sense to create a method authenticate, save, delete, activate directly in your user model.
So in your user model, it is preferable to implement static methods as
public static function authenticate ($ username, $ password)
{
$authService = $this-> getServiceLocator()->get('Zend\Authentication\AuthenticationService');
$adapter = $authService->getAdapter();
$adapter->setIdentityValue($username);
$adapter->setCredentialValue($password);
$authResult = $authService->authenticate();
return $authResult->isValid();
}
And in your controller, you can directly do:
User/Entity/User::authenticate($username, $password);
I view authentication and session management as application-level concerns.
One general criterion I often apply is this: "Could I use my models in another app (perhaps a commandline app) or another website?
For example, in your circumstance, I would view a User model as representing a user. That user exists irrespective of whether or not he is actually visiting and/or logging in/out of your website. He could be referenced in a commandline app (Ex: a cron job that sends email to all users on their birthday; a reporting utility that counts all users that have incomplete profiles); etc. As such, I would keep authentication session management at the controller-level or perhaps one level down in a service level.
But as in most things, YMMV.

ASP.NET MVC3: Do I need to use a MembershipProvider?

I am building a multi-tenant site with MVC3. Prior to this project I had never touched either the .NET stack or web development in general, so as you can imagine my domain knowledge is somewhat lacking.
I'm still using the default AccountController architecture, but I pretty quickly determined that I didn't want to use aspnetdb.mdf for authentication, as its design is pretty different from my requirements. I do want role-based authentication, so I ultimately wrote custom User and Role classes as code-first Entity classes and used this tutorial to set up a custom MembershipProvider and RoleProvider.
Everything works fine at the moment, but as I'm building the multi-tenancy functionality it's getting messier. Based on this example, I am using a custom extension of Controller which keeps track of which tenant is using this session, and all my controllers extend this class instead of the base Controller class.
All tenants are using the same database. Each entity has a Tenant property that identifies who it belongs to.
So, here's the problem:
Usernames do not need to be globally unique. Only the combination of username and tenant must be unique. Thus, ValidateUser needs to know the username, password, and tenant. Since my custom MembershipProvider is not a Controller, it doesn't know which tenant is using the session, and the ValidateUser method only accepts username and password so I can't pass it that information.
Furthermore, pretty much everything MembershipProvider does besides ValidateUser is already implemented in a UserRepository class, which that tutorial told me to make. I'm rather fond of the Repository pattern, and it's way more convenient than adhering to MembershipProvider's interface, but now there's a massive conflict of interest between UserRepository and MembershipProvider.
So, my question:
Do I need to use MembershipProvider, or even Membership, at all?
It seems like everything MembershipProvider does would be performed more conveniently by my repository class. At this point all I'd have to do is write a new Authorize attribute that doesn't rely on Membership, and everything should work without any MembershipProvider at all, right? If I don't drop Membership I'm forced to completely mutilate my MembershipProvider implementation to the point that it barely resembles the original interface anyway.
...Either that or Membership does a ton of things I'm unaware of and removing it is blatant stupidity. That is also a distinct possibility.
No, you don't need to use Membership, but consider for a moment exactly what Membership is. Membership does not involve your users names, or addresses, or other information. Membership is strictly related to the login account of the system. It only handles details with creating, validating, updating, or deleting the information needed to login. That's it.
Likewise, the Role system is only assigning a role name to the user.
Ultimately, Membership and Roles are just implementations of the IPrincipal interface. While FormsAuthentication is an implementation of the IIdentity interface. These work together so that you can utlize the built-in ASP.NET Authorization and Authentication system.
Membership actually does have the concept of multiple tennants. This functionality is accomplished via the "ApplicationNane" field of the aspnet_users table (also settable in the Membership class itself)
From the documentation on the Membership class:
The ApplicationName is used to identify users specific to an application. That is, the same user name can exist in the database for multiple ASP.NET applications that specify a different ApplicationName. This enables multiple applications to use the same database to store user information without running into duplicate user name conflicts. Alternatively, multiple ASP.NET applications can use the same user database by specifying the same ApplicationName. The ApplicationName can be set programmatically or declaratively in the configuration for the Web application.
Now, this is designed to typically be set in the Web.Config and stay the same for the life of the app, but I see no reason why you can't use it to specify which tennant you want.
The only issue here is that Membership.ApplicationName is static, which means it's shared by all threads running in the App Pool. However, if you use some kind of lock around accessing it, then this shouldn't be a huge issue (though it could affect scalability at some level).
This would basically allow you to use the standard, out of the box membership provider without any changes. You just have ot make sure to guard the access calls.
You don't have to use the membership provider at all. Its simply provided as a quick and consistent way to get up and running. Some choose it because it supports multiple databases (universal membership providers include azure as well as sql ce, express, and full) but for others trying to map it to your applications rules can be more difficult than the <5 lines of code it takes to authenticate and issue your own forms auth ticket.
With that said I'm assuming you are using forms authentication. You can simply issue the ticket yourself. I would still program against an interface for this which the default MVC template should have, so simply add in a new tenant id.
With that said, I'd consider having unique names. It ensures you don't 'forget' to do an additional tenant check somewhere else in the app and tenant1\userBip and tenant2\userBip surprisingly end up stomping on each others record at some point.
True, testing should uncover this - if testing is complete : )

TelerikProfileProvider with custom Membership Provider

I've setup two membership providers: my custom provider and the Sitefinity provider. My custom membership provider is set as the default.
I want to use Sitefinity's Profile provider for both sets of users. However, the profile provider only seems to work for the users that I pull out of the Sitefinity membership provider.
After poking around with Reflector a bit, it seems that the Telerik Profile Provider assumes that the username exists in its own DB.
User userByName = this.Application.GetUserByName(userName);
if (userByName != null)
{
// magic happens here...
}
All the magic only happens if it was able to retrieve the user locally. Seems to violate the principles of the providers. Shouldn't I be able to arbitrarily add properties to any user regardless of the membership provider?
(I've also posted this on the Sitefinity forum, but haven't got a response yet. SO has spoiled me. I've come to expect an answer in minutes, not days.)
If I understand you correctly you want to use the sitefininty provider as a base and attach some additional information to the users profiles.
In general I would advise against trying to mingle with internal sitefininty management. Instead try to attach whatever functionality you want to execute to the standard provider.
What I have done in these situations in the past was creating a Membership Provider Wrapper (In your case a ProfileProviderWrapper) that holds an internal reference to another profile provider, while being a Profile provider itself.
This way you can execute any code you want before/after calling back to the actual underlying provider (or maybe your not calling back at all).
For example: Before returning the profile you could attach additional properties to it.
This way you don't break the sitefinity behavior, while still being able to interfere.

Resources