通过预身份验证过滤器登录或在spring security中登录表单

时间:2014-08-20 12:00:42

标签: authentication spring-security pre-authentication

我正在寻找一种方法,您可以通过两种方式访问​​我的网站。

1)您应该能够使用表单登录并获取您的权限并使用该网站。

2)您应该能够登录到另一个网站,在那里您应该能够按下带有令牌的链接并登录到我的网站。 (我控制两个网站,他们使用相同的数据库)

第1阶段已经完成且运行良好,我已经完成了与此https://stackoverflow.com/a/9919988/1915913类似的第2阶段,并且工作正常,我得到一个令牌,我能够验证它并登录。

但我的问题是,对于相同的资源,我怎样才能让它们同时为我工作。我很确定我知道问题是什么,我创建了一个自定义过滤器,我尝试使用表单登录过滤器。 这不起作用,但可以吗?或者是否有其他方式可以获得此功能?

这不能以预验证过滤器似乎接管的方式工作,并且我无法正常登录工作,并且每当我进入项目中的新页面时,它似乎都会调用预认证过滤器。

我使用的类都非常简单。

我的安全应用背景:

<http pattern="/**" use-expressions="true" create-session="always">
        <intercept-url pattern="/login.jsp*" access="permitAll" />
        <intercept-url pattern="/**" access="denyAll" />
        <custom-filter position="PRE_AUTH_FILTER" ref="PreAuthenticatedProcessingFilter" />
        <form-login
                username-parameter="idnumber"
                password-parameter="password" login-processing-url="/processlogin"
                login-page='/login.jsp'
                authentication-failure-handler-ref="myAuthErrorHandler"
                authentication-success-handler-ref="mySuccessHandler"
                always-use-default-target='true'
                authentication-failure-url="/login.jsp?login_error=true"/>
        <logout logout-url="/logout/" logout-success-url="/login.jsp" delete-cookies="JSESSIONID"/>
        <session-management invalid-session-url="/">
            <concurrency-control expired-url="/" max-sessions="2" />
        </session-management>
    </http>

    <!-- form login -->
    <beans:bean id="mySuccessHandler" class="is.inna.rest.login.SuccessHandler"/>
    <beans:bean id="myAuthErrorHandler" class="is.inna.rest.login.AuthentificationListener"/>
    <beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    <beans:bean name="myUserDetailsService" class="is.inna.rest.login.LoginUserDetailService" />

    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="myUserDetailsService">
            <password-encoder ref="passwordEncoder" />
        </authentication-provider>
        <authentication-provider ref="preauthAuthProvider" />
    </authentication-manager>

     <!-- Pre auth -->
    <beans:bean id="userDetailsServiceWrapper"  class="is.inna.rest.login.AuthUserDetailService" />
    <beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <beans:property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceWrapper"/>
    </beans:bean>
    <beans:bean id="PreAuthenticatedProcessingFilter" class="is.inna.rest.login.PreAuthenticatedProcessingFilter">
        <beans:property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

我的用户详情服务

public class AuthUserDetailService implements AuthenticationUserDetailsService<Authentication> {

@Override
public UserDetails loadUserDetails(Authentication authentication) throws UsernameNotFoundException {
    String id = (String) authentication.getPrincipal();
    NotandiHelper notandi = UserDAO.getNotandiByToken(id);

    return new User(notandi.getUsername(), notandi.getPassword(), notandi.getAuthorities());
}

}

我的预审验过滤器

 public class PreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {

@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
    if(request.getParameter("id") != null){
        return request.getParameter("id");
    }else if(request.getParameter("idnumber") != null){
        return request.getParameter("idnumber");
    }
    return null;
}

@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
    if(request.getParameter("kt") != null){
        String[] credentials = new String[2];
        credentials[0] = request.getParameter("token");
        credentials[2] = request.getParameter("id");
        return credentials;
    }
    if(request.getParameter("idnumber")!= null){
        String[] credentials = new String[2];
        credentials[0] = request.getParameter("idnumber");
        credentials[1] = request.getParameter("password");
        return credentials;
    }

    return null;
}

1 个答案:

答案 0 :(得分:1)

当你扩展一个类时,你真的需要了解基类是如何工作的(继承问题之一)。在这种情况下,您将返回&#34; false&#34;在没有令牌存在的情况下,这是返回对象的方法的任意选择。如果您查看基类you will see that it checks for a non-null principal并立即从doAuthenticate返回(如果值为null),则会立即继续进行过滤器链,就好像预身份验证过滤器不在那里一样所有。这样做不对。请尝试返回null。

请注意,调试日志还应包含一条说明

的日志消息
  

preAuthenticatedPrincipal = null,尝试进行身份验证

您的配置中也不清楚如何验证令牌。似乎没有任何东西可以做到这一点。

请注意,如果您希望自动为未经身份验证的用户显示登录表单,则需要使用表单登录的入口点。 http403EntryPoint将立即返回403代码。