SpringSecurity 는 springBoot,redis 를 통합 하여 로그 인 상호 차기 기능 을 실현 합 니 다.
나의 문장 에 기초 하여--SpringSecurity 통합 springBoot,redis token 동적 url 권한 검사실현 하고 자 하 는 기능 은 한 사용자 가 두 대의 설비 에 동시에 로그 인 할 수 없다 는 것 을 실현 하 는 것 이다.두 가지 사고방식 이 있다.
(1)이후 의 로그 인 은 앞의 로그 인 을 자동 으로 차 버린다.
(2)만약 에 사용자 가 로그 인 을 했다 면 후발 주자 의 로그 인 을 허용 하지 않 는 다.
특히 프로젝트 의 기 초 는 redis 가 유지 하 는 session 입 니 다.
redisHttpSession 설정
spring session 을 redis 에서 관리 하도록 설정 합 니 다.
2.1 yml 의 http session 설정 을 제거 하고 yml 과 주 해 는 둘 중 하나 만 선택 합 니 다(동시에 설정 하고 주해 설정 만 유효 합 니 다).왜 yml 을 사용 하지 않 는 지 에 대해 서 는 잠시 후에 언급 하 겠 습 니 다.
2.2 webSecurity Config 에 주석 추가@EnableRedisHttpSession
@EnableRedisHttpSession(redisNamespace = "spring:session:myframe", maxInactiveIntervalInSeconds = 1700
, flushMode = FlushMode.ON_SAVE)
로그 인 한 결과 redis session namespace 가 저희 가 이름 을 지 었 습 니 다.redis 관리 session Repository 가 져 오기
사용자 의 로그 인 을 제한 하려 면 시스템 에 있 는 모든 session 을 가 져 와 야 합 니 다.
2.spring Session 홈 페이지 의 문 서 를 다시 봅 니 다.springsession 홈 페이지 제공 문서https://docs.spring.io/spring-session/docs/ 2.2.2.RELEASE/reference/html5/#api-findbyindexnamesessionrepository
SessionRepository 실현 도 FindByIndexNameSsionRepository 실현 을 선택 할 수 있 습 니 다.
FindByIndexNameSsionRepository 는 주어진 색인 이름과 색인 값 을 가 진 모든 세 션 을 찾 는 방법 을 제공 합 니 다.
FindByIndexNameSsionRepository 가 실 현 될 때 특정 사용자 의 모든 세 션 을 편리 하 게 찾 을 수 있 습 니 다.
/**
* redis sessionRepository
* RedisIndexedSessionRepository FindByIndexNameSessionRepository
*/
@Autowired
// @Lazy ...
// Circular reference involving containing bean '.RedisHttpSessionConfiguration'
@Lazy
private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
여기 서 주의 하 세 요.yml 을 통 해 redis session 을 설정 하면 session Repository 아래 에 빨 간 선 이 있 습 니 다.운행 에 영향 을 주지 않 지만 강박 증 이 있 으 므 로@EnableWebSecurity 주석 으로 바 꿉 니 다(왜 요?나 도 알 고 싶 지 않다.
session Repository 를 SpringSession Backed Session Registry 에 주입 합 니 다.
spring session 이 Spring Security 에 제공 하 는 어떤 세 션 을 병행 하 는 세 션 레 지 스 트 입 니 다.아마도 spring Security 에 게 로그 인 을 제한 하 라 고 했 을 것 입 니 다.session Repository 만 으로 는 안 되 고 도 구 를 추가 해 야 합 니 다.
webSecurity Config 가입:
/**
* spring session Spring Security ,
*
* @return
*/
@Bean
public SpringSessionBackedSessionRegistry sessionRegistry(){
return new SpringSessionBackedSessionRegistry<>(sessionRepository);
}
주:https://blog.csdn.net/qq_34136709/article/details/106012825 이 글 은 Http Session Event Publisher 를 추가 하여 session 을 감청 하여 구름 을 없 애 야 한다 고 말 했 습 니 다.아마 제 가 redis session 을 사 용 했 기 때 문 일 것 입 니 다.이것 이 필요 하지 않 습 니 다.필요 하면 잘못 보고 할 것 입 니 다.무슨 잘못 입 니까?까 먹 었 어.
세 션 만 료 후 처리 클래스 추가
먼저 CustomSession InformationExpired Strategy.java 를 만 들 고 session 이 만 료 된 후에 전단 의 처리 류 를 어떻게 알 리 는 지 알 립 니 다.내용 은 다음 과 같 습 니 다.
public class CustomSessionInformationExpiredStrategy implements SessionInformationExpiredStrategy {
@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException {
if (log.isDebugEnabled()) {
log.debug("{} {}", event.getSessionInformation(), MessageConstant.SESSION_EVICT);
}
HttpServletResponse response = event.getResponse();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
String responseJson = JackJsonUtil.object2String(ResponseFactory.fail(CodeMsgEnum.SESSION_EVICT, MessageConstant.SESSION_EVICT));
response.getWriter().write(responseJson);
}
}
주:일반적으로 스스로 전단 으로 돌아 가 는 정 보 를 다시 쓰 고 프레임 으로 던 지 는 오류 정 보 를 직접 쓰 지 않 습 니 다.configure(HttpSecurity http)방법 에 설정
.csrf().disable()
//
.sessionManagement()
// session
//.sessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy(httpSessionConfig.sessionRegistry()))
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
.maxSessionsPreventsLogin(false) //false ,
//session ( )
.expiredSessionStrategy(new CustomSessionInformationExpiredStrategy());
주의:https://blog.csdn.net/qq_34136709/article/details/106012825 이 글 은 session 인증 의 원 리 를 말 합 니 다.저 는 session 의 인증 전략 을 실 행 했 지만 debug 에 대응 하 는 코드 를 보 았 을 때이 session 인증 전략 은 Null Authenticated Session Strategy 이지 Concurrent Session Control Authentication Strategy 가 아 닙 니 다.그 러 니까 이 session 인증 정책 을 어디서 설정 해 야 합 니까?configure(HttpSecurity http)의 설정 이 제일 먼저 생각 났 어 요.
결 과 는 무효 입 니 다.그 후에 다른 사람의 코드 를 보고 이 전략 은 로그 인 할 때 추가 해 야 한다 고 생각 했 습 니 다.우리 의 로그 인 은 보통 자신 이 다시 써 야 합 니 다.자 연 스 럽 게 위의 쓰기 가 무효 가 될 것 입 니 다.그래서 나 는 사용자 정의 로그 인 필 터 를 찾 았 다.
그리고 this.setSession AuthenticationStrategy(session Strategy)를 발견 합 니 다.확실히 존재 한다.
public LoginFilter(UserVerifyAuthenticationProvider authenticationManager,
CustomAuthenticationSuccessHandler successHandler,
CustomAuthenticationFailureHandler failureHandler,
SpringSessionBackedSessionRegistry springSessionBackedSessionRegistry) {
// ( )
this.authenticationManager = authenticationManager;
//
this.setAuthenticationSuccessHandler(successHandler);
//
this.setAuthenticationFailureHandler(failureHandler);
// session ( springSecurity redis Session )
ConcurrentSessionControlAuthenticationStrategy sessionStrategy = new
ConcurrentSessionControlAuthenticationStrategy(springSessionBackedSessionRegistry);
// session
sessionStrategy.setMaximumSessions(1);
this.setSessionAuthenticationStrategy(sessionStrategy);
// url
super.setFilterProcessesUrl("/myLogin");
}
시작 하 자마자 session 인증 정책 이 우리 가 설정 한 정책 으로 바 뀌 었 다 는 것 을 알 게 되 었 습 니 다.완전한 웹 보안 Config 는 다음 과 같 습 니 다:
@Configuration
@EnableWebSecurity
//RedisFlushMode :ON_SAVE( response commit ),IMMEDIATE( , )
//yml ( , )
@EnableRedisHttpSession(redisNamespace = "spring:session:myframe", maxInactiveIntervalInSeconds = 5000
, flushMode = FlushMode.ON_SAVE)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserVerifyAuthenticationProvider authenticationManager;//
@Autowired
private CustomAuthenticationSuccessHandler successHandler;//
@Autowired
private CustomAuthenticationFailureHandler failureHandler;//
@Autowired
private MyFilterInvocationSecurityMetadataSource securityMetadataSource;// URL
@Autowired
private MyAccessDecisionManager accessDecisionManager;//
/**
* redis sessionRepository
* RedisIndexedSessionRepository FindByIndexNameSessionRepository
*/
@Autowired
// @Lazy ...
// Circular reference involving containing bean '.RedisHttpSessionConfiguration'
@Lazy
private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
/**
* spring session Spring Security ,
*
* @return
*/
@Bean
public SpringSessionBackedSessionRegistry sessionRegistry(){
return new SpringSessionBackedSessionRegistry<>(sessionRepository);
}
/**
*
* @return
*/
@Bean
@ConditionalOnMissingBean(PasswordEncoder.class)
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* HttpSessionIdResolver Bean
* Response Header x-auth-token sessionToken
* token Request Header x-auth-token sessionToken
*/
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
/**
* Swagger
*/
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/error",
"/webjars/**",
"/resources/**",
"/swagger-ui.html",
"/swagger-resources/**",
"/v2/api-docs");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// , , securityMetadataSource
//.antMatchers("/demo/**", "/about/**").permitAll()
// URL
.anyRequest().authenticated()
//
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
@Override
public <O extends FilterSecurityInterceptor> O postProcess(O object) {
object.setAccessDecisionManager(accessDecisionManager);
object.setSecurityMetadataSource(securityMetadataSource);
return object;
}
})
.and()
//
.logout().logoutUrl("/logout")
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.clearAuthentication(true)
.and()
//
.exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint())
//
.accessDeniedHandler(new CustomAccessDeniedHandler())
.and()
//
.addFilter(new LoginFilter(authenticationManager, successHandler, failureHandler, sessionRegistry()))
.csrf().disable()
//
.sessionManagement()
// session
//.sessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy(httpSessionConfig.sessionRegistry()))
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
.maxSessionsPreventsLogin(false) //false ,
//session ( )
.expiredSessionStrategy(new CustomSessionInformationExpiredStrategy());
//
http.headers()
.contentTypeOptions()
.and()
.xssProtection()
.and()
//
.cacheControl()
.and()
.httpStrictTransportSecurity()
.and()
// frame // iframe
.frameOptions().disable();
}
}
기타
@Lazy
private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
@lazy 를 추가 하지 않 고 어떤 순환 인용 을 할 지 에 대해 서 는 정말 신경 쓰 고 싶 지 않 습 니 다.오랫동안 봤 는데 누구 랑 누구 랑 순환 인용 이 일 어 났 는 지 모 르 겠 어 요...SpringSecurity 통합 springBoot,redis-로그 인 서 로 를 실현 하 는 글 은 여기까지 소개 되 었 습 니 다.더 많은 SpringSecurity 로그 인 서 로 를 위 한 콘 텐 츠 는 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.