[SPRING] Spring Security : 페이지의 북마크를 허용하기 위해 로그인 URL에 리디렉션 쿼리 매개 변수를 추가하는 방법은 무엇입니까?
SPRINGSpring Security : 페이지의 북마크를 허용하기 위해 로그인 URL에 리디렉션 쿼리 매개 변수를 추가하는 방법은 무엇입니까?
문제 시나리오
나는 현재 스프링 부트와 관련된 스프링 프로젝트 (보안 및 클라우드와 같은)를 기반으로하는 내 애플리케이션의 로그인 페이지에서 작업하고있다. 내 응용 프로그램의 사용자가 로그인 페이지를 북마크하기 때문에이 동작을 수행해야합니다. 내가 잠재적 인 문제에 대해 생각하기 시작했을 때, 응용 프로그램은 페이지를 북마크 한 후에 (여러 개의 URL이 될 수 있기 때문에) 리디렉션 할 위치를 알 수 없다는 것을 알았습니다. 일반적으로 사용자는 / dashboard가 아니며 인증 정보가 없기 때문에 로그인으로 리디렉션됩니다. 사용이 자신의 자격 증명을 제시하면 응용 프로그램이 사용자를 리디렉션합니다. 하지만 현재 세션에서 리디렉션 위치를 알리는 SavedRequest가 응용 프로그램에 저장되어있을 가능성이 있습니다.
달성하고자하는 것
기본적으로 달성하고자하는 것은 응용 프로그램이 사용자가 / login url에 책갈피를 설정 한 후에 어디로 갈지를 아는 것입니다. 이상적인 상황은 / login url이 redirect 매개 변수를 포함하는 것입니다. 예를 들어.
이제 사용자가 2 단계에서 제공된 URL을 북마크에 추가 한 다음 잠시 후 북마크를 클릭하면 합리적인 리디렉션을위한 충분한 정보가 애플리케이션에 제공됩니다.
누군가가 더 나은 접근법을 알고 있다면 나는 그것을 듣고 싶다.
지금까지 수행 된 단계
지금까지 StackOverflow에 대한 또 다른 대답에 대한 해결책을 찾았습니다. 올바른 방향으로 나아가는 것처럼 보이지만 원하는 기능 중 일부가 여전히 누락되었습니다.
LoginUrlAuthenticationEntryPoint 클래스의 사용자 정의 구현을 작성하여 시작했습니다. 이것은 다음과 같은 시작 메서드를 재정의합니다.
public class CustomLoginUrlAuthenticaitonEntryPoint extends LoginUrlAuthenticationEntryPoint
{
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException
{
if (!request.getRequestURI().equals(this.getLoginFormUrl()))
{
RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
redirectStrategy.sendRedirect(request, response, getLoginFormUrl() + "?redirect=" + request.getRequestURI() + "?" + request.getQueryString());
}
}
}
그런 다음이 사용자 지정 클래스를 기본 인증 진입 점으로 HttpSecurity에 추가했습니다.
@Configuration
@Order(-20)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint("/login"));
}
}
마지막으로 로그인 페이지를 서버에 연결하는 사용자 정의 로그인 컨트롤러를 구현했습니다.
@Controller
public class LoginController
{
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(@RequestParam(value = "redirect", required = false) String redirect)
{
ModelAndView model = new ModelAndView();
// Do something with the redirect url;
model.setViewName("login");
return model;
}
하지만 일단 이것을 구현하면 리디렉션이 올바르게 작동하고있는 것처럼 보였습니다. (/ 대시 보드? param = 값이 / login? redirect = / dashboard? param = value로 리디렉션되었지만 로그인 페이지가 표시되지 않았습니다. 그러나 / login url을 직접 방문하면 로그인 페이지가 표시됩니다.
그래서 나는 / login url에 커스텀 질의 매개 변수를 추가하는 것이 옳다고 생각한다.하지만 구현이 완벽하지는 않다. 누군가가 문제를 파악하거나 내 문제에 대해 더 나은 해결책을 제공 할 수 있습니까?
미리 감사드립니다.
해결법
-
==============================
1.경고 : 매개 변수를 사용하여 리디렉션 할 위치를 결정하면 Open Redirect Vulnerabilities까지 응용 프로그램을 열 수 있습니다. 사용자 입력에 따라 리디렉션을 수행 할 때 매우주의하십시오.
경고 : 매개 변수를 사용하여 리디렉션 할 위치를 결정하면 Open Redirect Vulnerabilities까지 응용 프로그램을 열 수 있습니다. 사용자 입력에 따라 리디렉션을 수행 할 때 매우주의하십시오.
계속 EntryPoint
첫 번째 단계는 URL이있는 매개 변수를 포함하는 역할을하는 AuthenticationEntryPoint를 작성하여 로그인 양식을 표시 할 때 URL에서 계속 진행하는 것입니다. 이 예제에서는 continue라는 매개 변수를 사용합니다.
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.util.UrlUtils; import org.springframework.web.util.UriComponentsBuilder; /** * @author Rob Winch * */ public class ContinueEntryPoint extends LoginUrlAuthenticationEntryPoint { public ContinueEntryPoint(String loginFormUrl) { super(loginFormUrl); } @Override protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) { String continueParamValue = UrlUtils.buildRequestUrl(request); String redirect = super.determineUrlToUseForThisRequest(request, response, exception); return UriComponentsBuilder.fromPath(redirect).queryParam("continue", continueParamValue).toUriString(); } }
WebSecurityConfig
다음 단계는 ContinueEntryPoint를 사용하는 보안 구성을 포함시키는 것입니다. 예 :
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .exceptionHandling() .authenticationEntryPoint(new ContinueEntryPoint("/login")) .and() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin(); } }
LoginController
마지막으로 사용자가 이미 인증 된 경우 매개 변수로 리디렉션하는 LoginController를 만들어야합니다. 예 :
import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.NotBlank; public class RedirectModel { @Pattern(regexp="^/([^/].*)?$") @NotBlank private String continueUrl; public void setContinue(String continueUrl) { this.continueUrl = continueUrl; } public String getContinue() { return continueUrl; } } @Controller public class LoginController { @RequestMapping("/login") public String login(Principal principal, @Valid @ModelAttribute RedirectModel model, BindingResult result) { if (!result.hasErrors() && principal != null) { // do not redirect for absolute URLs (i.e. https://evil.com) // do not redirect if we are not authenticated return "redirect:" + model.getContinue(); } return "login"; } }
전체 샘플
전체 예제는 rwinch / spring-security-sample에서 github에서 찾을 수 있습니다 (34087954-continue-on-login 브랜치). git을 사용하지 않으려는 경우 쉽게 다운로드 할 수 있습니다.
-
==============================
2.덜 제한적인 로그인을 시도하십시오. 보안 구성에 다음을 추가하십시오.
덜 제한적인 로그인을 시도하십시오. 보안 구성에 다음을 추가하십시오.
http .authorizeRequests() .antMatchers("/login").permitAll() ...
원본 스레드
from https://stackoverflow.com/questions/34087954/spring-security-how-to-add-a-redirect-query-parameter-to-the-login-url-to-allow by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] List 또는 String 배열을 Spring RestTemplate을 사용하여 getForObject에 전달하는 방법 (0) | 2019.04.14 |
---|---|
[SPRING] SpringApplication 기호를 확인할 수 없습니다. (0) | 2019.04.14 |
[SPRING] 스프링 보안 역할 계층 구조 문제 (0) | 2019.04.14 |
[SPRING] Spring WebMVC CRUD API 생성 방법 (0) | 2019.04.14 |
[SPRING] Spring Boot 2.0.0.M1 : org.springframework.boot.context.embed 패키지는 어디에 있습니까? [닫은] (0) | 2019.04.14 |