Spring Security를 사용하면 JSESSIONID를 URL에 부여 할 수 없습니다.
14553 단어 spring-security자바spring
그 원인에 대해 조사했으므로 정리한다.
네, 지금 JSESSIONID를 URL에 포함시키지 않겠습니까?
환경
사건을 재현
이벤트를 재현하려면 몇 가지 준비가 필요합니다.
JSESSIONID를 URL로 관리
쿠키가 이용 가능한 브라우저의 경우는 쿠키를 이용해 JSESSIONID 를 관리해 버린다.
URL을 강제로 관리하도록 서블릿 컨테이너 설정을 변경합니다.
Spring Boot를 사용했을 경우는, 이하와 같이 ServletContextInitializer
를 Bean 정의하는 것으로 설정할 수 있다.
@Bean
public ServletContextInitializer servletContextInitializer() {
return servletContext -> servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.URL));
}
URL Rewriting 사용
Spring Security에서는 URL Rewriting을 무효화하는 기능이 디폴트로 설정되어 있다.
다음과 같이 WebSecurityConfigurerAdapter
를 상속한 클래스에서 설정을 변경한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().enableSessionUrlRewriting(true);
}
}
로그인 페이지 만들기
Spring Security 가 디폴트로 제공하고 있는 로그인 페이지에서는 URL Rewriting 를 이용할 수 없기 때문에, 로그인 페이지를 만든다.
login.html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form th:action="@{/login}" method="post">
<div>
<label>ユーザー名: <input type="text" name="username"/></label>
</div>
<div>
<label>パスワード: <input type="password" name="password"/></label>
</div>
<input type="submit" value="login"/>
</form>
</body>
</html>
또한 이 페이지를 표시하기 위한 Controller 메서드를 만든다.
@Controller
public class HelloController {
@GetMapping("/login")
public String login() {
return "login";
}
}
마지막으로 설정을 추가합니다.
그런 다음 로그인에 사용할 사용자 이름과 암호를 지정합니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll().anyRequest().authenticated()
.and()
.formLogin().loginPage("/login")
.and()
.sessionManagement().enableSessionUrlRewriting(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("{noop}user").roles("ADMIN");
}
}
기본적으로 DelegatingPasswordEncoder
가 사용되므로 암호에는 prefix가 필요합니다. 이번은 평문이므로 {noop}
를 부여하고 있다.
DelegatingPasswordEncoder
에 대해 조사한 것은 아래에 정리되어 있다.
htps : // 이 m / d-o sh / ms / b b52152318391 5 5 07 아
로그인 후 페이지 만들기
이것도 html과 Controller 메소드를 만든다.
hello.html<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<h1>ログインできたよ</h1>
</body>
</html>
@Controller
public class HelloController {
@GetMapping("/")
public String index() {
return "hello";
}
@GetMapping("/login")
public String login() {
return "login";
}
}
이벤트 확인
응용 프로그램을 시작하고 액세스하면 오류가 발생합니다.
(정확하게는 에러가 발생하여 에러 화면으로 리디렉션하지만, 거기에서도 에러가 발생하여 리디렉션이 루프하고 있다.)
로그를 보면 RequestRefectedException
가 발생하고 있는 것을 확인할 수 있다.
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
원인
Spring Security 는 HttpFirewall
에 의해, 요구의 체크를 실시하고 있어, 그 구현의 1 개인 StrictHttpFirewall
에서는, 세미콜론을 포함한 URL 를 거부하게 되어 있다.
JSESSIONID 를 URL 에 포함하는 경우는 세미콜론이 URL 에 부여되기 (위해)때문에, StrictHttpFirewall
에 의해 거부되어 예외가 발생하고 있다.
Spring Security 의 버젼에 의해 디폴트로 이용하는 HttpFirewall
가 다르고, 한때는 DefaultHttpFirewall
가 이용되고 있었다.
이 클래스는 URL에 세미콜론이 포함되어 있어도 요청을 거부하지 않습니다.
이번은 버전을 들었을 때에, 디폴트의 HttpFirewall
가 바뀌어서 에러가 발생하게 되어 버렸다.
대처 1
StrictHttpFirewall
는 세미콜론을 허용하도록 설정을 변경할 수 있습니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
web.httpFirewall(firewall);
}
}
대처 2
DefaultHttpFirewall
를 이용하도록 설정을 변경한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
web.httpFirewall(firewall);
}
}
조치 확인
조치 1 또는 2를 수행 한 후 액세스하면 로그인 화면을 볼 수 있습니다.
사용자 이름 : user, 암호 : user로 로그인 할 수 있습니다.
덧붙여서 로그인 전후로 JSESSIONID 가 바뀌고 있는 것은, Spring Security 의 세션 고정화 공격 대책이 유효하게 되어 있기 때문.
htps : // / cs. sp 링 g. 이오 / sp 린 g - 쿠시 ty / 해 / 도 CS / 5.1.6. Ree Ase / Reffe Rense / HTML ml g / / N-s-Seshi On-Fu Chion
사이고에게
세션을 URL로 관리해서는 안됩니다.
Reference
이 문제에 관하여(Spring Security를 사용하면 JSESSIONID를 URL에 부여 할 수 없습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/d-yosh/items/f52372d7190fd8af98f0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
@Bean
public ServletContextInitializer servletContextInitializer() {
return servletContext -> servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.URL));
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().enableSessionUrlRewriting(true);
}
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form th:action="@{/login}" method="post">
<div>
<label>ユーザー名: <input type="text" name="username"/></label>
</div>
<div>
<label>パスワード: <input type="password" name="password"/></label>
</div>
<input type="submit" value="login"/>
</form>
</body>
</html>
@Controller
public class HelloController {
@GetMapping("/login")
public String login() {
return "login";
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login").permitAll().anyRequest().authenticated()
.and()
.formLogin().loginPage("/login")
.and()
.sessionManagement().enableSessionUrlRewriting(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("{noop}user").roles("ADMIN");
}
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<h1>ログインできたよ</h1>
</body>
</html>
@Controller
public class HelloController {
@GetMapping("/")
public String index() {
return "hello";
}
@GetMapping("/login")
public String login() {
return "login";
}
}
응용 프로그램을 시작하고 액세스하면 오류가 발생합니다.
(정확하게는 에러가 발생하여 에러 화면으로 리디렉션하지만, 거기에서도 에러가 발생하여 리디렉션이 루프하고 있다.)
로그를 보면
RequestRefectedException
가 발생하고 있는 것을 확인할 수 있다.org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
원인
Spring Security 는 HttpFirewall
에 의해, 요구의 체크를 실시하고 있어, 그 구현의 1 개인 StrictHttpFirewall
에서는, 세미콜론을 포함한 URL 를 거부하게 되어 있다.
JSESSIONID 를 URL 에 포함하는 경우는 세미콜론이 URL 에 부여되기 (위해)때문에, StrictHttpFirewall
에 의해 거부되어 예외가 발생하고 있다.
Spring Security 의 버젼에 의해 디폴트로 이용하는 HttpFirewall
가 다르고, 한때는 DefaultHttpFirewall
가 이용되고 있었다.
이 클래스는 URL에 세미콜론이 포함되어 있어도 요청을 거부하지 않습니다.
이번은 버전을 들었을 때에, 디폴트의 HttpFirewall
가 바뀌어서 에러가 발생하게 되어 버렸다.
대처 1
StrictHttpFirewall
는 세미콜론을 허용하도록 설정을 변경할 수 있습니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
web.httpFirewall(firewall);
}
}
대처 2
DefaultHttpFirewall
를 이용하도록 설정을 변경한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
web.httpFirewall(firewall);
}
}
조치 확인
조치 1 또는 2를 수행 한 후 액세스하면 로그인 화면을 볼 수 있습니다.
사용자 이름 : user, 암호 : user로 로그인 할 수 있습니다.
덧붙여서 로그인 전후로 JSESSIONID 가 바뀌고 있는 것은, Spring Security 의 세션 고정화 공격 대책이 유효하게 되어 있기 때문.
htps : // / cs. sp 링 g. 이오 / sp 린 g - 쿠시 ty / 해 / 도 CS / 5.1.6. Ree Ase / Reffe Rense / HTML ml g / / N-s-Seshi On-Fu Chion
사이고에게
세션을 URL로 관리해서는 안됩니다.
Reference
이 문제에 관하여(Spring Security를 사용하면 JSESSIONID를 URL에 부여 할 수 없습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/d-yosh/items/f52372d7190fd8af98f0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
StrictHttpFirewall
는 세미콜론을 허용하도록 설정을 변경할 수 있습니다.@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
web.httpFirewall(firewall);
}
}
대처 2
DefaultHttpFirewall
를 이용하도록 설정을 변경한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
web.httpFirewall(firewall);
}
}
조치 확인
조치 1 또는 2를 수행 한 후 액세스하면 로그인 화면을 볼 수 있습니다.
사용자 이름 : user, 암호 : user로 로그인 할 수 있습니다.
덧붙여서 로그인 전후로 JSESSIONID 가 바뀌고 있는 것은, Spring Security 의 세션 고정화 공격 대책이 유효하게 되어 있기 때문.
htps : // / cs. sp 링 g. 이오 / sp 린 g - 쿠시 ty / 해 / 도 CS / 5.1.6. Ree Ase / Reffe Rense / HTML ml g / / N-s-Seshi On-Fu Chion
사이고에게
세션을 URL로 관리해서는 안됩니다.
Reference
이 문제에 관하여(Spring Security를 사용하면 JSESSIONID를 URL에 부여 할 수 없습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/d-yosh/items/f52372d7190fd8af98f0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 諸々省略・・・
@Override
public void configure(WebSecurity web) throws Exception {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
web.httpFirewall(firewall);
}
}
조치 1 또는 2를 수행 한 후 액세스하면 로그인 화면을 볼 수 있습니다.
사용자 이름 : user, 암호 : user로 로그인 할 수 있습니다.
덧붙여서 로그인 전후로 JSESSIONID 가 바뀌고 있는 것은, Spring Security 의 세션 고정화 공격 대책이 유효하게 되어 있기 때문.
htps : // / cs. sp 링 g. 이오 / sp 린 g - 쿠시 ty / 해 / 도 CS / 5.1.6. Ree Ase / Reffe Rense / HTML ml g / / N-s-Seshi On-Fu Chion
사이고에게
세션을 URL로 관리해서는 안됩니다.
Reference
이 문제에 관하여(Spring Security를 사용하면 JSESSIONID를 URL에 부여 할 수 없습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/d-yosh/items/f52372d7190fd8af98f0
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Spring Security를 사용하면 JSESSIONID를 URL에 부여 할 수 없습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/d-yosh/items/f52372d7190fd8af98f0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)