我正在寻找一种方法,您可以通过两种方式访问我的网站。
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;
}
答案 0 :(得分:1)
当你扩展一个类时,你真的需要了解基类是如何工作的(继承问题之一)。在这种情况下,您将返回&#34; false&#34;在没有令牌存在的情况下,这是返回对象的方法的任意选择。如果您查看基类you will see that it checks for a non-null principal并立即从doAuthenticate
返回(如果值为null),则会立即继续进行过滤器链,就好像预身份验证过滤器不在那里一样所有。这样做不对。请尝试返回null。
请注意,调试日志还应包含一条说明
的日志消息preAuthenticatedPrincipal = null,尝试进行身份验证
您的配置中也不清楚如何验证令牌。似乎没有任何东西可以做到这一点。
请注意,如果您希望自动为未经身份验证的用户显示登录表单,则需要使用表单登录的入口点。 http403EntryPoint
将立即返回403代码。