AuthenticationException.getAuthentication()的替换

时间:2015-01-08 11:17:34

标签: java spring login spring-security openid

以下方案

  • 我们有一个带有openid按钮的登录表单
  • 所有用户都可以使用user / passwd或openid
  • 登录
  • 当用户尝试使用openid登录并且没有帐户时,他会被重定向到注册表单
  • 这适用于spring-security 3.x,但不适用于即将发布的4.x版本,因为AuthenticationException.getAuthentication()方法已被删除

我们已经尝试过的事情:

  • 使用successhandler替换失败处理程序但导致OpenId-UserDetailService中出现UserNameNotFoundException,因此处理程序不会被调用
  • 在OpenId-UserDetailService中实现重定向,但是在这里我们无权访问HttpServletRequest和HttpServletResponse

这是实际的3.x工作代码

@Slf4j
@Component
public class OpenIDAuthenticationFailureHandlerImpl extends SimpleUrlAuthenticationFailureHandler implements OpenIDAuthenticationFailureHandler {
    @Nonnull
    private final NormalizedOpenIdAttributesBuilder normalizedOpenIdAttributesBuilder;

    @Autowired
    public OpenIDAuthenticationFailureHandlerImpl(@Nullable final NormalizedOpenIdAttributesBuilder normalizedOpenIdAttributesBuilder) {
        Assert.notNull(normalizedOpenIdAttributesBuilder);
        this.normalizedOpenIdAttributesBuilder = normalizedOpenIdAttributesBuilder;
    }

    private static void sessionShouldBePresent(@Nullable final HttpSession session) throws ServletException {
        if (session == null) {
            log.error("No Session found");
            throw new ServletException("No session found");
        }
    }

    private static boolean openIdAuthenticationSuccessfulButUserIsNotRegistered(@Nullable final AuthenticationException exception) {
        return exception instanceof UsernameNotFoundException &&
                exception.getAuthentication() instanceof OpenIDAuthenticationToken &&
                OpenIDAuthenticationStatus.SUCCESS == getOpenIdAuthenticationToken(exception).getStatus();
    }

    private static OpenIDAuthenticationToken getOpenIdAuthenticationToken(@Nonnull final AuthenticationException exception) {
        return (OpenIDAuthenticationToken) exception.getAuthentication();
    }

    @Override
    public void onAuthenticationFailure(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException exception) throws IOException, ServletException {
        if (openIdAuthenticationSuccessfulButUserIsNotRegistered(exception)) {
            redirectToOpenIdRegistrationUrl(request, response, exception);
        } else {
            super.onAuthenticationFailure(request, response, exception);
        }
    }

    private void redirectToOpenIdRegistrationUrl(@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response, @Nonnull final AuthenticationException exception) throws IOException, ServletException {
        final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
        addOpenIdAttributesToSession(request, getOpenIdAuthenticationToken(exception));
        redirectStrategy.sendRedirect(request, response, "/signup");
    }

    private void addOpenIdAttributesToSession(@Nonnull final HttpServletRequest request, @Nonnull final OpenIDAuthenticationToken openIdAuthenticationToken) throws ServletException {
        final HttpSession session = request.getSession(false);
        sessionShouldBePresent(session);
        final NormalizedOpenIdAttributes normalizedOpenIdAttributes = normalizedOpenIdAttributesBuilder.build(openIdAuthenticationToken);
        session.setAttribute(OPENID_SESSION_ATTRIBUTE_NAME, normalizedOpenIdAttributes);
    }
}

websecurity配置类

@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    private OpenIDAuthenticationFailureHandler openIDAuthenticationFailureHandler;
    @Autowired
    private OpenIDAuthenticationUserDetailsService openIDAuthenticationUserDetailsService;

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login/check")
                .permitAll();

        http.logout()
                .permitAll();

        http.exceptionHandling()
                .accessDeniedPage("/denied");

        http.openidLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login/openid")
                .failureUrl("/login/failure")
                .failureHandler(openIDAuthenticationFailureHandler)
                .defaultSuccessUrl("/", true)
                .authenticationUserDetailsService(openIDAuthenticationUserDetailsService)
                .permitAll();
    }
}

此实现基于此http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html

的代码

我们可以尝试与spring-security 4.x兼容的任何建议。我们还搜索了互联网,但我们发现的所有内容都不适用于spring-security 4.x

0 个答案:

没有答案