Я хочу использовать HTTPSessionIdResolver для всего, что находится в "/ api **", и для всего остального стандартного CookieResolver.
Как это возможно, чтобы две конфигурации использовали разные распознаватели? При моем текущем подходе все использует X-AUTH.
Я попытался понять реализацию в Spring, и я оказался в SessionRepositoryFilter, но из этого фильтра создается только один экземпляр, поэтому существует только один преобразователь.
@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());
}
}
}
Я мог бы переместить логи c в один распознаватель, который делегирует работу существующим распознавателям, но это кажется вздорным?
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;
}
}