英文:
Spring Security and RequestCache with Anonymous User
问题
这是我的安全配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.requestCache().requestCache(new CustomRequestCache())
.and().authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().hasAnyAuthority(Role.getAllRoles())
.and().formLogin().loginPage(LOGIN_URL).permitAll()
.loginProcessingUrl(LOGIN_PROCESSING_URL)
.failureUrl(LOGIN_FAILURE_URL)
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL);
}
问题在于在我从 / 导航到受保护的URL时,CustomRequestCache未被调用,因此SavedRequestAwareAuthenticationSuccessHandler在登录后不会重定向到请求的页面。
我推测这是因为 permitAll 创建了一个匿名用户。
我应该如何配置Spring Security才能使 SavedRequestAwareAuthenticationSuccessHandler 正常工作?
英文:
That's my Security Configuration
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.requestCache().requestCache(new CustomRequestCache())
.and().authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().hasAnyAuthority(Role.getAllRoles())
.and().formLogin().loginPage(LOGIN_URL).permitAll()
.loginProcessingUrl(LOGIN_PROCESSING_URL)
.failureUrl(LOGIN_FAILURE_URL)
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
.and().logout().logoutSuccessUrl(LOGOUT_SUCCESS_URL);
}
The problem is that the CustomRequestCache is not called when I navigate from / to a protected URL and so the SavedRequestAwareAuthenticationSuccessHandler does not redirect to the requested page after login.
I assume that this is because permitAll creates a anonymous user.
How do I have to configure Spring Security to make SavedRequestAwareAuthenticationSuccessHandler work?
答案1
得分: 1
作为答案发布以便包含我的代码。我尝试重新创建您的设置,这是我的安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String THE_AUTHORITY = "ROLE_ONE";
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("user")).authorities(THE_AUTHORITY);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().disable()
.requestCache().requestCache(new CustomRequestCache())
.and().authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().hasAnyAuthority(THE_AUTHORITY)
.and().formLogin().loginPage("/login").permitAll()
.loginProcessingUrl("/login")
.failureUrl("/")
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
.and().logout().logoutSuccessUrl("/");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
以及我的控制器:
@RestController
public class TestController {
@GetMapping("/test")
public String getTest() {
return "You did it!";
}
@GetMapping("/")
public String getRoot() {
return "<a href=/test>Go to test</a>";
}
@GetMapping("/login")
public String getLogin() {
return "<form action=/login method=POST><input name=username /><input name=password /><input type=submit /></form>";
}
}
我可以打开它,导航到 /
,点击链接到 /test
,此时我会被重定向到登录表单。登录后,我会被重定向到 /test
。
这是我的 CustomRequestCache
:
public class CustomRequestCache extends HttpSessionRequestCache {
@Override
public void saveRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("Saving request to " + httpServletRequest.getRequestURI());
super.saveRequest(httpServletRequest, httpServletResponse);
}
@Override
public HttpServletRequest getMatchingRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("Returning request for " + httpServletRequest.getRequestURI());
return super.getMatchingRequest(httpServletRequest, httpServletResponse);
}
}
英文:
Posting as an answer so I can include my code. I tried recreating your setup, this is my security configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String THE_AUTHORITY = "ROLE_ONE";
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("user")).authorities(THE_AUTHORITY);
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().disable()
.requestCache().requestCache(new CustomRequestCache())
.and().authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().hasAnyAuthority(THE_AUTHORITY)
.and().formLogin().loginPage("/login").permitAll()
.loginProcessingUrl("/login")
.failureUrl("/")
.successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
.and().logout().logoutSuccessUrl("/");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
and my controller
@RestController
public class TestController {
@GetMapping("/test")
public String getTest() {
return "You did it!";
}
@GetMapping("/")
public String getRoot() {
return "<a href=/test>Go to test</a>";
}
@GetMapping("/login")
public String getLogin() {
return "<form action=/login method=POST><input name=username /><input name=password /><input type=submit /></form>";
}
}
I can open it, navigate to /
, click the link to /test
at which point I'm redirected to the login form. After logging in, I'm redirected to /test
.
This is my CustomReuqestCache:
public class CustomRequestCache extends HttpSessionRequestCache {
@Override
public void saveRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("Saving request to " + httpServletRequest.getRequestURI());
super.saveRequest(httpServletRequest, httpServletResponse);
}
@Override
public HttpServletRequest getMatchingRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("Returning request for " + httpServletRequest.getRequestURI());
return super.getMatchingRequest(httpServletRequest, httpServletResponse);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论