Spring Boot Security发送404虽然凭据是正确的 - 无法解析重定向路径

时间:2018-05-31 20:02:02

标签: java spring spring-boot spring-security

我为你们解决了一个简单的问题。我面临的问题是,如果我在Spring Boot应用程序中实现Spring Security,我总会收到404响应。

我通过整个代码进行了调试,我发现重定向路径始终是“/”而不是被调用的URL。

例如

call localhost:8080/user/login/ 
-> Spring Security check given credentials
-> they are correct 
-> resolve given path
-> SOMETHING STANGES HAPPENS HERE (Refer to figure (1))
-> resolve path to "/" and not "/user/login/" 
-> Therefore I get the response 404 NOT FOUND because it returns the wrong path

调试模式 - determineTargetUrl - > this.targetUrlParameter未设置,因此targetUrl将为“/”而不是 real targetUrl“/ user / login /”。代码如图(1)所示。

图(1)Spring Secutiry类 - AbstractAuthenticationTargetUrlRequestHandler enter image description here

我的Spring Security代码

WebSecurityConfig

@EnableWebSecurity

公共类WebSecurityConfig扩展了WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .cors()
            .disable()
            .csrf()
            .disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.POST, "/user/login/").permitAll()
            .antMatchers(HttpMethod.GET, "/user/secret/**").permitAll()
            .and()
            .addFilterBefore(new JWTLoginFilter("/user/login/", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

}

JWTLoginFilter

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

public JWTLoginFilter(String url, AuthenticationManager authManager) {
    super(new AntPathRequestMatcher(url));
    setAuthenticationManager(authManager);
}

@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException {
    User user = new ObjectMapper().readValue(req.getInputStream(), User.class);

    Optional<User> dbUser = SpringContextBridge.services().getUserRepository().findUserByEmail(user.getEmail());

    dbUser.ifPresent(us -> user.setPassword(SecretGenerator.generateSha256(user.getPassword(), us.getSecret())));

    return getAuthenticationManager()
            .authenticate(new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword(), Collections.emptyList())
            );
}

}

JWTAuthenticationFilter

public class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest) request);

    SecurityContextHolder.getContext().setAuthentication(authentication);
    filterChain.doFilter(request, response);
}

}

UserDetailsS​​erviceImpl

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

private UserRepository userRepository;

@Autowired
public void setUserRepository(UserRepository userRepository) {
    this.userRepository = userRepository;
}

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    Optional<User> user = userRepository.findUserByEmail(email);

    if (!user.isPresent()) {
        throw new UserNotFoundException("User with email: " + email + " not found");
    }
    return new org.springframework.security.core.userdetails.User(user.get().getEmail(), user.get().getPassword(), Collections.emptyList());
}

}

也许有人可以帮助我!

1 个答案:

答案 0 :(得分:0)

我有一个类似的问题,对我有用的解决方案是像这样重写AbstractAuthenticationProcessingFilter的successAuthentication方法

override fun successfulAuthentication(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain, authResult: Authentication?) {
    logger.info("Successful Authentication for user ${authResult?.principal}")
    SecurityContextHolder.getContext().authentication = authResult
    chain.doFilter(request, response)
}

注意:该示例在kotlin中