Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security OAuth2 dance and get parameters

In my Java Spring application I have implemented OAuth2 user authorization via external OAuth2 provider.

At my localhost in order to authenticate user via this external OAuth2 provider I need to go by the following url: https://127.0.0.1:8443/login/ok and right after OAuth2 dance I can get this user authenticated. So far everything is ok.

But when I have some request parameters in my login url, for example uid and level:

https://127.0.0.1:8443/login/ok?uid=45134132&level=3

after OAuth2 dance I'm redirected to https://127.0.0.1:8443/ and lose those parameters.

In my Chrome network panel I can see following set of calls:

  1. https://127.0.0.1:8443/login/ok?uid=45134132&level=3
  2. https://connect.ok.ru/oauth/authorize?redirect_uri=https://127.0.0.1:8443/login/ok?uid%3D45134132%26level%3D3&response_type=code&state=AKakq....
  3. https://127.0.0.1:8443/login/ok?uid=45134132&level=3&code=....
  4. https://127.0.0.1:8443/

So I'm losing these parameters after step #3.

Is it possible to configure Spring Security + OAuth2 to pass these parameters to step #4 also ?

This is my config(this a solution based on this answer Spring Security - Retaining URL parameters on redirect to login) but it doesn't work(AuthenticationProcessingFilterEntryPoint .commence method is not invoked):

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off   
        http
        .headers().frameOptions().disable()
        .and().logout()
        .and().antMatcher("/**").authorizeRequests()
            .antMatchers("/", "/login**", "/index.html", "/home.html").permitAll()
            .anyRequest().authenticated()
        .and().exceptionHandling().authenticationEntryPoint(new AuthenticationProcessingFilterEntryPoint("/"))
        .and().logout().logoutSuccessUrl("/").permitAll()
        .and().csrf().csrfTokenRepository(csrfTokenRepository())
        .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
        .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
        // @formatter:on
    }

    public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint {
        public AuthenticationProcessingFilterEntryPoint(String loginFormUrl) {
            super(loginFormUrl);
        }

        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException {
            RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
            redirectStrategy.sendRedirect(request, response, getLoginFormUrl() + "?" + request.getQueryString());
        }
    }

What can be wrong ?

like image 518
alexanoid Avatar asked Jan 09 '16 10:01

alexanoid


1 Answers

I have implemented this in the following way:

    private Filter ssoFilter(ClientResources client, String path) {
        OAuth2ClientAuthenticationProcessingFilter clientFilter = new OAuth2ClientAuthenticationProcessingFilter(path);
        .......
        clientFilter.setAuthenticationSuccessHandler(new UrlParameterAuthenticationHandler());
        return clientFilter;
    }

    public class UrlParameterAuthenticationHandler extends SimpleUrlAuthenticationSuccessHandler {

        @Override
        protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
                throws IOException, ServletException {
            String targetUrl = determineTargetUrl(request, response);

            if (response.isCommitted()) {
                logger.debug("Response has already been committed. Unable to redirect to " + targetUrl);
                return;
            }

            String queryString = HttpUtils.removeParams(request.getQueryString(), "state", "code");
            targetUrl = !StringUtils.isEmpty(queryString) ? targetUrl + "?" + queryString : targetUrl;
            getRedirectStrategy().sendRedirect(request, response, targetUrl);
        }

    }

Please correct me if there is a better approach

like image 90
alexanoid Avatar answered Sep 19 '22 18:09

alexanoid