如何从Spring中的自定义DataSource访问Http Session?

时间:2011-12-24 08:35:19

标签: java spring spring-security datasource

有没有办法在自定义DataSource中从WebApplicationContext访问HttpSession?我实现了一个自定义身份验证处理过滤器,它在HttpSession中存储了一些信息。然后,DataSource使用此信息来获取数据库连接。

另一种选择是使用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作为实用程序接口的静态最终变量:

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

然后在过滤器的attemptAuthentication方法中设置ThreadLocal的值

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

WebAttributes.authInfo.set(info);

现在,在自定义DataSource

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

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

这与使用SecurityContextHolder和CustomAuthenticationToken不一样吗?

2 个答案:

答案 0 :(得分:1)

在典型的多层应用程序中,您的数据访问层不应具有更高层的任何知识,例如HTTP接口。

我建议您使用Spring的会话请求范围进行调查。您可以在其中一个范围中创建范围内的代理bean,将身份验证信息放入其中,然后将其注入数据源。

答案 1 :(得分:1)

不要将该逻辑放在数据源中。 http会话和数据库不应该相关。

您可以在控制器或服务层周围HandlerInterceptor或使用aspectj进行检查