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.ServiceRunner
1.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 を保存し、競合が発生しました。
ヒントをありがとう、デビッド!