Spring Security OAuth2跳舞并获取参数

时间:2016-01-09 10:49:31

标签: java spring spring-security spring-boot spring-security-oauth2

在我的Java Spring应用程序中,我通过外部OAuth2提供程序实现了OAuth2用户授权。

在我的localhost上,为了通过这个外部OAuth2提供程序对用户进行身份验证,我需要访问以下网址:https://127.0.0.1:8443/login/ok,然后在OAuth2舞蹈之后我可以通过以下用户进行身份验证。到目前为止一切正常。

但是当我在登录网址中有一些请求参数时,例如uid和level:

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

在OAuth2跳舞之后,我被重定向到https://127.0.0.1:8443/并丢失了这些参数。

在我的Chrome网络面板中,我可以看到以下一组来电:

  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/
  5. 所以我在步骤#3之后失去了这些参数。

    是否可以将Spring Security + OAuth2配置为将这些参数传递给步骤#4?

    这是我的配置(这是基于此答案Spring Security - Retaining URL parameters on redirect to login的解决方案),但它不起作用(AuthenticationProcessingFilterEntryPoint .commence method未被调用):

        @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());
            }
        }
    

    有什么不对?

1 个答案:

答案 0 :(得分:2)

我已通过以下方式实现此目的:

    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);
        }

    }

如果有更好的方法,请纠正我