Git Product home page Git Product logo

ravendb.identity's People

Contributors

abremora avatar esenciadev avatar jbuedel avatar joshclose avatar judahgabriel avatar lahma avatar luis-fss avatar scattered-code avatar wagich 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

Watchers

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

ravendb.identity's Issues

How to handle unique constraints in a user?

Hi,

I'm new to both asp.net core identity and your project and I was wondering how to tackle the need for unique constraints, for example for the username. At what level can it be done?
Thanks

sample missing some information from traditional rdb,

Hello can you update the sample,

  • like traditional RDB/sql express or MOngoDb, does the Raven Identity use a separate DbContext, what is the recommended guidance here?
  • Also how do you manage linked claims to
  • The samples are missing the views from the scaffold, can you please share those, especially around the user/role/claims manager

Default Identity - considerations

Now that this project has switched to Razor from MVC, it makes sense that there should be a non-default identity scaffold project so that users can customize the files without figuring out how to generate them. The "hidden" scaffold identity files are more of a nuisance than helpful as most people aren't going to use the project as a starting point without being able to modify the files.

Here's Microsoft's documentation on the subject:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-2.2&tabs=netcore-cli

Thoughts?

8.0.9 of RavenDB.Identity SignInManager

Hi, currently I am working with a RavenDB store.
I found this nice plugin, but I got a little stuck.
Unfortunately, my client is not yet working with .Net 8, so I am stuck at .Net 6 for now.
That means that I am using nog the latest version, but version 8.0.9 of RavenDB.Identity.

I have the following configurations

   services
                .AddRavenDbDocStore() // Create our IDocumentStore singleton using the database settings in appsettings.json
                .AddRavenDbAsyncSession() // Create an Raven IAsyncDocumentSession for every request.
                .AddIdentityCore<MyUser>()
                .AddRoles<IdentityRole>()
                .AddRavenDbIdentityStores<MyUser, IdentityRole>(); // Use Raven as the Identity store for user users and roles.

Now my problem is that my signInManager is missing because that's was added in a different package.

I tried using .AddSignInManager<SignInManager>() but that gave me all kinds of dependency injection errors since I needed to add Microsoft.AspNetCore.Identity

Any idea what am I not seeing?

UserStore: UpdateAsync and other methods not updating documents?

Hi,

After configuring the RavenDB.Identity stores, I'm trying to add a user and also some claims to the user.

I see that the document representing the user get's created in the database, but the claims collection is still empty after adding the claims.

    alice = new ApplicationUser
    {
        UserName = "alice",
        Email = "[email protected]",
        EmailConfirmed = true,
    };

    // This creates the document in RavenDB as SaveChangesAsync is called
    // internally in the UserStore
    var result = userMgr.CreateAsync(alice, "Pass123$").Result;
    if (!result.Succeeded)
    {
        throw new Exception(result.Errors.First().Description);
    }

    // This doesn't update the ApplicationUser document, as
    // the UserStore implementation based on Raven only updates
    // the entity, but doesn't try to call SaveChangesAsync
    result = userMgr.AddClaimsAsync(alice, new Claim[]{
            new Claim(JwtClaimTypes.Name, "Alice Smith"),
            new Claim(JwtClaimTypes.GivenName, "Alice"),
            new Claim(JwtClaimTypes.FamilyName, "Smith"),
            new Claim(JwtClaimTypes.WebSite, "http://alice.com"),
        }).Result;
    if (!result.Succeeded)
    {
        throw new Exception(result.Errors.First().Description);
    }

    // Even forcing an update of the user does not call internally DbSession.SaveChangesAsync()
    // as only email changes are tracked to try to update the email reservation.
    userMgr.UpdateAsync(alice).Wait();

    Log.Debug("alice created");

Following the code in UserStore.cs, I'm a little bit confused that only CreateAsync and DeleteAsync actually persist immediatly calling ravenSession.SaveChangesAsync. I wonder if this behavior is something documented or expected by aspnet identity UserManager. Shouldn't all of these methods try to update the database as eagerly as possible?

Thanks!

Germán

Two-factor authentication error: "Store does not implement IUserAuthenticatorKeyStore<User>"

(there's a discussion about this error on another project's issues list mrahhal/MR.AspNet.Identity.EntityFramework6#12)

When clicking on Two-factor authentication at /Manage/Index, I'm taken to /Manage/TwoFactorAuthentication and get the following error:

An unhandled exception occurred while processing the request.
NotSupportedException: Store does not implement IUserAuthenticatorKeyStore.
Microsoft.AspNetCore.Identity.UserManager.GetAuthenticatorKeyStore()

Here's the entire stack:
NotSupportedException: Store does not implement IUserAuthenticatorKeyStore.
Microsoft.AspNetCore.Identity.UserManager.GetAuthenticatorKeyStore()
Microsoft.AspNetCore.Identity.UserManager.GetAuthenticatorKeyAsync(TUser user)
Sample.Controllers.ManageController+d__22.MoveNext() in ManageController.cs
+
var model = new TwoFactorAuthenticationViewModel
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d__12.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d__10.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d__14.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware+d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware+d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware+d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

8.0.7 on Nuget, source says 8.0.6

Just a quick one, the public Nuget package, changelog and source code here seem out of sync.

Perhaps you could consider tagging the repo to co-incide with Nuget packages?

Calling userManager.FindByEmailAsync right after userManager.CreateAsync return null but on breakpoint its fine

Hi,
So the plan is to register a user and then put the AccountId into the Person document and save the person document with that AccountId and the reason here is that the person can have different accounts and I cannot put them under the Person document because first it gets too big for no reason and second, the accounts are not independent.
So I'm creating the account like,

await _userManager.CreateAsync(request.GetAccount(), request.Password);

then after the creation successful check I want to read the account with

await _userManager.FindByEmailAsync(request.EmailAddress)

to get the account and eventually get the Id of the account to put under the person table.

The problem is that after waiting on the creation and getting success the creation is not actually finished on the database so it causes me to receive null on finding the user. it works if on finding the user I set a breakpoint then step forward and then my account is there which means it is waited enough for the database to actually put the record in the database.

Support RequireUniqueEmail

Hello

Actually the UserStore will throw exception about email uniqueness even if RequireUniqueEmail is set to false.

Solutions:

  1. support the parameter
  2. Remove the code to check the email and let the default UserValidator do the job
  3. Create a new RavenDBUserValidation to replace with the default with compare/exchange.

Add Login

I know the problem is with the UserLoginInfo class. But how to solve this?

An unhandled exception occurred while processing the request.
PlatformNotSupportedException: This instance contains state that cannot be serialized and deserialized on this platform.
System.Security.Claims.ClaimsPrincipal.OnSerializingMethod(StreamingContext context)

TargetInvocationException: Exception has been thrown by the target of an invocation.
System.RuntimeMethodHandle.InvokeMethod(object target, Object[] arguments, Signature sig, bool constructor)

Lowercase roles and JWT tokens

I see in UserStore.AddToRoleAsync, the roleName is getting ToLower called on it and that is what is being stored in the users roles array.

I'm using Microsoft.AspNetCore.Authentication.JwtBearer for authentication. I create claims for the roles which are all lowercase. I have a role SiteAdmin that is stored as siteadmin under the user. The lowercase version is shipped off to the client. When the client makes requests, it sends that lowercase version to the server to authenticate.

I have controller actions that I'm decorating with Authorize(Roles = "SiteAdmin) because that is how I created it when doing AddToRoleAsync(user, "SiteAdmin"). This doesn't work though because the JWT token has the lowercase version in it.

Why are you doing a ToLower on the roleName? I did notice that it comes in normalized as an uppercase string, but curious if there is a specific reason you're lowering it. I also see that a role is created if it doesn't already exist, and that is using the lowercase name also. This seems a little odd especially if the user has extended IdentityRole and added some extra properties.

Since the roleName comes in normalized, do you see any issue with finding the role in the db first, and using the normal non-normalized name to store in IdentityUser.Roles instead so it matches IdentityRole.Name?

I believe all of this is only manifested because I'm using a JWT and it doesn't re-lookup the claims on an Authorize.

User Id configuration not consistent with RavenDB

Is it possible to configure the id generation to auto generate ids rather then server generated? I Prefer users/1-A rather then users/0000000000000001074-A.

I use services.Configure<RavenIdentityOptions>(options => options.UserIdType = UserIdType.ServerGenerated); but according to the docs the id should be in the auto generated format rather then server generated.

Screenshot 2020-07-26 at 09 53 50

IMO RavenDB.Identity should be more consistent with how RavenDB works.

If I add users| to my Users class like this

public class User : Raven.Identity.IdentityUser {
    public User() {
        Id = "users|";
    }
}

I expect the Id to be users/1 not users/0000000000000001074-A but that does not work either?

UserStore<T>MigrateToV6() does not work for DocumentStore with Conventions.FindCollectionName set

We initialize our stores like that, because we feel it is more natural:

var store = new DocumentStore {
    Certificate = clientCertificate,
    Urls = new[] { url },
    Database = database,
    Conventions = {
        FindCollectionName = t => t.Name,
        UseOptimisticConcurrency = useOptimisticConcurrency
    }
};
store.Initialize();

So our documents start with IdentityUserByUserName/. But in UserStore.MigrateToV6() the document prefix is hard coded:

var stream = dbSession.Advanced.Stream<IdentityUserByUserName>("IdentityUserByUserNames/");

Maybe the best would be an overloaded method to set the prefix manually.

Delegate to modify conventions

Method to add the document store needs to take a delegate that can modify conventions on the doc store before it is initialized

Web API and Authorize with Roles

When using this with an API project in a SPA I'm having trouble locking down certain end points to specific roles.

  1. When the [Authorize] attribute denies a request it tries to redirect the 401 to the "Account/Login" page. As I'm using a SPA and an API how do I stop this so it correctly returns 401 from the api call?

I've tried adding this to the Startup file to convert the api redirects to 401, however it doesn't work correctly.

    services.AddAuthentication(opts =>
                {
                    opts.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    opts.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                })
                .AddCookie(opts =>
                {
                    opts.Cookie.Name = ".AspNetCore.Identity.Application";
                    opts.Events = new CookieAuthenticationEvents()
                    {
                        
                        OnRedirectToLogin = ctx =>
                        {
                            if (ctx.Request.Path.StartsWithSegments("/api") && ctx.Response.StatusCode == 200)
                            {
                                ctx.Response.StatusCode = 401;
                                return Task.FromResult<object>(null);
                            }

                            ctx.Response.Redirect(ctx.RedirectUri);
                            return Task.FromResult<object>(null);
                        }
                    };
                });
  1. It correctly authorizes when not logged in, or logged in. But when I add [Authorize(Roles = "ADMIN")] I can no longer access this route because of being unauthorized.

My user is in the "ADMIN" role, I have confirmed in the RavenDB that the user has this set in the Roles array.
await _userManager.AddToRoleAsync(user, "ADMIN");

Blazor WASM (only) and no server backend?

I'm a long-time .NET developer. I'm playing w/ Blazor WASM (no asp.net core backend) and am wondering whether I can use this package to go directly to a RavenDB cloud instance without the support of using a .net core controller.

My goal is to load the Blazor WASM app as just a bunch of static files, and then interact directly w/ RavenDB cloud...

(BTW: I like what you've done here. You seem to be very committed to RavenDB as a database. I'm looking for experience in alternatives to SQL databases & RavenDB seems to be one of the only ones offering free hosting for developers. I looked at CosmosDB some time ago, but they didn't have anything for Identity in CosmosDB until very recently. And Firebase doesn't really have any really good C# packages.)

Should call SaveChanges after deleting a user

RavenDB docs states that entities can be marked for deletion by using the Delete method, but will not be removed from the server until SaveChanges is called

Code in question:

DbSession.Delete(user); // It's possible user is already saved to the database. If so, delete him.

Suggestion:

DbSession.Delete(user.Id); // It's possible user is already saved to the database. If so, delete him.await

DbSession.SaveChangesAsync(cancellationToken);

UserManager.ConfirmEmailAsync not working

I'm implementing an email address confirmation controller action. I get the user, call ConfirmEmailAsync, and see that User.EmailConfirmed = true, but it doesn't get saved in RavenDB. I tried adding Session.SaveChangesAsync(), but that didn't help. The only way I could get it working was to re-get the user from the Session directly, set User.EmailConfirmed = true and do SaveChangesAsync().

var user = await userManager.FindByEmailAsync(email);
if (user == null)
{
	return NotFound();
}

var result = await userManager.ConfirmEmailAsync(user, code);

if (result.Succeeded)
{
	user = await Session.Query<User>().SingleAsync(u => u.Email == email);
	user.EmailConfirmed = true;
	await Session.SaveChangesAsync();

	return Redirect("~/account/email-confirmed");
}

return Redirect("~/account/confirm-email-error");

I looked at UserManager.store and it's an instance of Raven.Identity.UserStore.

Here is a log of what goes through RavenDB when I don't have the extra 3 lines to re-get the user.

[
  {
    "TimeStamp": "2019-12-09T00:21:03.9275580Z",
    "RequestId": 27,
    "HttpMethod": "POST",
    "ElapsedMilliseconds": 0,
    "ResponseStatusCode": 304,
    "RequestUri": "http://127.0.0.1:8080/databases/InfinitWifi/queries?queryHash=3841586971965068908",
    "AbsoluteUri": "http://127.0.0.1:8080",
    "DatabaseName": "InfinitWifi",
    "CustomInfo": "from Users where Email = $p0 limit $p1, $p2\r\n{\"p0\":\"[email protected]\",\"p1\":0,\"p2\":1}",
    "Type": "Queries"
  },
  {
    "TimeStamp": "2019-12-09T00:21:03.9351362Z",
    "RequestId": 28,
    "HttpMethod": "GET",
    "ElapsedMilliseconds": 0,
    "ResponseStatusCode": 200,
    "RequestUri": "http://127.0.0.1:8080/databases/InfinitWifi/cmpxchg?&key=emails%2Fme%40gmail.com",
    "AbsoluteUri": "http://127.0.0.1:8080",
    "DatabaseName": "InfinitWifi",
    "CustomInfo": "N/A",
    "Type": "None"
  },
  {
    "TimeStamp": "2019-12-09T00:21:03.9454399Z",
    "RequestId": 29,
    "HttpMethod": "GET",
    "ElapsedMilliseconds": 0,
    "ResponseStatusCode": 304,
    "RequestUri": "http://127.0.0.1:8080/databases/InfinitWifi/docs?&id=users%2Fme%40gmail.com",
    "AbsoluteUri": "http://127.0.0.1:8080",
    "DatabaseName": "InfinitWifi",
    "CustomInfo": "users/[email protected]",
    "Type": "Documents"
  }
]

SignInAsync throws unhelpful exception when `Conventions.FindIdentityProperty` is used.

We've mapped our document Ids to DocumentID. When registering a new user I call SignInManager.SignInAsync<AppUser>(...) and get an ArgumentNullException.

Overriding AppUser.Id, like so, fixes it.

   public class AppUser : IdentityUser
   {
      public override string? Id => DocumentID;
      public string DocumentID { get; set; }
   }

The exception is:

dbug: Raven.Identity.UserStore[0]
      Creating email reservation for xjs@dkdk
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMC82JFR5V3L", Request id "0HMC82JFR5V3L:00000001": An unhandled exception was thrown by the application.
System.ArgumentNullException: Value cannot be null. (Parameter 'value')
   at System.Security.Claims.Claim..ctor(String type, String value, String valueType, String issuer, String originalIssuer, ClaimsIdentity subject, String propertyKey, String propertyValue)
   at System.Security.Claims.Claim..ctor(String type, String value)
   at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`1.GenerateClaimsAsync(TUser user)
   at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`2.GenerateClaimsAsync(TUser user)
   at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory`1.CreateAsync(TUser user)
   at Microsoft.AspNetCore.Identity.SignInManager`1.CreateUserPrincipalAsync(TUser user)
   at Microsoft.AspNetCore.Identity.SignInManager`1.SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable`1 additionalClaims)
   at AMS.Eclipse.Server.Controllers.ApiAuthenticationController.Register(RegisterParams registerParams) in C:\Users\jbuedel\Projects\EclipsePro-Design\src\AMS.Eclipse.Server\Controllers\ApiAuthenticationController.cs:line 114
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Connection id "0HMC82JFR5V3L", Request id "0HMC82JFR5V3L:00000001": An unhandled exception was thrown by the application. Value cannot be null. (Parameter 'value')

Our DocumentStore creation looks like this:

         var store = new DocumentStore
         {
            Conventions =
            {
               FindIdentityProperty = prop => prop.Name == "DocumentID",
               MaxNumberOfRequestsPerSession = 200
            },
            Urls = new[] { url },
            Database = databaseName
         };

My thought is maybe IdentityUser.Id should be removed and instead somehow resolve the document id property through the convention perhaps?

UserManager.AddToRolesAsync and UserManager.RemoveFromRolesAsync fails when roles are empty

If I call UserManager.AddToRolesAsync or UserManager.RemoveFromRolesAsync with an IEnumerable with 0 results, an exception is thrown.

The given key 'users/[email protected]' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Raven.Identity.UserStore`2.UpdateAsync(TUser user, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Identity.UserManager`1.UpdateUserAsync(TUser user)
   at Microsoft.AspNetCore.Identity.UserManager`1.RemoveFromRolesAsync(TUser user, IEnumerable`1 roles)

If I find some time I'll find the issue and submit a pull request, but I've been pretty busy lately.

AuthenticationTokens and AuthenticationProperties not updated on UpdateExternalAuthenticationTokensAsync

I use Github authentication with SaveTokens=true. When for the first time I get a new login on my user document. The login has both AuthenticationTokens and AuthenticationProperties.

In addition to that I also get IdentityUserAuthTokens documents and IdentityUserLogins document.

That seems fine and all but when I login a second time with the external login I run UpdateExternalAuthenticationTokensAsync and then it seems like it's only the IdentityUserAuthTokens documents that gets updated and not the user properties AuthenticationTokens and AuthenticationProperties.

AuthenticationProperties contains expires and so on so I guess that the user document also should get an update on UpdateExternalAuthenticationTokensAsync?

UpdateAsync does nothing

Hi I am using your library and CreateAsync works like a charm, but UpdateAsync does just nothing.

Compare exchange values get saved in the wrong database if session isn't pointing to the store's default database

If targeting a different database in the session other than the default database the store is initialized with, documents correctly go to the database configured in the IAsyncSession, however, Compare Exchange values go to the default database configured on the store.
Under most cases they would be the same, but in my case I'm building a multi-tenant application in which I store users in separate databases at runtime.

https://github.com/ops-ai/BeyondAuth/blob/b35d86d6451edba74b03bad1b55b40a6e87332a2/src/Authentication/Startup.cs#L328

Part of the fix is simple, just adding .ForDatabase here:

return DbSession.Advanced.DocumentStore.Operations.SendAsync(reserveEmailOperation);

However, getting the current database from the session seems to be tricky. Happy to create a PR once I figure it out if you're interested

What is the purpose of IdentityUserByUserName

I'm curious about why you are creating multiple models stored with a custom id generation and so forth. I can see a comment here but I don't understand why?

In my own provider I just do

using (var session = _documentStore.OpenAsyncSession())
{
    var userByName = session.Query<TUser>().SingleOrDefaultAsync(x => x.NormalizedUserName.Equals(normalizedUserName));
    if (userByName == null)
    {
        return Task.FromResult(default(TUser));
    }
    return userByName;
}

in FindByNameAsync.

Use static indexes instead of dynamic

Would you accept PR for adding usage of static indexes which would also allow waiting from them in certain operations. For example after adding using the API can return null because indexes aren't in sync yet. The preferred logic would be with having proper UserIndex:

  • add user document
  • wait for UserIndex to index to latest point in time
  • return from add method

We have prohibited dynamic indexes in general in development mode so that we don't get any surprising new indexes in production.

Register User: The email address ... is already taken.

Hi,

when I register a new User, the user is created and it works well.
After that I deleted this User in the RavenDB. Then I tried to Register the same email adress again, and it fails telling me: "The email address ... is already taken."
How is this possible, after i deleted the User in the database? I restarted the database and the demo application, but the email adress cannot be registered again. Is there anything I did wrong?

Thanks in advance, keep up your good work!
Bye

Clash between expected User.Id "Collection/HiLo" and resulted "Collection/Email" - Error on UserManager.ResetPasswordAsync

When calling for
_userManager.ResetPasswordAsync(storeUser, token, newPassword)

I get failed result with the following error :

"ConcurrencyFailure"
"Unable to update user email."

The actual PassworsReset works, but error is thrown.

I think I use the same session to get the user, is it what's happening here ?
Why would it want to update user email ? :)

It was working fine a while back. But I can recall if bug happened after asp.core 3 or RavenDB.Identity 7.x

Thanks

Exception using RavenDB.Client 5.0.0

I get the following exception when I use RavenDB.Client 5.0.0 with RavenDB.Identity 7.0.1

System.MissingMethodException: Method not found: 'System.String Raven.Client.Documents.Conventions.DocumentConventions.get_IdentityPartsSeparator()'.
at Raven.Identity.RoleStore2.GetRavenIdFromRoleName(String role, IDocumentStore docStore) at Raven.Identity.RoleStore2.FindByNameAsync(String normalizedName, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Identity.RoleManager1.FindByNameAsync(String roleName) at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory2.GenerateClaimsAsync(TUser user)
at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory1.CreateAsync(TUser user) at Microsoft.AspNetCore.Identity.SignInManager1.CreateUserPrincipalAsync(TUser user)
at Microsoft.AspNetCore.Identity.SignInManager1.SignInWithClaimsAsync(TUser user, AuthenticationProperties authenticationProperties, IEnumerable1 additionalClaims)
at Microsoft.AspNetCore.Identity.SignInManager1.SignInOrTwoFactorAsync(TUser user, Boolean isPersistent, String loginProvider, Boolean bypassTwoFactor) at Microsoft.AspNetCore.Identity.SignInManager1.ExternalLoginSignInAsync(String loginProvider, String providerKey, Boolean isPersistent, Boolean bypassTwoFactor)
at Wieldy.Web.Controllers.AuthController.GithubCallback(String returnUrl, String remoteError) in /Users/marcus/Library/Mobile Documents/comappleCloudDocs/Projects/private/wieldy/src/web/Controllers/AuthController.cs:line 104
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Serialization error using dotnet core preview 8

I'm using version 6.1 of RavenDB.Identity with dotnet core preview 8.

My config looks like this:

services.Configure<RavenSettings>(Configuration.GetSection("RavenSettings"));
services.AddRavenDbDocStore()
    .AddRavenDbAsyncSession()
    .AddRavenDbIdentity<AppUser>()
    .AddDefaultUI();

services.AddAuthentication()
    AddGoogle(o =>
    {
        o.ClientId = "xxx.apps.googleusercontent.com";
        o.ClientSecret = "xxx";
    });

services.AddControllersWithViews().AddMvcOptions(o => o.Filters.Add<RavenSaveChangesAsyncFilter>());
services.AddRazorPages();

When I try to register a new account using Google I get a System.PlatformNotSupportedException: This instance contains state that cannot be serialized and deserialized on this platform. with the following stack trace.

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.PlatformNotSupportedException: This instance contains state that cannot be serialized and deserialized on this platform.
   at System.Security.Claims.ClaimsPrincipal.OnSerializingMethod(StreamingContext context)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Newtonsoft.Json.Serialization.JsonContract.<>c__DisplayClass57_0.<CreateSerializationCallback>b__0(Object o, StreamingContext context)
   at Newtonsoft.Json.Serialization.JsonContract.InvokeOnSerializing(Object o, StreamingContext context)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.OnSerializing(JsonWriter writer, JsonContract contract, Object value)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)
   at Raven.Client.Documents.Session.EntityToBlittable.ConvertEntityToBlittable(Object entity, DocumentInfo documentInfo) in C:\Builds\RavenDB-Stable-4.2\42017\src\Raven.Client\Documents\Session\EntityToBlittable.cs:line 43
   at Raven.Client.Documents.Session.InMemoryDocumentSessionOperations.PrepareForEntitiesPuts(SaveChangesData result) in C:\Builds\RavenDB-Stable-4.2\42017\src\Raven.Client\Documents\Session\InMemoryDocumentSessionOperations.cs:line 971
   at Raven.Client.Documents.Session.InMemoryDocumentSessionOperations.PrepareForSaveChanges() in C:\Builds\RavenDB-Stable-4.2\42017\src\Raven.Client\Documents\Session\InMemoryDocumentSessionOperations.cs:line 800
   at Raven.Client.Documents.Session.Operations.BatchOperation.CreateRequest() in C:\Builds\RavenDB-Stable-4.2\42017\src\Raven.Client\Documents\Session\Operations\BatchOperation.cs:line 32
   at Raven.Client.Documents.Session.AsyncDocumentSession.SaveChangesAsync(CancellationToken token) in C:\Builds\RavenDB-Stable-4.2\42017\src\Raven.Client\Documents\Session\AsyncDocumentSession.cs:line 135
   at WebApp3.RavenSaveChangesAsyncFilter.OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) in /Users/marcus/Temp/WebApp3/Startup.cs:line 181
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Maybe this has to do with the new System.Text.Json APIs? Or do you have any clue on whats has changed?

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.