GithubHelp home page GithubHelp logo

maxiomtech / mongodb.aspnet.identity Goto Github PK

View Code? Open in Web Editor NEW
196.0 35.0 92.0 535 KB

ASP.NET Identity provider that uses MongoDB for storage

License: MIT License

C# 86.89% CSS 0.40% ASP 0.08% HTML 4.03% JavaScript 8.59%

mongodb.aspnet.identity's Introduction

MongoDB.AspNet.Identity

ASP.NET Identity provider that users MongoDB for storage

Purpose

ASP.NET MVC 5 shipped with a new Identity system (in the Microsoft.AspNet.Identity.Core package) in order to support both local login and remote logins via OpenID/OAuth, but only ships with an Entity Framework provider (Microsoft.AspNet.Identity.EntityFramework).

News

02-11-2014 - [http://blogs.msdn.com/b/webdev/archive/2014/02/11/announcing-preview-of-microsoft-aspnet-identity-2-0-0-beta1.aspx](Microsoft has released Microsoft.AspNet.Identity v2 Beta 1). I will be addressing these issues and introducing them into the MongoDB.AspNet.Identity provider.

Features

  • Drop-in replacement ASP.NET Identity with MongoDB as the backing store.
  • Requires only 1 mongo document type, while EntityFramework requires 5 tables
  • Contains the same IdentityUser class used by the EntityFramework provider in the MVC 5 project template.
  • Supports additional profile properties on your application's user model.
  • Provides UserStore implementation that implements the same interfaces as the EntityFramework version:
    • IUserStore
    • IUserLoginStore
    • IUserRoleStore
    • IUserClaimStore
    • IUserPasswordStore
    • IUserSecurityStampStore
    • IUserEmailStore (1.0.7)
    • IUserLockoutStore<TUser, string> (1.0.7)
    • IUserTwoFactorStore<TUser, string> (1.0.7)

Instructions

These instructions assume you know how to set up MongoDB within an MVC application.

  1. Create a new ASP.NET MVC 5 project, choosing the Individual User Accounts authentication type.
  2. Remove the Entity Framework packages and replace with MongoDB Identity:
Uninstall-Package Microsoft.AspNet.Identity.EntityFramework
Uninstall-Package EntityFramework
Install-Package MongoDB.AspNet.Identity
  1. In ~/Models/IdentityModels.cs:
    • Remove the namespace: Microsoft.AspNet.Identity.EntityFramework
    • Add the namespace: MongoDB.AspNet.Identity
    • Remove the ApplicationDbContext class completely.
  2. In ~/Controllers/AccountController.cs
    • Remove the namespace: Microsoft.AspNet.Identity.EntityFramework
    • Add the connection string name to the constructor of the UserStore. Or empty constructor will use DefaultConnection
  3. In ~/App_Start/IdentityConfig.cs
    • Remove reference to ApplicationDbContext
    • Amend ApplicationUserManager to inherit UserManager<ApplicationUser, string>. Also amend parameter for ApplicationUser.GenerateUserIdentityAsync
  4. In ~/App_Start/Startup.Auth.cs
    • Remove app.CreatePerOwinContext(ApplicationDbContext.Create);
AccountController requires a parameterless constructor. 
You could instantiate the UserManager in this contructor using any the UserStore constructors.
public AccountController()
{
    //examples
    this.UserManager = 
    new ApplicationUserManager(new UserStore<ApplicationUser>("MyConnection"));
}

Connection Strings

The UserStore has multiple constructors for handling connection strings. Here are some examples of the expected inputs and where the connection string should be located.

1. SQL Style

UserStore<TUser>(string connectionNameOrUrl)

UserStore("Mongo")

web.config

<add name="Mongo" connectionString="Server=localhost:27017;Database={YourDataBase}" />

2. Mongo Style

UserStore<TUser>(string connectionNameOrUrl)

UserStore("Mongo")

web.config

<add name="Mongo" connectionString="mongodb://localhost/{YourDataBase}" />

OR

UserStore<TUser>(string connectionNameOrUrl)

UserStore("mongodb://localhost/{YourDataBase}")

Thanks To

Special thanks to David Boike whos RavenDB AspNet Identity project gave me the base for jumpstarting the MongoDB provider

mongodb.aspnet.identity's People

Contributors

asitebro avatar jsheely avatar runxc1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongodb.aspnet.identity's Issues

dll version conflict

Using mongo driver 1.9.x in project but MongoDb.identity uses 1.8.5 driver, hence compiler error.

Fork needed to update dll version ? possible to remove strong version binding?

On Version 1.0.5 Error in ApplicationUser

I have downloaded the package from NuGet and maybe it's not updated, because after installing the package found an error on ApplicationUser.
In ApplicationUser, for user Email property is not there.

Even I tried with test application but found that in the test application version used is 1.0.7.
On test application, DLL reference is missing for version 1.0.7

ApplicationUser Update

How can I update user info? I use a construction like below but have an exaction in this string: await db.UpdateAsync(model). Bad usage?

    public async Task<ActionResult> EditProfile()
    {
        var db = new UserStore<ApplicationUser>("MongoLab");
        var user = await db.FindByIdAsync(User.Identity.GetUserId());
        return View(user);
    }

    [HttpPost]
    public async Task<ActionResult> EditProfile(ApplicationUser model)
    {
        var db = new UserStore<ApplicationUser>("MongoLab");
        var user = await db.FindByIdAsync(User.Identity.GetUserId());
        await db.UpdateAsync(model);
        //await db.DeleteAsync(user);
        //await db.CreateAsync(model);

        return View();
    }

Connection string issues

Two issues with the UserStore code.

  1. The parameter name to the constructor is databaseName which is misleading. It should be connectionName or something similar.

  2. No matter what connection string I used, such as the standard URI connection scheme, I received a "Format of the initialization string does not conform to specification starting at index 0." error. Changing the constructor code to:

        var conString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;

        var databaseName = MongoUrl.Create(conString).DatabaseName;
        var server = new MongoClient(conString).GetServer();

        db = server.GetDatabase(databaseName);

Fixed the issue.

Thanks.

Asp.net Identity 2.0

Hi -

Thanks for this project! I see you have a v2 branch.

Do you have a list of of tasks for this release?

I may be able to help.

Thanks,
Jon

Issues with latest MVC 5 web api

I have created a Web api project and tried to use this but get several issues

When I insert
this.UserManager = new UserManager(new UserStore("Mongo"));

In the default constructor I get

Severity Code Description Project File Line
Error CS0266 Cannot implicitly convert type 'Microsoft.AspNet.Identity.UserManager<WebApplication2.Models.ApplicationUser>' to 'WebApplication2.ApplicationUserManager'. An explicit conversion exists (are you missing a cast?) WebApplication2 C:\Git\Foosball9000\WebApplication2\Controllers\AccountController.cs 30

In IdentityConfig and Startup.Auth.cs there is a reference to ApplicationDbContext which I deleted, what should that be replaced with?

RegisterExternal in Accountcontroller have
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

But email is not defined in ApplicationUser, should that just be replaced with Id?

Hope this project is not dead :)

Branch V2: UserManager.Users is null

Hi,

I have setup branch V2 in my project. I can register users. It works perfectly.

However, when I use my usermanager and want to get all the users, the property is null.

I have one user in my mongo db.

Would you know what is the cause?

Is it a bug?

My init setup:

 // Configure the db context and user manager to use a single instance per request
//app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

Thanks,

Role Management?

I love the work you guys have done here. I am trying to implement this provider, but I'm running up against issues with the Roles part of it. I see that there's a Roles array created in the document, but I don't see anything in the code that would actually find/create/update/destroy that array. Am I missing something, or has it not yet been implemented?

Items to complete for V2

Right now the major items left for v2 are

  • User which allows user to specific the type for the Id field. int,string,guid, etc. Since we currently use ObjectId it makes the ObjectId.Parse() feature difficult. This feature may get removed for the MongoDB implementation.
  • RoleStore - In this version I will be implementing IdentityRole which requires a backing store to handle the data instead of saving Roles in an non-normalized string array.
  • Testing

External Database - Format of the initialization string does not conform to specification starting at index 0

When we use a local database using the IP number inside the connection string the solution recognizes perfectly, but when I use an external MongoDB provider like MongoHQ or MongoLab it throws an error.

Error: Format of the initialization string does not conform to specification starting at index 0.

Usually, this error is thrown when we have a bad connection string format using SQL,Oracle, MySql, etc...

What I dont understand is when I use the same connectionstring URI like below it works


static MongoDatabase retreive_mongohq_db()
        {
            return MongoServer.Create(
                ConfigurationManager.ConnectionStrings["MONGO"].ConnectionString)
                .GetDatabase("mydb");
        }

But when I do like below it doesnt


public UserManager(): base(new UserStore("MONGO"))
        {
            
        }

User.Identity.GetUserId() returns null

Could be I'm doing something wrong in my configuration, but when I try to use this extension method, I get a null value returned. After peeking the definition of the method, it's trying to get the user id via the Claims collection for the user, for which there aren't any. The user has an _id value, but Claims is empty. Specifically, the method tries to find the NameIdentifier claim(which I thought was odd usage for that).

Have you seen this before? Any thoughts on what I could be doing wrong? Happy to elaborate if needed.

Error on UserManager.FindById

When running this code:

UserManager.FindById(User.Identity.GetUserId())

I get an error stating that "some guid" is not a valid 24 digit hex string... Right now GetUserId seems to be returning a Guid as a string. If I change this to be:

UserManager.FindById(MongoDB.Bson.ObjectId.GenerateNewId().ToString())

... It works as expected. The problem is that obviously this won't work in the real world, but it does seem that FindById is expecting an ObjectId.

Am I missing something?

Thanks!

Return list of users

Removing the ApplicationDBContext removes the ability to fetch all the users easily.

E.g.:

  var context = new ApplicationDbContext();
  var allUsers = context.Users.ToList();

Any ideas on support for this?

Additional user information.

That the part of project where I can add any personal info like phone, email, blog post etc related to sucessfully logined user? What the common scheme? Schould I inherit UserStore class, should I do something with "AspNetUsers" collection or have to create outstanding one?

User Collection Name

Thank you for putting up the project.

As I can see it in the project, the users' collection name is fixed to "AspNetUsers". Is there any plans on customizing this to be changed based on property/constructor?

Claims with private setter and duplicate Id field

Thanks a lot for this project!

I'm working through the ins & outs of claims in ASP.NET Identity for my project and found a few things I don't understand in your code:

  1. Why is the setter for Claims and Roles in IdentityUser private? By having it public, these properties could be added to the user model right on creation with just one trip to the db instead of two.
  2. Why are you repeating the Id and UserId on IdentityUserClaim when it's a nested array in the mongo "schema"? Is it required by the framework?

Thanks!

Connection problem to mongodb database

I follow the procedure for installation but i have the bellow issue :

[NullReferenceException: La référence d'objet n'est pas définie à une instance d'un objet.]
MongoDB.Driver.MongoServerInstance.RefreshStateAsSoonAsPossible() +70
MongoDB.Driver.Internal.MongoConnection.HandleException(Exception ex) +24
MongoDB.Driver.Internal.MongoConnection.SendMessage(BsonBuffer buffer, Int32 requestId) +191
MongoDB.Driver.Internal.MongoConnection.SendMessage(MongoRequestMessage message) +125
MongoDB.Driver.Operations.CommandOperation`1.Execute(MongoConnection connection) +206
MongoDB.Driver.MongoServerInstance.RunCommandAs(MongoConnection connection, String databaseName, IMongoCommand command) +189
MongoDB.Driver.MongoServerInstance.Ping(MongoConnection connection) +316
MongoDB.Driver.MongoServerInstance.Connect() +371
MongoDB.Driver.Internal.DirectMongoServerProxy.Connect(TimeSpan timeout, ReadPreference readPreference) +222

[MongoConnectionException: Unable to connect to server ds041160.mlab.com:41160: La référence d'objet n'est pas définie à une instance d'un objet..]
MongoDB.Driver.Internal.DirectMongoServerProxy.Connect(TimeSpan timeout, ReadPreference readPreference) +804
MongoDB.Driver.Internal.DirectMongoServerProxy.ChooseServerInstance(ReadPreference readPreference) +93
MongoDB.Driver.MongoServer.AcquireConnection(ReadPreference readPreference) +227
MongoDB.Driver.MongoCursorConnectionProvider.AcquireConnection() +26
MongoDB.Driver.Operations.QueryOperation1.GetFirstBatch(IConnectionProvider connectionProvider) +91 MongoDB.Driver.Operations.<Execute>d__0.MoveNext() +113 System.Linq.Enumerable.FirstOrDefault(IEnumerable1 source) +121
MongoDB.Driver.MongoCollection.FindOneAs(IMongoQuery query) +120
MongoDB.Driver.MongoCollection1.FindOne(IMongoQuery query) +51 MongoDB.AspNet.Identity.UserStore1.FindByNameAsync(String userName) +127
Microsoft.AspNet.Identity.UserManager2.FindByNameAsync(String userName) +56 Microsoft.AspNet.Identity.<ValidateUserName>d__4.MoveNext() +392 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 Microsoft.AspNet.Identity.<ValidateAsync>d__0.MoveNext() +266 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 Microsoft.AspNet.Identity.<CreateAsync>d__0.MoveNext() +568 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 Microsoft.AspNet.Identity.<CreateAsync>d__d.MoveNext() +483 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +28
WebApplication1.Controllers.d__15.MoveNext() in d:\Users\lbettah\Documents\Visual Studio 2015\Projects\WebApplication1\WebApplication1\Controllers\AccountController.cs:155
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +97
System.Web.Mvc.Async.<>c__DisplayClass37.b__36(IAsyncResult asyncResult) +17
System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3d() +50
System.Web.Mvc.Async.<>c__DisplayClass46.b__3f() +225
System.Web.Mvc.Async.<>c__DisplayClass33.b__32(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass2b.b__1c() +26
System.Web.Mvc.Async.<>c__DisplayClass21.b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9644037
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Can I use v2 branch?

Is v2 ready to use? I tried to use yesterday but its not complete as I already knew.. there are few points missing.. I will try again today 26/05 since jshelly made a commit today.. to see if it will throw any error..

Incompatible with 2013 SPA template

I created an SPA project and followed the steps to convert to MongoDB. There are more differences than has been noted and more work to make this work needs to be done. It looks like the original developer isn't supporting it, so one of us needs to fork it and fix it. I may spend some time on it, but it would be nice to get others to pitch in.

UserStore.FindAsync Incorrect Query Logic

Thanks for the work on this. I found a bug while I was "borrowing" your existing work and thought I would help. I don't plan to use this library verbatim at this point so instead of submitting a commit I will just comment below:

The UserStore FindAsync implementation is incorrect. Although the query will probably match the user most of the time it will yield the wrong user in some cases. It is also not as performant as the suggested change.

user = _users
    .FindOne(Query.And(Query.EQ("Logins.LoginProvider", login.LoginProvider), 
        Query.EQ("Logins.ProviderKey", login.ProviderKey)));

Should be changed to use ElemMatch which actually compares two values of the same element of an array instead of two distinct properties of any of the array values.

var user = _users.FindOne(
                Query<TUser>.ElemMatch(i => i.Logins, i => Query.And(
                    Query<UserLoginInfo>.EQ(loginRow => loginRow.LoginProvider, login.LoginProvider),
                    Query<UserLoginInfo>.EQ(loginRow => loginRow.ProviderKey, login.ProviderKey))));

I haven't tested the change but I do know ElemMatch is what should be used for a query on multiple properties of a single array element. Wanted to let you know before I moved on. Thanks again for the work on this!

Not an issue, just for those who might be trying to configure MongoDB.AspNet.Identity with Web API 2

Well, the current version of MongoDB.AspNet.Identity works like a charm with ASP.NET MVC 5 and MVC 4 and WebForms as far as I used in my personal projects.

Currently, I'm working on a Web API based solution and came to my mind to keep using MongoDB as my main db.

Basically, to configure MongoDB.AspNet.Identity with Web API I followed the steps bellow:

1)Create new class inside AccountBindingModels.cs to keep all models together

public class ApplicationUser : IdentityUser
    {
        [Required]
        public string Email { get; set; }
    }

this is because the Web API project template doesn't generate a IdentityModel.cs instead it creates a AccountBindingModels.cs to store all binding models... as the file name says...

  1. Replace all IdentityUser references with ApplicationUser inside AccountController.cs, ApplicationOAuthProvider.cs and Startup.Auth.cs

  2. Pass your connectionstring name as a parameter in Startup.Auth.cs as below

UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>("Mongo"));

4)Replace all IdentityUserLogin with UserLoginInfo inside AccountController.cs

5)Update the Register inside AccountController to store Email property like

ApplicationUser user = new ApplicationUser
{
       UserName = model.UserName,
       Email =  model.Email
};

Notes: The steps above worked for me and might not work at a different environment since I had no time to set up this again in a new solution. I created this project 06/May/14, Tuesday, with the latest version of this library and mongocsharpdriver.

Hope to get a feedback around this to recognize this as a step-by-step to configure the MongoDB.AspNet.Identity with Web API projects.

Look forward to hear from you guys!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.