Kar*_*mba 5 java spring spring-security
我想将 HTTPSessionIdResolver 用于“/api**”下的所有内容以及标准 CookieResolver 下的所有内容。
这怎么可能,以便两种配置使用不同的解析器?以我目前的方法,一切都使用 X-AUTH。
我试图理解 Spring 中的实现,最终在 SessionRepositoryFilter 中,但是这个过滤器只创建了一个实例,所以 der 只存在一个解析器。
@EnableWebSecurity
public class TestConfig {
@EnableSpringHttpSession
@Configuration
@Order(1)
public static class Abc extends WebSecurityConfigurerAdapter {
@Bean
@Primary
public HeaderHttpSessionIdResolver xAuth() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
@Bean
@Primary
public MapSessionRepository mapSessionRepository(){
return new MapSessionRepository(new HashMap<>());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/service/json/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf()
.disable();
}
}
@EnableSpringHttpSession
@Configuration
@Order(2)
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
@Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.build();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/user/registration", "/webfonts/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public BCryptPasswordEncoder bcrypt() {
return new BCryptPasswordEncoder();
}
@Bean
public JdbcUserDetailsManager userDetailsManager() {
JdbcUserDetailsManager manager = new UserDetailsManager(dataSource());
manager.setUsersByUsernameQuery("select username,password,enabled from users where username=?");
manager.setAuthoritiesByUsernameQuery("select username,authority from authorities where username = ?");
return manager;
}
@Autowired
public void initialize(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userDetailsManager()).passwordEncoder(bcrypt());
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以将逻辑移到一个解析器中,该解析器将工作委托给现有的解析器,但这似乎很糟糕?
public class SmartHttpSessionIdResolver implements HttpSessionIdResolver {
private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token";
private static final CookieHttpSessionIdResolver cookie = new CookieHttpSessionIdResolver();
private static final HeaderHttpSessionIdResolver xauth = HeaderHttpSessionIdResolver.xAuthToken();
@Override
public List<String> resolveSessionIds(HttpServletRequest request) {
if (isXAuth(request)) {
return xauth.resolveSessionIds(request);
}
return cookie.resolveSessionIds(request);
}
@Override
public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
if (isXAuth(request)) {
xauth.setSessionId(request, response, sessionId);
} else {
cookie.setSessionId(request, response, sessionId);
}
}
@Override
public void expireSession(HttpServletRequest request, HttpServletResponse response) {
if (isXAuth(request)) {
xauth.expireSession(request, response);
} else {
cookie.expireSession(request, response);
}
}
private boolean isXAuth(HttpServletRequest request) {
return request.getHeader(HEADER_X_AUTH_TOKEN) != null;
}
}
Run Code Online (Sandbox Code Playgroud)
在尝试了问题中提供的解决方案(说实话,效果很好)之后,我还尝试通过提供两个不同的过滤器来做到这一点。然而,当@EnableSpringHttpSession
添加 时,SessionRepositoryFilter
会自动添加 a,并且在 servlet 过滤器链中再添加两个看起来很奇怪。因此,我认为它们必须进入安全过滤器链,这很好,因为这样我们也可以使用在那里进行的 URL 匹配(而不必在其他地方实现)。
由于其他安全过滤器使用HttpSession
,我们必须手动将SessionRepositoryFilter
第一个过滤器放入此链中。这是我想出的(在 Kotlin 中),它对我来说很有效:
@EnableWebSecurity
class SecurityConfig() {
private val sessionStore = ConcurrentHashMap<String, Session>()
private val sessionRepo = MapSessionRepository(sessionStore)
@Configuration
@Order(1)
inner class XAuthConfig(): WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.requestMatchers()
.antMatchers("/api**")
.and()
.addFilterBefore(
SessionRepositoryFilter(sessionRepo).apply{
setHttpSessionIdResolver(
HeaderHttpSessionIdResolver.xAuthToken();
)
}, WebAsyncManagerIntegrationFilter::class.java)
}
}
@Configuration
@Order(2)
inner class DefaultConfig(): WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.addFilterBefore(
SessionRepositoryFilter(sessionRepo).apply{
setHttpSessionIdResolver(
CookieHttpSessionIdResolver()
)
}, WebAsyncManagerIntegrationFilter::class.java)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,注释@EnableSpringHttpSession
已被删除。相反,我们在 sSessionRepositoryFilter
之前手动添加 s WebAsyncManagerIntegrationFilter
(安全过滤器链中的第一个过滤器)。它的作用就是用 Spring 来SessionRepositoryFilter
替换现有的,无论是手动放置还是通过自动配置自动放置都可以。只要安全过滤器链之前没有其他过滤器使用会话,就应该可以解决问题。否则,一些过滤器重新排列可能仍然有效。HttpSession
HttpSession
归档时间: |
|
查看次数: |
1156 次 |
最近记录: |