我正在尝试成功执行登录操作后实现主体{“ token”:“ asdasdasd”},但到目前为止,我无法做到这一点。我不太确定在使用SpringSecurity提供的默认登录路由时如何完成此操作。到目前为止,一切正常,但是我只需要将令牌放入体内即可。
JwtAuthenticationFilter
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
/* Trigger when we issue POST request to /login */
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
LoginViewModel credentials = null;
try {
credentials = new ObjectMapper().readValue(request.getInputStream(), LoginViewModel.class);
} catch (IOException e) {
e.printStackTrace();
}
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
credentials.getUsername(),
credentials.getPassword(),
new ArrayList<>());
Authentication auth = authenticationManager.authenticate(authenticationToken);
return auth;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
LoginViewModel.UserPrincipal principal = (LoginViewModel.UserPrincipal) authResult.getPrincipal();
String token = JWT.create()
.withSubject(principal.getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + JwtProperties.EXPIRATION_TIME))
.sign(HMAC512(JwtProperties.SECRET.getBytes()));
// where the token is set to the header
response.addHeader(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX + token);
}
}
JwtAuthorizationFilter
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
private UserRepository userRepository;
public JwtAuthorizationFilter(AuthenticationManager authenticationManager, UserRepository userRepository) {
super(authenticationManager);
this.userRepository = userRepository;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
// Read the Authorization header, where the JWT token should be
String header = request.getHeader(JwtProperties.HEADER_STRING);
// If header does not contain BEARER or is null delegate to Spring impl and exit
if (header == null || !header.startsWith(JwtProperties.TOKEN_PREFIX)) {
chain.doFilter(request, response);
return;
}
// If header is present, try grab user principal from database and perform authorization
Authentication authentication = getUsernamePasswordAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
// Continue filter execution
chain.doFilter(request, response);
}
private Authentication getUsernamePasswordAuthentication(HttpServletRequest request) {
String token = request.getHeader(JwtProperties.HEADER_STRING)
.replace(JwtProperties.TOKEN_PREFIX,"");
if (token != null) {
// parse the token and validate it
String userName = JWT.require(HMAC512(JwtProperties.SECRET.getBytes()))
.build()
.verify(token)
.getSubject();
// Search in the DB if we find the user by token subject (username)
// If so, then grab user details and create spring auth token using username, pass, authorities/roles
if (userName != null) {
User user = userRepository.findByUsername(userName);
LoginViewModel.UserPrincipal principal = new LoginViewModel.UserPrincipal(user);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userName, null, principal.getAuthorities());
return auth;
}
return null;
}
return null;
}
}
SecurityConfiguration
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private UserPrincipalDetailsService userPrincipalDetailsService;
private UserRepository userRepository;
public SecurityConfiguration(UserPrincipalDetailsService userPrincipalDetailsService, UserRepository userRepository) {
this.userPrincipalDetailsService = userPrincipalDetailsService;
this.userRepository = userRepository;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager(), this.userRepository))
.authorizeRequests()
.antMatchers("/resources/**", "/api/auth/**", "/").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.antMatchers("/api/public/management/*").hasRole("MANAGER")
.antMatchers("/api/public/admin/*").hasRole("ADMIN")
.anyRequest().authenticated();
}
@Bean
DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(this.userPrincipalDetailsService);
return daoAuthenticationProvider;
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
String json = "asdasdasd";
response.getWriter().write(json);
response.flushBuffer();