2011-12-14 11 views
2

NHibernate(Fluently)を使用して、アプリケーションロールを除くすべてのアプリケーションにロックダウンされているデータベースと対話しています。 sp_setapprolesp_unsetapprole直接が、NHibernateはでこれを行うにしようとしたとき、私は問題に実行します:私は保存されprocsのを使用してSQL Server Management Studioの内のアプリケーションロールを使用することができるよSQL ServerアプリケーションロールでNHibernateを使用する

using (var session = SessionFactory.OpenSession()) 
{ 
    byte[] cookie; 

    // 1) Set the application role 
    using (var command = session.Connection.CreateCommand()) 
    { 
     command.CommandType = CommandType.StoredProcedure; 
     command.CommandText = "sp_setapprole"; 
     command.Parameters.Add(new SqlParameter("@rolename", RoleName)); 
     command.Parameters.Add(new SqlParameter("@password", RolePassword)); 
     command.Parameters.Add(new SqlParameter("@fCreateCookie", true)); 
     command.Parameters.Add(
      new SqlParameter 
       { 
        ParameterName = "@cookie", 
        DbType = DbType.Binary, 
        Direction = ParameterDirection.Output, 
        Size = 8000 
       }); 

     // This works perfectly fine 
     command.ExecuteNonQuery(); 
     var outVal = (SqlParameter)command.Parameters["@cookie"]; 

     // This returns a byte array value for the cookie generated 
     cookie = (byte[])outVal.Value; 
    } 

    // 2) This line dutifully retreives my contrived Person object but renders 
    // part 3) of this saga next to useless because it performs a logout 
    // (identified with SQL Profiler) and the app role/cookie is forgotten. 
    session.CreateCriteria(typeof(Person)).List<Person>().FirstOrDefault(); 

    // 3) Unset the application role 
    using (var command = session.Connection.CreateCommand()) 
    { 
     command.CommandType = CommandType.StoredProcedure; 
     command.CommandText = "sp_unsetapprole"; 
     command.Parameters.Add(new SqlParameter("@cookie", cookie)); 
     command.ExecuteNonQuery(); 
    } 
} 

要約すると、上の例で1)と3)の間の何かをすると、アプリケーションがクラッシュします。私がプールしているかどうかによって、2つの異なる方法で:

プール - 現在のコマンドで重大なエラーが発生しました。もしあれば、結果は破棄されるべきです。何も設定されていないか、クッキーが無効であるたため、未設定のアプリケーションロールをすることはできません -

をプールされていません。

(通常は若干異なる行われますが、私はプールの属性を設定するために必要なことであろう)私はこのことができますかどうかわからないんだけど、私は次のように接続しています:

private static ISessionFactory CreateSessionFactory() 
{ 
    return Fluently.Configure().Database(
     MsSqlConfiguration.MsSql2008.ConnectionString(
      "Data Source=(local);" + 
      "Initial Catalog=PeopleDB;" + 
      "Integrated Security=False;" + 
      "User ID=someuserid;" + 
      "Password=somepassword" + 
      "Pooling=False")) 
     .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>()) 
     .BuildSessionFactory(); 
} 

FYIユーザー上記のコードで接続すると、少なくともsp_setapproleが動作していることを証明するデータベースへのアクセス権は全くありません。

誰かがこれを見つけて解決することができましたか?私は良いGoogleを持っていたが、何も出てこなかった。事前に

おかげで、 ロブ

答えて

2

NHを作成し、それがIConnectionProviderを使用して、それらを必要とするときの接続を閉じます。アプリケーション内で使用されているすべての接続が同じ認証手順を使用する場合は、独自のIConnectionProviderを実装し、MsSqlConfiguration.MsSql2008.Provider<YourOwnConnectionProvider>()で構成するのが最善です。

class MyConnectionProvider : DriverConnectionProvider 
{ 
    public override IDbConnection GetConnection() 
    { 
     var connection = base.GetConnection(); 

     byte[] cooky; 
     // TODO: authenticate 

     return new MyConnectionWrapper(connection, cooky); 
    } 

    public override void CloseConnection(IDbConnection conn) 
    { 
     var myConn = conn as MyConnectionWrapper; 
     if (myConn != null) 
     { 
      // TODO: deregister with myConn.Cooky; 
     } 
     base.CloseConnection(conn); 
    } 
} 
+0

答えてくれてありがとうございます。私はMyConnectionWrapperが実装しているものについて興味があります...そのクラスの目的を説明できますか? – Rob

+0

基本的な接続にすべてを委譲し、クローズ時に登録解除するプロパティとしてCookyを保持するデコレータだけです – Firo

+0

これは機能しています!私が最後にやらなければいけなかったのは、GetConnectionのオーバーライドとsetConnectionオーバーライドのunsetapproleでsetapproleを呼び出すことでした。 – Rob

関連する問題