2011-12-24 31 views
0

有没有一种方法可以从自定义DataSource中的WebApplicationContext访问HttpSession?我实现了一个定制的认证处理过滤器,它在HttpSession中存储了一些信息。这个信息然后被一个DataSource用来获得一个数据库连接。如何从Spring中的自定义数据源访问HttpSession?

另一个选择是使用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的新类,其中只有用户名和密码。然后reated一个ThreadLocal作为公用接口的静态最终变量:

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

ThreadLocal的的值然后在过滤器的attemptAuthentication方法设定现在

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

WebAttributes.authInfo.set(info); 

,在自定义数据源

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

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

是不是这样使用SecurityContextHolder和CustomAuthenticationToken?

回答

1

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

我建议你使用Spring的会话请求调查范围。您可以在这些作用域之一中创建一个作用域代理bean,将认证信息放入其中,并将其注入到数据源中。

+0

任何好的资源有关使用范围代理豆?另外,访问DataSource中的SecurityContext是不好的做法吗? – suikodian 2011-12-24 09:51:04

1

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

你可以在一个HandlerInterceptor或AspectJ的支票,在你的控制器或服务层

+0

如何使用HandlerInterceptor将认证信息传递给DataSource?认证过滤器将这些信息存储在新创建的令牌以及http会话中。 – suikodian 2011-12-24 09:49:27

+0

你不应该在数据源中使用它,就是这样。不过,您可以将它设置在一个ThreadLocal变量中,并在数据源中读取它。但是考虑在代码(拦截器)中提前使用身份验证,而不是在获取数据库连接时使用 – Bozho 2011-12-24 09:50:51

+0

@Bozho Spring的会话和请求范围的代理bean使用下面的'ThreadLocal',但使用它们而不是'ThreadLocal'进行单元测试更容易一点。 – artbristol 2011-12-24 10:00:13

相关问题