spring security 配置successHandler无效,仍跳转默认路径
spring security自定义配置类继承WebSecurityConfigurerAdapter,一般会配置开放接口、登录接口以及自定义的过滤器等// 这里我配置了登录成功后返回json数据,但并没有效果,仍然跳转到默认路径/http.formLogin().loginProcessingUrl("/login").successHandler((request, response, aut
·
spring security自定义配置类继承WebSecurityConfigurerAdapter,一般会配置开放接口、登录接口以及自定义的过滤器等
// 这里我配置了登录成功后返回json数据,但并没有效果,仍然跳转到默认路径/
http
.formLogin()
.successHandler(
(request, response, authentication) -> {
CustomUser principal = (CustomUser) authentication.getPrincipal();
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.write(JSON.toJSONString(ResultVo.SUCCESS(JwtUtils.generateJsonWebToken(principal))));
out.flush();
out.close();
}
)
走进successHandler()方法看到,该方法位于AbstractAuthenticationFilterConfigurer类中
public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecurityBuilder<B>, T extends AbstractAuthenticationFilterConfigurer<B, T, F>, F extends AbstractAuthenticationProcessingFilter> extends AbstractHttpConfigurer<T, B> {
private F authFilter;
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource;
private SavedRequestAwareAuthenticationSuccessHandler defaultSuccessHandler;
private AuthenticationSuccessHandler successHandler;
private LoginUrlAuthenticationEntryPoint authenticationEntryPoint;
private boolean customLoginPage;
private String loginPage;
private String loginProcessingUrl;
private AuthenticationFailureHandler failureHandler;
private boolean permitAll;
private String failureUrl;
protected AbstractAuthenticationFilterConfigurer() {
// 这里面定义了默认的登录成功处理SavedRequestAwareAuthenticationSuccessHandler
this.defaultSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
this.successHandler = this.defaultSuccessHandler;
this.setLoginPage("/login");
}
public final T defaultSuccessUrl(String defaultSuccessUrl) {
return this.defaultSuccessUrl(defaultSuccessUrl, false);
}
public final T defaultSuccessUrl(String defaultSuccessUrl, boolean alwaysUse) {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setDefaultTargetUrl(defaultSuccessUrl);
handler.setAlwaysUseDefaultTargetUrl(alwaysUse);
this.defaultSuccessHandler = handler;
return this.successHandler(handler);
}
...
// 自定义成功处理调用这个方法,都是设置successHandler
public final T successHandler(AuthenticationSuccessHandler successHandler) {
this.successHandler = successHandler;
return this.getSelf();
}
}
可以看出这个类是认证过滤器配置类,因为我后面还配置了自定义的登录过滤器,所有会不会是后面配置的过滤器把上面的配置覆盖掉了
public class AuthenticationProcessingFilter extends UsernamePasswordAuthenticationFilter {
/**
* json格式登录
* @param request
* @param response
* @return
* @throws AuthenticationException
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
ObjectMapper mapper = new ObjectMapper();
UsernamePasswordAuthenticationToken authRequest = null;
try (InputStream is = request.getInputStream()) {
Map<String, String> authenticationBean = mapper.readValue(is, Map.class);
authRequest = new UsernamePasswordAuthenticationToken(authenticationBean.get("username"), authenticationBean.get("password"));
} catch (IOException e) {
e.printStackTrace();
authRequest = new UsernamePasswordAuthenticationToken("", "");
}
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
} else {
return super.attemptAuthentication(request, response);
}
}
}
这里继承UsernamePasswordAuthenticationFilter ,重写的认证方法,走进UsernamePasswordAuthenticationFilter 发现他继承AbstractAuthenticationProcessingFilter
public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean implements ApplicationEventPublisherAware, MessageSourceAware {
protected ApplicationEventPublisher eventPublisher;
protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
private AuthenticationManager authenticationManager;
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private RememberMeServices rememberMeServices = new NullRememberMeServices();
private RequestMatcher requiresAuthenticationRequestMatcher;
private boolean continueChainBeforeSuccessfulAuthentication = false;
private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();
private boolean allowSessionCreation = true;
// 他里面也定义的这个SavedRequestAwareAuthenticationSuccessHandler
// 我上面配置的SuccessHandler没有生效,可能是他走的是这个
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
...
// 这里面也有一个设置SuccessHandler的方法
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
Assert.notNull(successHandler, "successHandler cannot be null");
this.successHandler = successHandler;
}
}
然后我就在配置类中添加过滤器的地方设置successHandler
@Bean
public AuthenticationProcessingFilter authenticationProcessingFilter() throws Exception {
AuthenticationProcessingFilter authenticationProcessingFilter = new AuthenticationProcessingFilter();
authenticationProcessingFilter.setAuthenticationManager(authenticationManagerBean());
// 设置successHandler
authenticationProcessingFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
return authenticationProcessingFilter;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(adminAuthenticationProvider());
}
/**
* 自定义认证
* @return
*/
@Bean
public AdminAuthenticationProvider adminAuthenticationProvider() {
return new AdminAuthenticationProvider();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return (request, response, authentication) -> {
CustomUser principal = (CustomUser) authentication.getPrincipal();
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.write(JSON.toJSONString(ResultVo.SUCCESS(JwtUtils.generateJsonWebToken(principal))));
out.flush();
out.close();
};
}
这样设置就可以了。总结:当添加过滤器时,在过滤器中设置AuthenticationSuccessHandler,而不要在http.formLogin()后面设置
更多推荐
已为社区贡献1条内容
所有评论(0)