春季安全与匿名用户的请求缓存

huangapple go评论81阅读模式
英文:

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 = &quot;ROLE_ONE&quot;;

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser(&quot;user&quot;).password(passwordEncoder().encode(&quot;user&quot;)).authorities(THE_AUTHORITY);
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable()
                .requestCache().requestCache(new CustomRequestCache())
                .and().authorizeRequests()
                .antMatchers(&quot;/&quot;).permitAll()
                .anyRequest().hasAnyAuthority(THE_AUTHORITY)
                .and().formLogin().loginPage(&quot;/login&quot;).permitAll()
                    .loginProcessingUrl(&quot;/login&quot;)
                    .failureUrl(&quot;/&quot;)
                .successHandler(new SavedRequestAwareAuthenticationSuccessHandler())
                .and().logout().logoutSuccessUrl(&quot;/&quot;);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

and my controller

@RestController
public class TestController {

    @GetMapping(&quot;/test&quot;)
    public String getTest() {
        return &quot;You did it!&quot;;
    }

    @GetMapping(&quot;/&quot;)
    public String getRoot() {
        return &quot;&lt;a href=/test&gt;Go to test&lt;/a&gt;&quot;;
    }

    @GetMapping(&quot;/login&quot;)
    public String getLogin() {
        return &quot;&lt;form action=/login method=POST&gt;&lt;input name=username /&gt;&lt;input name=password /&gt;&lt;input type=submit /&gt;&lt;/form&gt;&quot;;
    }
}

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(&quot;Saving request to &quot; + httpServletRequest.getRequestURI());
        super.saveRequest(httpServletRequest, httpServletResponse);
    }

    @Override
    public HttpServletRequest getMatchingRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
         System.out.println(&quot;Returning request for &quot; + httpServletRequest.getRequestURI());
         return super.getMatchingRequest(httpServletRequest, httpServletResponse);
    }
}

huangapple
  • 本文由 发表于 2020年5月5日 17:13:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/61609660.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定