当我提供默认 index.jsp 时,404 错误消失了,而我的项目中缺少该 index.jsp。但这并没有解决我的问题,因为我需要 Rest response(JSON) 结果。我从 DispatcheServlet 和 Filter 链等的长代码调试中学到了什么。如果我们在 rest 调用后需要 JSON 响应,并且我们不打算发送任何视图响应(如 jsps),我们应该实现 AuthenticationSuccessHandler 并返回无效。
最初我的 spring-secuyrity.xml 如下:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<global-method-security pre-post-annotations="enabled" />
<http pattern="/abc/login" security="none"/>
<http pattern="/abc/**" entry-point-ref="jwtAuthenticationEntryPoint" create-session="stateless">
<csrf disabled="true"/>
<custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthorizationTokenFilter"/>
</http>
<beans:bean id="jwtAuthorizationTokenFilter" class="com.abc.xyz.controller.JwtAuthorizationTokenFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="<MyUserDetailsService>">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"/>
<class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="10" />
</beans:bean>
</beans:beans>
我改成如下:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<global-method-security pre-post-annotations="enabled" />
<http pattern="/abc/login" security="none"/>
<http pattern="/abc/**" entry-point-ref="jwtAuthenticationEntryPoint" create-session="stateless">
<csrf disabled="true"/>
<custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthorizationTokenFilter"/>
</http>
<beans:bean id="jwtAuthorizationTokenFilter" class="com.abc.xyz.controller.JwtAuthorizationTokenFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationSuccessHandler" ref="authSuccessHandler" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="<MyUserDetailsService>">
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="10" />
</beans:bean>
<!-- Auth Success handler -->
<beans:bean id="authSuccessHandler" class="com.abc.xyz.controller.JwtAuthenticationSuccessHandler" />
</beans:beans>
智威汤逊:
@Component
public class JwtAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
// Not to do anything
}
}
在上面的代码中,我们设置了 2 个 bean 属性,这些属性不需要在 JwtAuthorizationTokenFilter 中
JwtAuthorizationTokenFilter 扩展到 AbstractAuthenticationProcessingFilter
我相信通过反射它设置了 AbstractAuthenticationProcessingFilter 的 authenticationManager、successHandler
这是我在 AbstractAuthenticationProcessingFilter 中看到的以下 2 个方法
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public void setAuthenticationSuccessHandler(
AuthenticationSuccessHandler successHandler) {
Assert.notNull(successHandler, "successHandler cannot be null");
this.successHandler = successHandler;
}