Spring Security 3.1.4不同页面上的多个登录表单,具有相同的Authentication Manager

时间:2013-09-25 13:19:54

标签: spring login spring-security spring-social

我实际上已经坚持了一段时间,现在不知道如何进一步发展。 我希望有多个标签,但据我所知,在同一个http块中是不可能的。 这样做的原因是我希望authentication-failure-url指向登录尝试来自的页面(并且在成功尝试时还将用户重定向回该站点)。

我有一个文件header.jsp,我有登录表单。我希望将来在我的所有页面上都包含此内容,以使用户能够从所有页面登录而无需重定向。

我该怎么做?

我的大部分代码都来自春季样本。 (安全+社交+注册示例) 这是我的security.xml的重要部分(没有任何尝试实现此目的)

<http pattern="/resources/**" security="none" />

<http pattern="/project/" security="none" />

<http use-expressions="true">

        <!-- Authentication policy -->

        <form-login login-page="/signin" login-processing-url="/signin/authenticate" authentication-failure-url="/signin?error=bad_credentials" />

        <logout logout-url="/signout" delete-cookies="JSESSIONID" />

        <intercept-url pattern="/addcourse" access="isAuthenticated()" />

        <!--<intercept-url pattern="/**" access="isAuthenticated()"  />-->

</http>

据我了解,我可以使用多个HTTP块?像这样:

<!-- Login place 1, sign in page -->
<http pattern="/signin" use-expressions="true">
    <form-login login-page="/signin" login-processing-url="/signin/authenticate" authentication-failure-url="/signin?error=bad_credentials" />
    <intercept-url pattern="/addcourse" access="isAuthenticated()" />
    <logout logout-url="/signout" delete-cookies="JSESSIONID" />
</http>

<!--Login place 2, start page -->
<http pattern="/" use-expressions="true">
    <form-login login-page="/" login-processing-url="/signin/authenticate" authentication-failure-url="/?error=bad_credentials" />
    <logout logout-url="/signout" delete-cookies="JSESSIONID" />
</http>

这给了我

Sep 26, 2013 11:57:43 PM org.apache.catalina.core.StandardContext listenerStart

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'providerSignInController' defined in class path resource [com/courseportal/project/config/SocialConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.security.web.savedrequest.RequestCache]: : No qualifying bean of type [org.springframework.security.web.savedrequest.RequestCache] is defined: expected single matching bean but found 2: org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.security.web.savedrequest.RequestCache] is defined: expected single matching bean but found 2: org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#1

    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)

另一种尝试是在security.xml中创建一个过滤器,用于正确路由流量。我不确定如何做到这一点。

我希望有人可以帮助我,并说出适当的方法。

祝你好运, Nilsi

2 个答案:

答案 0 :(得分:1)

我将准确回答

  

原因是我希望authentication-failure-url指向登录尝试来自的页面(并且在成功尝试时还将用户重定向回该站点)。

为了在我们的项目中这样做,我们添加了非常简单的入口点,如下所示:

<http ... entry-point-ref="LoginUrlAuthenticationEntryPoint"> 
   ...

在同一个春天之后,我们定义了切入点:

<bean id="LoginUrlAuthenticationEntryPoint"
 class="YOU_CLASS_LoginUrlAuthenticationEntryPoint">
 <property name="loginFormUrl" value="/signin" />
</bean>

现在您已将入口点声明为org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint的扩展名。这样做的目的是在登录后添加到登录URL返回实际页面的路径,因此您的登录URL将看起来像:http://mysite/signin?redirect_url=http://mysite/some_page.jsp

import import org.springframework.security.web.util.*;
...
public class YOU_CLASS_LoginUrlAuthenticationEntryPoint extends
    LoginUrlAuthenticationEntryPoint {
...
@Override
protected String buildRedirectUrlToLoginPage(
      HttpServletRequest request, 
      HttpServletResponse response,
      AuthenticationException authException) {
//following code check if your on login page already, then you don't add redirect
    String loginForm = 
        determineUrlToUseForThisRequest(request, response, authException);

    if (UrlUtils.isAbsoluteUrl(loginForm)) {
        return loginForm;
    }

之后使用RedirectUrlBuilder创建看起来像http://mysite/signin?redirect_url=http://mysite/some_page.jsp的路径并从此方法返回它。几乎完成....

成功登录后分析参数redirect_url并将用户重定向到其页面

答案 1 :(得分:-1)

通过Ajax POST登录表单,如有必要,在成功登录后刷新当前页面(可能提示用户执行此操作)或登录失败时显示错误消息“登录失败”。

为此,请实施自定义AuthenticationSuccessHandlerAuthenticationFailureHandler

成功:返回HTTP 204 No Content作为成功的指示,并在客户端重新加载页面

失败:返回HTTP 401 Unauthorized以指示失败,并在客户端显示错误消息