【发布时间】:2018-11-10 22:01:42
【问题描述】:
我有一个简单的问题要问你们。如果我在我的 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
我的 Spring Security 代码
网络安全配置
@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);
}
}
UserDetailsServiceImpl
@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());
}
}
也许有人可以帮助我!
【问题讨论】:
-
您可能需要配置成功转发url。
-
是否需要重写successauthentication方法?或者哪种方法是正确的?
标签: java spring spring-boot spring-security