我按照教程https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/将jwt集成到我的应用程序中。我正在尝试将自定义successhandler添加到我的应用程序中。不幸的是,成功的登录请求不会触发successhandler。我尝试返回一个用户对象,而不是在标头中使用令牌进行空响应。我的处理程序是
@Component
public class AuthSuccessHandler implements AuthenticationSuccessHandler {
@Autowired
private ApplicationUserRepository userRepository;
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
UserDetails user = (UserDetails) authentication.getPrincipal();
AuthInfo authInfo = new AuthInfo();
authInfo.setUser(userRepository.findOneByUserName(user.getUsername()));
authInfo.setToken(response.getHeader("Authentication"));
response.getWriter().write(objectMapper.writeValueAsString(authInfo));
response.setContentType("application/json");
response.setStatus(200);
}
}
我已在WebSecurityConfigurer.configure()
中将其配置为
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.antMatchers(HttpMethod.GET, "/public/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.successHandler(successHandler)
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager(), securityConfig))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), securityConfig))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@ pvpkiran的解决方案并没有奏效。在调试时,我发现authenticationfilter正在运行两次,并且授权过滤器没有触发。下面给出了应用程序日志中可用的过滤器列表
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
JWTAuthenticationFilter
JWTAuthorizationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
答案 0 :(得分:0)
试试这个。创建这样的本地方法。
public JwtAuthenticationTokenFilter authenticationTokenFilter() {
JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(successHandler);
return filter;
}
然后像这样更改配置方法
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.antMatchers(HttpMethod.GET, "/public/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
另一点是,最好不要让你的AuthSuccessHandler
bean(删除@Component
)并在你的安全配置中创建一个像这样的AuthSucessHandler对象。原因是,如果您将AuthSuccessHandler声明为bean,则spring将扫描它并添加两个SuccessHandler(
1.扫描豆子时,
2.在SecurityConfig中添加它时
)
@EnableWebSecurity
@Configuration
public class JwtSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ApplicationUserRepository userRepository;
@Autowired
private ObjectMapper objectMapper;
public JwtAuthenticationTokenFilter authenticationTokenFilter() {
JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
filter.setAuthenticationManager(authenticationManager());
AuthSuccessHandler successHandler = new AuthSuccessHandler(userRepository, objectMapper):
filter.setAuthenticationSuccessHandler(successHandler);
return filter;
}
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.antMatchers(HttpMethod.GET, "/public/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
像这样更改您的AuthSuccessHandler
public class AuthSuccessHandler implements AuthenticationSuccessHandler {
private ApplicationUserRepository userRepository;
private ObjectMapper objectMapper;
public AuthSuccessHandler(ApplicationUserRepository userRepository, ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
this.userRepository = userRepository;
}
........
}