How can I get my Custom Filter to continue on to do Spring Session?

旧巷老猫 提交于 2019-12-12 04:25:48

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!