1

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

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

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

第 1 阶段已完成并且运行良好,我已将第 2 阶段制作为类似于此https://stackoverflow.com/a/9919988/1915913的内容,并且效果也很好,我得到了一个令牌,我能够验证它并登录.

但我的问题是,我怎样才能让它们同时为我工作,为相同的资源工作。我很确定我知道问题出在哪里,我创建了一个自定义过滤器并尝试使用表单登录过滤器。那行不通,但可以吗?还是有其他方法可以获得此功能?

这在预授权过滤器似乎接管并且我无法正常登录的情况下不起作用,并且每次我进入项目中的新页面时它似乎都会调用预授权过滤器。

我为此使用的类都非常简单。

我的安全应用上下文:

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

1 回答 1

1

当你扩展一个类时,你真的需要了解基类是如何工作的(继承的问题之一)。在这种情况下,您在不存在令牌的情况下返回“false”,这是返回对象的方法的任意选择。如果查看基类,您会看到它检查非空主体doAuthenticate,如果值为空,则立即返回,导致过滤器链立即继续,就好像预认证过滤器不存在一样全部。所以这是不对的。尝试返回 null 。

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

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

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

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

于 2014-08-20T13:16:03.540 回答