[SPRING] URL 매개 변수 / URL로 전달 된 로그인 매개 변수를 확인하지 못하게하려면 어떻게해야합니까?
SPRINGURL 매개 변수 / URL로 전달 된 로그인 매개 변수를 확인하지 못하게하려면 어떻게해야합니까?
응용 프로그램은 요청 된 모든 URL을 기록합니다. 이는 URL 매개 변수를 사용하여 인증하지 않는 것이 중요하다는 것을 의미합니다. 로그가 쌍으로 가득 찬 상황을 유발할 수 있기 때문입니다 (login = abc & password = 123). 이런 이유로 저는 요청 보안 본문에서 매개 변수를 읽을 수 있도록 스프링 보안을 구성했습니다. request-header에 다음 행을 추가하여 완료됩니다.
'Content-Type': 'application/x-www-form-urlencoded'
시체는 :
{'login':'admin', 'password':'password'}
괜찮아요.하지만 품질 보증을 통해 URL 매개 변수를 통해 인증 할 수 없게됩니다. 현재 다음 URL에 대한 POST가 인증됩니다.
https://example.com/foo?login=admin&password=password
누구든지이 옵션을 비활성화하는 트릭을 알고 있습니까? 가급적 주석을 사용하십시오.
의견으로 인해 나는 내 문제에 더 많은 세부 사항을 추가하기로 결정했다. 내 봄 보안은 WebSecurityConfigurerAdapter로 구성됩니다. 나는 가지고있다
http.usernameParameter("login")
.passwordParameter("password")
(...)
이렇게하면 Spring은 두 매개 변수와 본문에서 로그인 데이터를 검색하게됩니다. URL에서 매개 변수를 검색하지 못하게하고 싶습니다.
해결법
-
==============================
1.나는이 동작이 JavaEE 자체보다는 Spring에 의해 구현되지 않았기 때문에 가능하지 않다고 생각한다.
나는이 동작이 JavaEE 자체보다는 Spring에 의해 구현되지 않았기 때문에 가능하지 않다고 생각한다.
HttpServletRequest.getParameter doc 상태 :
그러나 다음과 같은 필터를 사용하여이 값을 변경하려고 할 수 있습니다.
public class DisableGetAuthFiler extends OncePerRequestFilter { ... @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { filterChain.doFilter( new HttpServletRequestWrapper(request) { @Override public String getParameter(String name) { if (("login".equals(name) && getQueryString().contains("login")) || ("password".equals(name) && getQueryString().contains("password"))) { return null; } else { return super.getParameter(name); } } }, response ); } }
Haim Raman은 새 필터를 도입하는 대신 기존 필터를 사용하는 또 다른 솔루션을 제안했습니다. tryAuthentication () 대신 obtainUsername () 및 obtainPassword ()를 재정의하는 것이 좋습니다.
-
==============================
2.chimmi가 제안한 해결 방안을 봄 보안에 기초한 대안으로 제안하고자합니다.
chimmi가 제안한 해결 방안을 봄 보안에 기초한 대안으로 제안하고자합니다.
이 답변은 xenteros에서 bres26 대답에 대해 제안한 문제에 대한 해결책을 제공합니다.
기존 UsernamePasswordAuthenticationFilter 구현 재정의
public class ImprovedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override protected String obtainUsername(HttpServletRequest request) { final String usernameParameter = getUsernameParameter(); validateQueryParameter(request, usernameParameter); return super.obtainUsername(request); } @Override protected String obtainPassword(HttpServletRequest request) { final String passwordParameter = getPasswordParameter(); validateQueryParameter(request, passwordParameter); return super.obtainPassword(request); } private void validateQueryParameter(HttpServletRequest request, String parameter) { final String queryString = request.getQueryString(); if (!StringUtils.isEmpty(queryString)) { if (queryString.contains(parameter)) throw new AuthenticationServiceException("Query parameters for login are a prohibit, use message body only!"); } } }
자신의 구현을 기존의 구현으로 대체해야합니다 (여기 doc 참조).
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home","/login").permitAll() .anyRequest().authenticated() .and() .logout() .permitAll() .and() //Replace FORM_LOGIN_FILTER with your own custom implementation .addFilterAt(improvedUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .exceptionHandling() .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")) .and() //disable csrf to allow easy testing .csrf().disable(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("user").password("password").roles("USER"); } public UsernamePasswordAuthenticationFilter improvedUsernamePasswordAuthenticationFilter() throws Exception { UsernamePasswordAuthenticationFilter authFilter = new ImprovedUsernamePasswordAuthenticationFilter(); authFilter.setRequiresAuthenticationRequestMatcher( new AntPathRequestMatcher("/login", "POST") ); authFilter .setAuthenticationManager(authenticationManager()); authFilter .setAuthenticationSuccessHandler( new SavedRequestAwareAuthenticationSuccessHandler() ); authFilter .setAuthenticationFailureHandler( new SimpleUrlAuthenticationFailureHandler("/login?error") ); return authFilter; } }
장점 : 스프링 보안을 기반으로하며 변경에 유연합니다. 단점 : 불행히도 Spring Java Config는 설정하고 읽기가 매우 어려웠습니다.
편집 : chimmi 코멘트를 허용하고 obtainUsername 및 obtainPassword를 재정의했습니다. github에서 소스 코드를 찾을 수 있습니다.
-
==============================
3.jhan이 언급 한 것처럼 제 지식과 직관력을 최대한 살려면 주석은 @RequestMapping (value = "/ login", method = "RequestMethod.POST") 주석을 사용하는 것이 좋습니다. 그런 다음 사용자가 URL과 함께 전달할 수있는 매개 변수에 관계없이 URL과 URI는 항상 / login이 기본값입니다. 이것이 로거가 기록한 것입니다. 사용자 이름과 암호 쌍이 아니라 "http : // localhost : 8080 / login"또는 포트가 무엇이든 상관 없습니다.
jhan이 언급 한 것처럼 제 지식과 직관력을 최대한 살려면 주석은 @RequestMapping (value = "/ login", method = "RequestMethod.POST") 주석을 사용하는 것이 좋습니다. 그런 다음 사용자가 URL과 함께 전달할 수있는 매개 변수에 관계없이 URL과 URI는 항상 / login이 기본값입니다. 이것이 로거가 기록한 것입니다. 사용자 이름과 암호 쌍이 아니라 "http : // localhost : 8080 / login"또는 포트가 무엇이든 상관 없습니다.
-
==============================
4.UsernamePasswordAuthenticationFilter의 RequestMatcher를 수정하여이 작업을 수행 할 수 있습니다. 예 :
UsernamePasswordAuthenticationFilter의 RequestMatcher를 수정하여이 작업을 수행 할 수 있습니다. 예 :
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .formLogin() .withObjectPostProcessor(new ObjectPostProcessor<UsernamePasswordAuthenticationFilter>() { @Override public <O extends UsernamePasswordAuthenticationFilter> O postProcess( O filter) { AntPathRequestMatcher pathMatcher = new AntPathRequestMatcher("/login", "POST"); RequestMatcher noQuery = new RequestMatcher() { @Override public boolean matches(HttpServletRequest request) { return request.getQueryString() == null; } }; AndRequestMatcher matcher = new AndRequestMatcher(Arrays.asList(pathMatcher, noQuery)); filter.setRequiresAuthenticationRequestMatcher(matcher); return filter; } }) .and() ... } }
참고 : 아래 요구 사항은 GET 요청이 발행되는 것을 방지하지 않으므로 자격 증명이 누출됩니다. 이것이 실제로 발생하지 않도록 UI에 달려 있습니다.
from https://stackoverflow.com/questions/38716703/how-do-i-disable-resolving-login-parameters-passed-as-url-parameters-from-the by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Errors / BindingResult 인수는 모델 특성, @RequestBody 또는 @RequestPart 인수 바로 다음에 선언되어야합니다. (0) | 2019.01.17 |
---|---|
[SPRING] IntelliJ는 tomcat / conf 디렉토리를 프로젝트 디렉토리에 복사해야합니다. (0) | 2019.01.17 |
[SPRING] Spring Data REST를 사용하는 REST API 전용 사용자 정의 기본 헤더 (0) | 2019.01.17 |
[SPRING] 봄 - 한 URL을 다른 URL로 다시 작성하십시오. (0) | 2019.01.17 |
[SPRING] Spring의 MessageInterpolator (0) | 2019.01.16 |