К сожалению, я не смог найти способ добавить аутентификацию без сохранения состояния в мое приложение Spring Security. Я использую пользовательский AuthenticationPovider для аутентификации по запросу AJAX и AjaxLoginFilter с методом переопределения doFilter (). И на этом этапе все было хорошо. Затем я добавляю постоянный сервис запомнить меня. И снова мое приложение работает хорошо. Теперь я решил сделать проверку подлинности без сохранения состояния, добавив .sessionCreationPolicy (SessionCreationPolicy.STATELESS) в configure (). И потерпеть неудачу. Моя аутентификация сейчас неверна. Мое приложение требует только "принципала" для входа (с любыми "учетными данными"). Учетные данные стали непроверенными. Что не так с моей попыткой сделать проверку подлинности без сохранения состояния? Я думаю, что какой-то метод authenticate () работает некорректно, или порядок фильтров в цепочке неверен, но мой опыт не настолько высок, чтобы решить этот вопрос.
my AjaxLoginFilter
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (httpRequest.getRequestURL().toString().endsWith("/login") &&
httpRequest.getMethod().matches("POST")) {
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(httpRequest.getReader().lines().collect(Collectors.joining()), User.class);
Authentication auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
SecurityContextHolder.getContext().setAuthentication(auth);
chain.doFilter(request, response);
} else {
chain.doFilter(request, response);
}
}
}
my WebSecurityConfig
public static final String KEY = "posc";
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
UserService userService;
@Autowired
private AjaxAuthenticationProvider ajaxProvider;
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userService);
auth
.authenticationProvider(this.ajaxProvider)
.authenticationProvider(new RememberMeAuthenticationProvider(KEY));
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/**/*.css")
.antMatchers("/**/*.js")
.antMatchers("/**/*.png")
.antMatchers("/**/*.ico")
;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/login")
.permitAll()
.antMatchers("/editor.html")
.hasRole("ADMIN")
.and()
.authorizeRequests()
.antMatchers("/resources/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.defaultSuccessUrl("/index.html")
.and()
.exceptionHandling().accessDeniedPage("/error.html")
.and()
.logout()
.logoutUrl("/customlogout.html")
.logoutSuccessUrl("/login.html")
.permitAll()
.and()
.rememberMe()
.rememberMeServices(rememberMeServices());
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
@Bean
public AbstractRememberMeServices rememberMeServices() {
PersistentTokenBasedRememberMeServices rememberMeServices =
new PersistentTokenBasedRememberMeServices(KEY, userService, persistentTokenRepository());
rememberMeServices.setAlwaysRemember(true);
rememberMeServices.setCookieName("remember-me-posc");
rememberMeServices.setTokenValiditySeconds(1209600);
return rememberMeServices;
}
}
и мой LoginController
private AuthenticationManager authenticationManager;
@Autowired
private RememberMeServices rememberMeServices;
@PostMapping("/login")
public ResponseEntity login(final HttpServletRequest request, final HttpServletResponse response) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
Authentication authenticationFromContext =
SecurityContextHolder.getContext().getAuthentication();
rememberMeServices.loginSuccess(request, response, authenticationFromContext);
System.out.println("My login controller");
return ResponseEntity.ok(new HashMap<>());
}
my UserService
private final UserRepository userRepository;
private static List<User> users = new ArrayList();
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByUsername(username)
.map(UserDetailsAdapter::new)
.orElseThrow(() -> new UsernameNotFoundException("Can't found username \'" + username + "\'"));
}