有没有办法在自定义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不一样吗?
答案 0 :(得分:1)
在典型的多层应用程序中,您的数据访问层不应具有更高层的任何知识,例如HTTP接口。
我建议您使用Spring的会话或请求范围进行调查。您可以在其中一个范围中创建范围内的代理bean,将身份验证信息放入其中,然后将其注入数据源。
答案 1 :(得分:1)
不要将该逻辑放在数据源中。 http会话和数据库不应该相关。
您可以在控制器或服务层周围HandlerInterceptor
或使用aspectj进行检查