假设我们有针对以下 URL 的自定义身份验证方式。
Path1: http://www.example.com/company1/home
Path2: http://www.example.com/company2/home
Path3: http://www.example.com/company3/home
.
.
.
PathX: http://www.example.com/companyX/home
而且公司拥有不同的数据集。
现在,我希望 Spring Security 基于 http://www.example.com/XXX/ 为上述每个 URL 创建单独的会话。因此,当我在单独的浏览器选项卡中登录不同的 URL 时,我可以使用所有这些 URL。我想保持所有会话处于活动状态并避免在使用其他 URL 进行身份验证后会话终止。
如何实现这一目标?
SessionRepository 负责创建、检索和保存会话。因此,您必须实现自定义的 SessionRepositry 和会话策略。 自定义 SessionRepository 将负责根据 URL 路径存储会话。然后我们必须配置 spring security 以使用自定义 SessionRepository。
实现主要是以下几行:
@Component
public class CustomSessionRepository implements SessionRepository<Session> {
private final Map<String, Map<String, Session>> session = new HashMap<>(); //map to store the URL path to a map of session id and session object
@override
public Session createSession() {
return new MapSession(); // or any other Session Implementation
}
@Override
public void save(Session session) {
String path = getPathFromSession(session);
sessions.computeIfAbsent(path, k -> new HashMap<>()).put(session.getId, session);
}
@Override
public Session findById(String id) {
String path = getPathFromRequest();
return sessions.getOrDefault(path, new HashMap<>()).get(id)
}
@Override
public void deleteById(String id) {
String path = getPathFromRequest();
sessions.getOrDefault(path, new HashMap<>()).remove(id);
}
private String getPathFromSession(Session session) {
return session.getAttribute("path");
}
private String getPathFromRequest() {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
return request.getRequestURI().split("/")[2]; //uri path format /companyX/
}
}
这是安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity HTTP) throws Exception {
http.authorizeRequests()
.antMatchers("/company1/**", "/company2/**", "/company3/**")
.authenticate().and()
.formLogin().and()
.sessionManagement()
.sessionFixation().none()
.sessionRepository(customSessionRepository());
return http.build();
}
@Bean
public CustomSessionRepository customSessionRepository() {
return new CustomSessionRegistry();
}
}