I'm currently building a new ASP.NET MVC 5 project which I want to release around September. I need to choose a membership system, but I'm currently quite confused about which direction should I take. The current SimpleMembership works well, but will apparently be incompatible with the upcoming ASP.NET Identity. ASP.NET Identity on the other hand is absolutely new with zero documentation and can change anytime. Finally it seems that string based IDs are used here, which seems like a very unnecessary overhead compared to integer based IDs, which SimpleMembership supports. Is there a good, future proof way I can choose?
I would advise against using SimpleMembership as well. You can still use int IDs in your database, you would just need to ToString() the ID when plugging in your database entity, i.e.:
public class MyUser : IUser {
[Key]
int UserID { get; set; }
string IUser.Id { get { return UserId.ToString(); } }
}
In my opinion if you start your project with asp.net mvc 5 you should use the new membership system since it is well integrated with http://owin.org/ standards.
I would either use the newest version of identity or build your own Account system completely. ASP.NET Identity now uses a GUID ( NVARCHAR(128) - in the db ) for the ID, however you can still use a int if you want to. I know people still using identity 1.0 with no issues I believe they used int for the Id back then.
Either way an Id shouldnt ever clash whether its a int or a guid. as the above post said you can just Id.ToString();
Whatever route you take I dont think it will make much of a difference.
I believe ASP.NET is quite good framework and provide almost all required functionality for an applications. It also provide feasibility to choose type of Id column as per your choice. I created basic a wrapper over ASP.NET identity and published a nuget, so that it would be easily use. You can take a look on code at github
Related
Envrionment: Visual Studio 2013, ASP.NET MVC 5
On the new MVC5-based project I will be working on, I need to use a custom database that stores usernames, passwords, and roles in its own way. I am searching the Internet to look for an example for custom authentication. Looks like the old-style "membership provider" classes have been replaced by the new "Identity" mechanism.
However, finding a good step-by-step example has proven to be futile. There are a few links (published this year) that talk about implementing custom IPrincipal and DbContext classes. Some other links talk about implementing IUserLoginStore and IUserPasswordStore. A few others hinted on implementing IUser, IUserStore interfaces.
Maybe the last option is what is needed. Can someone please guide me with the steps or point me to any link that has a simple example? Something like:
Implement MyUser based on IUser
Implement MyUserStore based on IUserStore
Modify web.config to use MyUserStore
Remove DefaultConnection from web.config as it is not required
Regards.
First, stop. Stop thinking about "custom authentication". You don't need custom authentication, you just need custom storage of authentication data.
ASP.NET Identity has abstracted out the storage mechanism of authentication from the process of authentication. There are several interfaces that follow the pattern IxxxStore.. Such as IUserStore, IRoleStore, etc...
You can find more information about this here, along with custom implementations for various databases which you can probably convert to your own needs.
http://odetocode.com/blogs/scott/archive/2014/01/20/implementing-asp-net-identity.aspx
As an example, here is a RavenDB implementation that uses all the various interfaces in a single class.
https://github.com/tugberkugurlu/AspNet.Identity.RavenDB/blob/master/src/AspNet.Identity.RavenDB/Stores/RavenUserStore.cs
However, all this assumes you really truly a need to store data totally differently. If you just need to store the data in different columns, then it may simply be as easy as overriding OnModelCreating in your IdentityContext and changing the names of the columns in use.
ad.1.
public class ApplicationUser :IUser
{
public string Id
{
get;
set;
}
public string UserName
{
get;
set;
}
}
ad.2.
public class MyStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserSecurityStampStore<ApplicationUser>, IUserEmailStore<ApplicationUser>
{
... //implement all interfaces here
}
ad. 3.
Now you can create your applicationUserManagerService (you will need IdentityMessageService, and IDataProtectionProvider):
var applicationUserManagerService = new ApplicationUserManagerService(new MyStore(), emailService, dataProtectionProvider);
Try to use IoC and register your IUserStore (I did it this way - link below):
unityContainer.RegisterType<IUserStore<ApplicationUser>, MyStore>();
check also my answer here (i'm using int as UserId there):
AspIdentiy ApplicationUserManager is Static, how to extend so it participates in my IoC framework?
I've created a new MVC 3 Internet Application, and it comes with the Account model/controller, etc.
Those are stored in a MDF database.
I'd like to create new models for my application, and make relations from these to my account model.
I did not find anything about it, maybe I looked for the wrong thing... So I was wondering, is there anybody who could point me in the right direction about how to do so?
Thanks!
Ah there in lies a problem with using the built in providers and aspnet default db.. In that database there is a unique id for each row - you in theory CAN use that to link to your databasse - but realize this is completely separate. One alternative many people do is to use a Custom Membership Provider (for example custom sql membership provider)
There are tons of articles/blogs out there on that - for starters see:
http://blogs.syrinx.com/blogs/dotnet/archive/2007/12/14/a-simple-custom-sql-membership-provider-part-1.aspx
This enables you to keep everything in your own database and its fairly easy to implement.
I found this as well:
https://github.com/anderly/SimpleMembership.Mvc3
I guess it's another alternative.
The answer I was looking for is exactly this:
In your model, link to the Membership User like this:
public virtual Guid UserGuid { get; set; }
public virtual MembershipUser User
{
get
{
return Membership.GetUser(UserGuid);
}
}
I'm trying to create a data access later using System.DirectoryServices. I'd like to use the MVC 2 framework and have all my views be mostly strongly-typed. Does anyone know any good way to this?
For example I started creating a Group Entity:
public class Group
{
public string DistinguishedName { get; set; }
public string GroupName { get; set; }
}
And an abstract interface:
public interface IGroupRepository
{
List<Group> Groups { get; }
}
I am confused about developing the GroupRepository using the system.directory services. Connecting to a SQL database is easy there are examples everywhere but I have no been able to find any using the System.directory sevices in conjunction with a class using MVC. Has anyone tried to do something like this? Any great would be
If you're on .NET 3.5 (and if you use MVC 2, chances are good you are), you should check out the new System.DirectoryServices.AccountManagement namespace which brings you lots of strong .NET classes and types for many of the directory objects you're dealing with on a regular basis - no need to re-invent the wheel (yet again!).
Check out this great article in MSDN magazine on how to use this S.DS.AM namespace:
Managing Directory Security Principals in the .NET Framework 3.5
Update: for reasons I don't totally understand, the simple approach of using a UserPrincipal as a model for a ASP.NET MVC view doesn't work - it seems as if ASP.NET MVC cannot "find" any properties on that object.
So the approach would have to be to do something like this:
grab your UserPrincipal (or DirectoryEntry) from Active Directory
define a separate ViewModel - this is just a class that holds properties, like first name, last name and so forth
you can either fill that ViewModel class yourself, or you can grab some help like AutoMapper to make mapping from UserPrincipal (DirectoryEntry) to your ViewModel easier
then display (or edit) your ViewModel class in a standard ASP.NET MVC view
handle any possible updates by transferring any changes back from the ViewModel to the "proper" object and persisting that object
It's a bit more involved than I'd like it to be - but I quite honestly don't see how else you can do this otherwise.
We're beginning to design a whole bunch of new services to create (WCF, ADO.NET Data Services, possibly in the cloud at some point) and one question that pops up is what authentication and authorization scheme to use - there are quite a few!
We basically need to be able to identify users (actual people, and "virtual" application/service users) on a wide variety of protocols - HTTP, HTTPS, TCP - and we need to assign them at least a bunch of roles / permission to see certain data and/or do certain operations.
We definitely can't use Windows group membership alone - we have plenty of external consumers of our services and we don't want to have to set up a domain account in our internal domain for everyone of them.
So there's mainly three options, I think:
Using the ASP.NET membership system - create users and assign roles there
Use AzMan (Authorization manager) which seems to be a more granular, more mature, more elaborate system (with users, tasks, groups - three levels, not just user + roles)
Roll our own
First of all - which of these three would you recommend? Any why?
Secondly - are there more options that I'm missing?
Thanks for any hints, pointers, opinions!
Marc
PS: seeing the answers so far, I'm amazed at the amount of folks voting for option #3. I would have thought that MS would be able to design something reusable that could handle all of these requirements....
Actually, the answer is probably a combination of 1 and 3.
You can take advantage of a lot of the tools and features that the framework provides for you by writing a membership, role or profile provider if the default options don't quite go as far as you'd like.
We've done just that on a number of client sites - for example one of our clients has most of their users stored as Commerce Server users, and use the Commerce Server profile system, so we wrote a membership and profile provider to talk to those datastores - a fairly simple excercise.
Most people are probably going for 3 because of the need to authenticate over raw TCP - this introduces a layer beyond that of the standard ASP.NET membership providers.
Most of what MS produce is "ok" or "good enough", but there will always be edge cases where you want to do something "not quite standard" that mean you end up rolling your own. I guess to have something beyond "Basic Auth" or "Windows Auth" that was simple for your average developer to understand, they took the sensible option of "lets just build this for the web".
If you take a look at the numerous ways you can authenticate against a WCF service, you'll see what I mean - these are designed to handle different transport mechanisms, and are therefore much more complex.
That said, the default roles and profile providers are fairly limited (roles: no hierarchy, so you need to check for each possible role, or explicitly assign each role to the user; profiles: all stored in one field as comma seperated values - not easy to find all users who've got a value set).
We use (3). Actually that helped us in an integration scenery to have accounts in sync with
business processes
Other systems (not all on the same technology stack (ASP.NET))
On a recent project we extended the ASP.NET membership provider (wrote a custom provider) with the intent of using some of the role based controls for managing permissions. Now that the project has matured sufficiently, we're finding that the controls are not flexible enough for our requirements, and to some extent we're regretting going down the MS membership path. Rolling your own authentication if you have the time to architect it correctly is going to be the best option.
It sounds like your app is a bit of a hybrid in that you're serving internal and external customers, but perhaps also give some consideration to integrating OpenID for your external customers. There are some great ASP.NET OpenID controls that really makes handling new accounts for external customers a no brainer. This of course depends on how 'public' your application is.
Ldap anyone? It's free, cross-plaftorm, easy to use and administer remotely, has bridges to other auth schemes, and bindings in more languages that you knew existed...
Isn't AZMan from 2003?
I would recommend 1 or 3. Personally I've always gone for 3. There's a lot of functionality that 1 has that I don't use or care to use.
I would stay away from AzMan. We went down that road once and didn't like the section of town we broke down in. We've always done AD-based logins that use the SID of the current user to link to a user in the database, then taken the permissions from there. Given your setup this may not be possible (or practical), but I'd stay away from AzMan in any event.
I'm not an ASP or .NET developer, but my gut says (3). You really don't want a public-use web-app to have any sort of access to your corporate network, much less be able to put auth credentials anywhere near AD.
You seem to provide too much and too extensible to stick to one technological solution
Solution 3.
I would base the whole application around a User class
You would just simply have to model it so that it will provide you with the needed flexibility and extensibility
Something like:
[ClassAttribute ( "Yordan Georgiev", "1.0.2", "20090302", "20090415" , false )]
public class User
{
#region DomainName
private string _DomainName;
public string DomainName
{
get { return _DomainName; }
set { _DomainName = value; }
} //eof property DomainName
#endregion DomainName
#region Status
private int _Status;
public int Status
{
get { return _Status; }
set { _Status = value; }
} //eof property Status
#endregion Status
#region Password
private string _Password = Resources.GV.Pass;
public string Password
{
get { return _Password; }
set {
_Password = GenApp.Utils.Security.Encryptor.Encrypt ( value,
GenApp.Conf.GenAppSettings.Instance.EncryptionAlgorithm );
//debug_Password = value; //unencrypted
}
} //eof property Password
#endregion Password
#region ListUserRoles
private List<UserRole> _ListUserRoles;
public List<UserRole> ListUserRoles { get { return _ListUserRoles; } set { _ListUserRoles = value; } }
#endregion ListUserRoles
#region UserSettings
private GenApp.Conf.UserSettings _UserSettings;
public GenApp.Conf.UserSettings UserSettings
{
get {
if (_UserSettings == null)
_UserSettings = (GenApp.Conf.UserSettings)GenApp.Conf.GenAppSettings.Instance;
return _UserSettings;
}
set { _UserSettings = value; }
} //eof property UserSettings
}
In my project many tables are linked to aspnet_Application table by ApplicationId foreign key. I don't want the users to view or edit it, so I'm looking for way to preset this sql table field value before the insert query is executed. I still have scaffolding enabled for this column (in order for DD to generate the right sql script) but I'm hiding this column/field in all my edit/list/insert pages.
Ideally I'm looking for a place to inject my code right before DynamicInsert is executed for any table in my LinqToSql class.
Thanks
So after some digging around I came up with an acceptable solution. I've created a partial class for my data context and added a partial Insert_ method for every table that's linked to the aspnet_Applications. In every method I set the ApplicationId field to current application id.
It looks like this:
public partial class MyDataContext
{
partial void InsertMyTable(MyTable instance)
{
instance.ApplicationId = HttpContext.Current.Session["ApplicationId"] as Guid?;
this.ExecuteDynamicInsert(instance);
}
}
Note that you can't execute other LINQ statements while in this method. In particular I had to store the application id in session rather than querying the aspnet_Applications table.
While this is acceptable solution it isn't perfect (a lot of repetitive code) so if anyone knows better throw me a bone here :)
In the future the best solution would be to use DomainService part of .Net RIA Services preview just released at MIX09 see there videos here:
.NET RIA Services - Building Data-Driven Applications with Microsoft Silverlight and Microsoft ASP.NET
Microsoft ASP.NET 4.0 Data Access: Patterns for Success with Web Forms
The first is an introl to .net RIA Services from the point of view od Silverlight but more of it applied to DD the second is David Ebbo's presentation at MIX and shows how DomainService works with DD I think this is the way forward as you can do all your business logic here in the DomainService.