Я занимаюсь разработкой веб-приложения, которое использует Spring Security в качестве поставщика аутентификации / авторизации.Вот как я его настраиваю:
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
//Allow resources for all pages
.antMatchers("/css/**", "/images/**", "/webjars/**").permitAll()
//Allow or disallow specific routes depending on user privileges
//Users
.antMatchers("/users/", "users/search").hasAuthority("View Users")
.antMatchers("/users/add", "/users/edit/*", "/users/delete/*").hasAuthority("Edit Users")
.antMatchers("/roles/", "roles/search").hasAuthority("View Roles")
.antMatchers("/roles/add", "/roles/edit/*", "/roles/delete/*").hasAuthority("Edit Roles")
.antMatchers("/permissions/", "permissions/search").hasAuthority("View Permissions")
//A million other antMatchers here...
//All custom routes require authentication
.anyRequest().authenticated()
//Custom login page and handling
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/perform_login")
.successHandler(loginHandler())
.failureUrl("/login_error")
.permitAll()
//Custom logout handling with POST request and logout handler for auditing
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessHandler(logoutHandler())
.logoutSuccessUrl("/logout_success")
.permitAll()
//Invalidate the session and delete the JSESSIONID cookie on logout
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
}
Я не хочу публиковать слишком много кода (я буду при необходимости), но по сути мои пользователи хранятся в базе данных, и я использую расширение UserDetails и UserDetailsService длявзаимодействовать между Spring Security и БД.В моей сущности User у меня есть логическое поле, которое контролирует, нужно ли пользователю менять свой пароль (первый вход в систему).Чтобы достичь этой функциональности при входе пользователя в систему, у меня есть следующий AuthenticationSuccessHandler:
public class LoginHandler implements AuthenticationSuccessHandler
{
@Autowired
private UserService userService;
@Autowired
private PreferenceService preferenceService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException
{
User user = userService.findById(((UserDetails) authentication.getPrincipal()).getId());
if (user.isMustChangePassword())
{
response.sendRedirect(request.getContextPath() + "/users/initialPasswordChange");
}
else
{
response.sendRedirect(request.getContextPath() + getAnchorPageURL(user));
}
}
}
Это отлично работает при входе в систему, поведение точно такое, как я хочу.На начальной странице смены пароля нет меню, но ничто не мешает пользователю изменить URL-адрес и перейти на домашнюю страницу без изменения своего пароля.В старые времена Spring MVC я бы создавал собственный класс Filter, работающий на каждой странице, который проверял бы, имеет ли пользователь, вошедший в систему, значение этого поля, равное true, и перенаправлял на начальную страницу смены пароля.Таким образом, весь сайт был бы недоступен, пока пароль не был изменен, независимо от того, что сделал пользователь.
Есть ли сегодня более элегантный способ Spring Security для этого?
Опять я предоставлю больше кода, если это может помочь, не хотел затоплять свой пост и хотелсначала включите самые важные биты.