1

RavenDB および RavenUserAuthRepository パッケージとともに、すぐに使用できる ServiceStack 認証プラグインを使用しようとしています。

AppHost

var store = new DocumentStore()
        {
            ConnectionStringName = "ServiceStackAuthSample"
        }
            .Initialize();

        IndexCreation.CreateIndexes(typeof(RavenUserAuthRepository).Assembly, store);

        container.Register(store);
        var session = container.Resolve<IDocumentStore>().OpenSession();
        container.Register(p => session).ReusedWithin(ReuseScope.Request);

        container.Register<IUserAuthRepository>(p => new RavenUserAuthRepository(p.Resolve<IDocumentStore>(), p.Resolve<IDocumentSession>()));

Facebook、GoogleOAuth、Twitter による最初の認証試行は、期待どおりに機能します。ただし、再認証を試みると、RavenDB が気に入らないようで、次のようになります。

エラー CodeNonUniqueObjectExceptionmessageAttempted が ID 'UserAuths/1'.stack Trace[Auth: 10/21/2013 6:51:04 PM]: [REQUEST: {provider:facebook}] Raven.Client.Exceptions.NonUniqueObjectException:別のオブジェクトを ID 'UserAuths/1' に関連付けようとしました。c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:Raven.Client.Document.InMemoryDocumentSessionOperations の行 778 の Raven.Client.Document.InMemoryDocumentSessionOperations.AssertNoNonUniqueInstance (オブジェクト エンティティ、文字列 ID)。 c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:Raven.Client.Document.InMemoryDocumentSessionOperations の 670 行目の StoreInternal (Object entity, Etag etag, String id, Boolean forceConcurrencyCheck)。2 authInfo) at ServiceStack.ServiceInterface.Auth.FacebookAuthProvider.Authenticate(IServiceBase authService, IAuthSession session, Auth request) at ServiceStack.ServiceInterface.Auth.AuthService.Authenticate(Auth request, String provider, IAuthSession session, IAuthProvider oAuthConfig) at ServiceStack.ServiceInterface.Auth.AuthService.Post(Auth request) at lambda_method(Closure , Object , Object ) at ServiceStack.ServiceHost.ServiceRunner1.Execute(IRequestContext リクエストコンテキスト、オブジェクトインスタンス、TRequest リクエスト)

RavenDB を検索すると、セッションに関係がある可能性があることがわかりますが、ここで何が間違っているのかわかりません。ServiceStack で RavenDB セッションを管理する方法についての私の理解かもしれません。

アップデート

ServiceStack.AuthenticationRavenDb.RavenUserAuthRepository::GetUserAuthメソッドの v3 ブランチにバグがあったことが判明しました。他のすべてのメソッドは、コンストラクターによって挿入されたプライベート IDocumentSession メンバーを使用していましたが、GetUserAuth は IDocumentSession の新しいインスタンスを作成していました。

private readonly IDocumentStore _documentStore;

public RavenUserAuthRepository(IDocumentStore documentStore,IDocumentSession session)
{
    _documentStore = documentStore;
    _session = session;
}

public UserAuth GetUserAuth(string userAuthId)
{
    using (var session = documentStore.OpenSession())
    {
        int intAuthId;
        return int.TryParse(userAuthId, out intAuthId) 
            ? session.Load<UserAuth>(intAuthId) 
            : session.Load<UserAuth>(userAuthId);
    }
}

修理済み

public UserAuth GetUserAuth(string userAuthId)
{
    using (_session)
    {
        int intAuthId;
        return int.TryParse(userAuthId, out intAuthId) 
            ? _session.Load<UserAuth>(intAuthId) 
            : _session.Load<UserAuth>(userAuthId);
    }
}

これにより、 CreateOrMergeAuthSessionが (GetUserAuth を介して) 1 つのセッション インスタンスで UserAuth を取得し、プライベート セッション メンバーを使用して UserAuth を保存し、競合が発生しました。

ヒントをありがとう、デビッド!

4

1 に答える 1