问题
I've got this code which seems to be working mostly ok.
filter
public class JsonAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private final ObjectMapper objectMapper;
private final Validator validator;
protected JsonAuthenticationFilter(
final RequestMatcher matcher,
final ObjectMapper objectMapper,
final Validator validator
) {
super( matcher );
this.objectMapper = objectMapper;
this.validator = validator;
}
@Override
public Authentication attemptAuthentication( final HttpServletRequest request, final HttpServletResponse response )
throws AuthenticationException, IOException, ServletException {
PasswordCredentials credentials;
try {
credentials = objectMapper.readValue( request.getReader(), PasswordCredentials.class );
DataBinder dataBinder = new DataBinder( credentials );
dataBinder.setValidator( validator );
dataBinder.validate();
} catch ( final Exception e ) {
throw new BadRequestException( "Bad Request", e );
}
AbstractAuthenticationToken authRequest = credentials.toAuthenticationToken();
setDetails( request, authRequest );
return this.getAuthenticationManager().authenticate( authRequest );
}
protected void setDetails( HttpServletRequest request, AbstractAuthenticationToken authRequest ) {
authRequest.setDetails( authenticationDetailsSource.buildDetails( request ) );
}
@Override
@Autowired
public void setAuthenticationManager( final AuthenticationManager authenticationManager ) {
super.setAuthenticationManager( authenticationManager );
}
}
filter config
@Configuration
class FilterConfig {
@Bean
AuthenticationSuccessHandler successHandler() {
return new MySavedRequestAwareAuthenticationSuccessHandler();
}
@Bean
AuthenticationFailureHandler failureHandler() {
return new SimpleUrlAuthenticationFailureHandler();
}
@Bean
JsonAuthenticationFilter authenticationFilter( final ObjectMapper mapper, final Validator validator ) {
RequestMatcher matcher = new AndRequestMatcher( Arrays.asList(
new AntPathRequestMatcher( "/authentication/password", "POST" ),
new MediaTypeRequestMatcher( new ContentTypeContentNegotiationStrategy(),
MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8 )
) );
JsonAuthenticationFilter filter = new JsonAuthenticationFilter( matcher, mapper, validator );
filter.setAuthenticationSuccessHandler( successHandler() );
filter.setAuthenticationFailureHandler( failureHandler() );
return filter;
}
}
security config
@Configuration
@Order( SecurityConstants.WEB_SECURITY_CONFIG + 2 )
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final JsonAuthenticationFilter authenticationFilter;
WebSecurityConfig( final JsonAuthenticationFilter authenticationFilter ) {
this.authenticationFilter = authenticationFilter;
}
@Bean
SessionRepository<ExpiringSession> sessionRepository() {
return new MapSessionRepository();
}
@Override
protected void configure( final HttpSecurity http ) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint( ( request, response, authException ) -> {
response.sendError( HttpServletResponse.SC_UNAUTHORIZED );
} )
.and()
.addFilterAt( authenticationFilter, UsernamePasswordAuthenticationFilter.class )
.formLogin()
.and()
.csrf().disable();
}
I'm using this test to verify that the login has done all of the appropriate things, it is failing on the missing Set-Cookie
header.
@SpringBootTest
@AutoConfigureMockMvc
@RunWith( SpringRunner.class )
public class AuthenticationTest extends AbstractSecurityTest {
@Autowired
private MockMvc mvc;
@Autowired
private Gson gson;
@Test
public void validLogin() throws Exception {
log.debug( "posting password" );
String json = gson.toJson( new PasswordCredentials( name, pass ) );
this.mvc.perform(
post( "/authentication/password" )
.contentType( MediaType.APPLICATION_JSON )
.content( json ) )
.andExpect( header().string( "Set-Cookie", startsWith( "SESSION" ) ) )
.andExpect( status().is2xxSuccessful() );
}
it does not go on to create the session, or presumably, many other things I would get if I were simply doing form login. I've tried a number of things outside of what I've shown here, this is just my current iteration. Note: Using Spring Boot with versions in Spring Platform Athens RC1.
What do I need to add/remove to get it to continue doing the same things it would do if I were were using formLogin
?
来源:https://stackoverflow.com/questions/39281738/how-can-i-get-my-custom-filter-to-continue-on-to-do-spring-session