2011-12-24 12 views
0

カスタムDataSourceのWebApplicationContextからHttpSessionにアクセスする方法はありますか?いくつかの情報をHttpSessionに保存するカスタム認証処理フィルタを実装しました。この情報は、データベース接続を取得するためにデータソースによって使用されます。SpringのカスタムDataSourceからHttpSessionにアクセスするには?

もう1つのオプションは、SecurityContextHolderを使用して、追加の属性を含むようにカスタマイズされた認証トークンを取得することです。私はこれが正しいアプローチであるとは確信していません。

これは私がこれまで持っているものです。

public class CustomDataSource extends DriverManagerDataSource implements ApplicationContextAware { 

protected Connection getConnectionFromDriverManager(String url, 
     Properties props) throws SQLException { 

    // want to use the web context to get the http session 

    // Authentication has a getAttribute(String name) method 
    SecurityContext securityContext = SecurityContextHolder.getContext(); 
    CustomAuthenticationToken authentication = (CustomAuthenticationToken) securityContext.getAuthentication(); 
    Object attribute = authentication.getAttribute("db"); 


    // create a connection object here 
    Object conn = getConnectionFromAttribute(attribute); 
    return (Connection)conn; 
} 

private WebApplicationContext context; 

@Override 
public void setApplicationContext(ApplicationContext applicationContext) 
     throws BeansException { 
    this.context = (WebApplicationContext)applicationContext;   
} 
} 

更新

私は唯一のユーザ名とパスワードを持っているAUTHINFOと呼ばれる新しいクラスを、定義されました。ユーティリティ・インタフェースの静的な最終的な変数としてのThreadLocalをreated次いで:

public interface WebUtils{ 
    public static final ThreadLocal<AuthInfo> authInfo = new ThreadLocal<AuthInfo>(); 
} 

のThreadLocalの値は、カスタムデータソースに、今フィルタ

AuthInfo info = new AuthInfo(); 
info.setName(username); 
info.setPass(password); 

WebAttributes.authInfo.set(info); 

のattemptAuthentication方法で設定されている

protected Connection getConnectionFromDriverManager(String url, 
     Properties props) throws SQLException { 

    AuthInfo info = WebAttributes.authInfo.get(); 
    Connection conn = getConnFromAuthInfo(info); 
    return conn; 
} 

これはSecurityContextHolderとCustomAuthenticationTokenの使用と同じですか?

答えて

1

一般的な多層アプリケーションでは、データアクセスレイヤーにHTTPインタフェースなどの上位レイヤに関する知識がないようにしてください。

セッションまたはリクエストスコープを使用して調査することをお勧めします。これらのスコープのいずれかでスコープ付きプロキシBeanを作成し、その中に認証情報を配置し、それをデータソースに挿入することができます。

+0

スコーププロキシ豆を使用しておよそどれでも良いリソースの周りに、HandlerInterceptorまたはAspectJのでチェックを行うことができますか?また、DataSourceのSecurityContextにアクセスすることは悪い習慣ですか? – suikodian

1

データソースにそのロジックを配置しないでください。 httpセッションとデータベースは関連していてはなりません。

あなたのコントローラやサービス層

+0

HandlerInterceptorを使用して認証情報をDataSourceに渡すにはどうすればよいですか?認証フィルターは、この情報を新しく作成されたトークンとhttpセッションに保管します。 – suikodian

+0

あなたはデータソースでそれを使うべきではありません。しかし、それを 'ThreadLocal'変数に設定し、それをデータソースで読み取ることで可能です。しかし、db接続を取得するのではなく、コード(インターセプタ)の前に認証を置くことを検討してください。 – Bozho

+0

@Bozho Springのセッションと要求スコープ付きプロキシBeansは、 'ThreadLocal'をカバーの下で使用しますが、' ThreadLocal'の代わりにそれらを使用すると、もう少し簡単です。 @artbristolが同意した。 – artbristol

関連する問題