В чем разница между аутентификацией и авторизацией в контексте Spring Security? - PullRequest
2 голосов
/ 12 октября 2019

Я работаю над проектом начальной загрузки java, в котором я пытаюсь настроить Spring Security для аутентификации пользователей с помощью JWT, руководства, которому я следую (а также многих учебных пособий и проектов, которые я нашел в Интернете). около двух разделов - аутентификация и авторизация .

В большинстве уроков есть два класса фильтров: один обрабатывает аутентификацию, а другой - авторизацию! (Некоторые из них я обнаружил только с одним классом, который расширяет класс OncePerRequestFilter).

В тех проектах, которые имеют два класса фильтров, класс фильтра аутентификации расширяется UsernamePasswordAuthenticationFilter класс. Класс авторизации расширяет класс BasicAuthenticationFilter.

Есть ли способ, которым я могу использовать только часть аутентификации в своем проекте, или мне следует использовать оба класса для настройки аутентификации пользователя в весенней безопасности?

Любое объяснение будет оценено.

Ответы [ 2 ]

3 голосов
/ 12 октября 2019

Есть ли способ, которым я могу использовать только часть аутентификации в моем проекте, или я должен использовать оба класса для настройки аутентификации пользователя в весенней безопасности?

Нет, понятия нетЧто касается только аутентификации, то у вас неправильное представление о безопасности Spring, безопасность Spring - это все о конфигурации, либо по умолчанию, либо путем реализации ваших пользовательских конфигураций. (AuthenticationFilters, AuthenticationProviders, AuthenticationToken и т. Д.)


Безопасность Spring полностью связана с аутентификацией и авторизацией, безопасность Spring настраивается путем объявления фильтра DelegatingFilterProxy в web.xml (в Spring загружается егобудет выполнено автоматической настройкой).

Spring security помещает WALL ( HttpFireWall ) перед вашим приложением с точки зрения прокси-фильтров или пружиныуправляемые бобы. Запрос может дойти до вашего приложения, если он успешно прошел как аутентификацию, так и авторизацию. Аутентификация - это идентификация пользователя.

она будет проходить

  • проверку учетных данных или
  • проверку содержимого заголовка авторизации или
  • проверка файла cookie, связанного с запросом (файл cookie JSESSIONID), т. Е. Сеанс
  • Если ни одно из указанных выше совпадений не идентифицировано как пользователь Anonymous.

Здесь, вна этом шаге Authentication объект будет создан. Из объекта аутентификации вы можете получить

  • подробности объекта (дополнительные сведения о запросе аутентификации)
  • основной объект (UserDetails илиAuthenticatedPrincipal или Principal)
  • учетные данные (обычно пароль, но может быть любым, относящимся к AuthenticationManager)
  • коллекции предоставлено Авторитами
  • и логическое , аутентифицированное .

2. Авторизация зависит от решения о доступе.

Там будет FilterSecurityInterceptor, который идет почти последним в цепочке фильтров, который получает Authentication объект из SecurityContext, получает список предоставленных полномочий (роли предоставлены), и он будетрешение о том, разрешить ли этот запрос достичь запрошенного ресурса или нет, решение принимается путем сопоставления с разрешенными AntMatchers, настроенными в HttpSecurityConfiguration.

. Рассмотрим исключения 401-UnAuthorized и 403-Forbidden. Эти решения будут приниматься последними в цепочке фильтров
401-UnAuthorized : не авторизованный пользователь пытается получить доступ к защищенному ресурсу.
403-Forbidden : пытается аутентифицированный пользовательдля доступа к ограниченному ресурсу.
Не прошедшему проверку подлинности пользователю будет разрешен доступ к неограниченным ресурсам, и он не получит ошибку UnAuthorized, но она обрабатывается AnonymousAuthenticationFilter, которая устанавливает полномочия ROLE_ANONYMOUS для неаутентифицированного пользователя.

Примечание
Ниже приведен порядок фильтров. где
Аутентификация - @ order-4
Авторизация - @ Order-9 (Last)

Из документа
В Spring Security есть несколько областей, где шаблоныВы определили, проверяются на входящие запросы, чтобы решить, как запрос должен быть обработан. Это происходит, когда FilterChainProxy решает, через какую цепочку фильтров должен быть пропущен запрос, а также когда FilterSecurityInterceptor решает, какие ограничения безопасности применяются к запросу. Важно понимать, что это за механизм и какое значение URL используется при тестировании по определенным вами шаблонам.

Порядок фильтров
Порядок, в котором фильтры определяются в цепочке:очень важный. Независимо от того, какие фильтры вы на самом деле используете, порядок должен быть следующим:
1. ChannelProcessingFilter, поскольку может потребоваться перенаправление на другой протокол
2. SecurityContextPersistenceFilter, поэтому SecurityContext может быть установлен в SecurityContextHolder в начале веб-запроса, и любые изменения в SecurityContext могут быть скопированы в HttpSession, когда веб-запрос заканчивается (готов для использования со следующимвеб-запрос)
3. ConcurrentSessionFilter, поскольку он использует функциональность SecurityContextHolder, но ему необходимо обновить SessionRegistry, чтобы отразить текущие запросы от основного
4. Механизмы обработки аутентификации -UsernamePasswordAuthenticationFilter, CasAuthenticationFilter, BasicAuthenticationFilter и т. Д., Чтобы SecurityContextHolder можно было изменить, чтобы он содержал действительный токен запроса аутентификации
5. SecurityContextHolderAwareRequestFilter, если вы используете его для установки Spring SecurityHttpServletRequestWrapper в ваш контейнер сервлетов
6. RememberMeAuthenticationFilter, так что, если более ранний механизм обработки аутентификации не обновил SecurityContextHolder, и запрос представляет файл cookie, который позволяет службам запомнить меняПоместите подходящий запомненный объект аутентификации туда
7. AnonymousAuthenticationFilter, так что если ранее механизм обработки аутентификации не обновил SecurityContextHolder, анонимный объект аутентификации будет помещен туда
8. ExceptionTranslationFilter, чтобы перехватить любые исключения Spring Security, чтобы ошибка HTTP возвращаласьsponse может быть возвращен или соответствующий AuthenticationEntryPoint может быть запущен
9. FilterSecurityInterceptor, чтобы защитить веб-URI и выдавать исключения, когда доступ запрещен

Просто чтобы дать некоторое представление о фильтрах в пружинной безопасности

enter image description here

Наконец, если вы новичок в безопасности пружин,Мое предложение состоит в том, чтобы попробовать максимальное количество примеров и больше времени уделить журналам отладки и попытаться понять поток.

0 голосов
/ 12 октября 2019

вам нужно написать свой userDetial, чтобы сообщить текущему пользователю авторизации и конфигурации, что

public class MyUserDetails implements UserDetails {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private User user;

public MyUserDetails(User user) {
    this.user = user;
}

@Override
public String getUsername() {
    return user.getLogin();
}

@Override
public String getPassword() {
    return user.getPassword();
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return user.getGrantedAuthorities();
}

@Override
public boolean isAccountNonExpired() {
    return user.getActivated();
}

@Override
public boolean isAccountNonLocked() {
    return user.getActivated();
}

@Override
public boolean isCredentialsNonExpired() {
    return user.getActivated();
}

@Override
public boolean isEnabled() {
    return user.getActivated();
}

} 

ur фильтр может быть таким

public class JWTFilter extends GenericFilterBean {

private TokenProvider tokenProvider;

public JWTFilter(TokenProvider tokenProvider) {
    this.tokenProvider = tokenProvider;
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
    throws IOException, ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    String jwt = resolveToken(httpServletRequest);
    if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
        Authentication authentication = this.tokenProvider.getAuthentication(jwt);
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
    filterChain.doFilter(servletRequest, servletResponse);
}

private String resolveToken(HttpServletRequest request){
    String bearerToken1 = RequestUtil.getTokenFromHeader(request);
    if (bearerToken1 != null) return bearerToken1;
    String jwt = request.getParameter(JWTConfigurer.AUTHORIZATION_TOKEN);
    if (StringUtils.hasText(jwt)) {
        return jwt;
    }
    return null;
}
}

, и вам нужно изменить ваш userDetailService навесна знает, как убить пользователя

@Component("userDetailsService")
public class DomainUserDetailsService implements UserDetailsService {

private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);

private final UserRepository userRepository;

public DomainUserDetailsService(UserRepository userRepository) {
    this.userRepository = userRepository;
}

@Override
@Transactional
public UserDetails loadUserByUsername(final String login) {
    log.debug("Authenticating {}", login);

    String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
    Optional<User> userByLoginFromDatabase = userRepository.findOneWithRolesByLogin(lowercaseLogin);
    return userByLoginFromDatabase.map(user -> new MyUserDetails(user))
        .orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database"));

}

}
...