简体   繁体   中英

spring security oauth2 manipulate request url before redirect

I have a Vaadin application that is secured using spring security OAuth2. This works fine except for the occasional PUSH or HEARTBEAT endpoint being used to request first and thus triggering the auth process and the user ends up on the wrong page (These endpoints should not be visited directly by the user).

A simple but unsecure fix is to permitAll() on these endpoints. However as this poses a threat I need to close this hole up.

To do this I would like to parse and potentially edit the request url before redirecting to it at successfull auth. How would I go about doing this?

I would guess I need to add a filter somewhere in the chain to intercept the request and edit it. But I'm not sure where.

Here is my client:

@Configuration
@EnableOAuth2Sso
public class OAuthConfig extends WebSecurityConfigurerAdapter
{

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login**").permitAll()
                .antMatchers("/vaadinServlet/PUSH/**").permitAll()          //todo fix this hole
                .antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll()      //todo fix this hole
                .anyRequest().authenticated()
                .and()
                .logout()
                .logoutSuccessUrl("/")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));

    }

    @Override
    public void configure(WebSecurity web) throws Exception
    {
        web.ignoring().antMatchers("/css/*").antMatchers("/VAADIN/**"); // Static resources are ignored
    }

}

And the server:

@Configuration
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter
{
//jwt token stuff & my own client/auth providers. Should not be important.
...
}

server login form:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{

    @Autowired
    private RestAuthenticationProvider authenticationProvider;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.authenticationProvider(authenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http
                .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/forgetPassword*").permitAll()
                .antMatchers(HttpMethod.POST,"/user/resetPassword*").permitAll()
                .antMatchers(HttpMethod.GET,"/user/changePassword*").permitAll()
                .antMatchers("/user/updatePassword*", "/user/savePassword*", "/updatePassword*")
                .hasAnyAuthority("CHANGE_PASSWORD_PRIVILEGE","ROLE_USER")
                .anyRequest().authenticated()
                .and()
                    .formLogin()
                    .loginPage("/login")
                    .permitAll()
                .and()
                    .csrf().csrfTokenRepository(csrfTokenRepository());
    }

    private CsrfTokenRepository csrfTokenRepository()
    {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }

}

Just add some implementation with your project

1: create Authentication Failure handler

@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {


    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        System.out.print("here failure");



        String s=request.getParameter("username");
        setDefaultFailureUrl("/login?error&username="+s);
        super.onAuthenticationFailure(request,response,exception);
    }

}

2: Authentication Success Handler

@Component
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request , HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        /* custom Block 
Do any thing here
  */

        setDefaultTargetUrl("/home/");
        super.onAuthenticationSuccess(request,response,authentication);
    }
}

3: access request entry point

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        System.out.print("Unauthorized Access");

        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }
}

Implement the components as per your requirement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM