весенняя аутентификация в зависимости от аутентификации веб-сервера в Tomcat? - PullRequest
0 голосов
/ 24 октября 2019

Я запускаю весеннее веб-приложение в tomcat9, которое находится за apache2. Только пользователи, прошедшие аутентификацию в apache, могут получить доступ к приложению, и request.getRemoteUser () уже возвращает имя пользователя, как его видит apache. Я также могу получить свои сущности пользователя, вызвав userRepository.findByAuth0id (request.getRemoteUser ());

Прочитав некоторые из превосходных ответов здесь, я пришел к следующему:

Аутентификацияфильтр:

public class RemoteAuthenticationFilter implements Filter {

  @Autowired
  private UserRepository userRepository;

  @Override
  public void init(final FilterConfig fc) throws ServletException {

  }

  @Override
  public void doFilter(
      final ServletRequest req, final ServletResponse res, final FilterChain fc
  ) throws IOException, ServletException {
    final SecurityContext context = SecurityContextHolder.getContext();
    if (
      context.getAuthentication() != null &&
          context.getAuthentication().isAuthenticated()
    ) {
      // do nothing
    } else {
      final HttpServletRequest httpRequest = (HttpServletRequest) req;
      final String auth0id = httpRequest.getRemoteUser();
      final List<User> users =
          userRepository.findByAuth0id(auth0id);
      if (users.size() == 0)
        return;

      final Authentication auth = new RemoteAuthentication(users.get(0));
      SecurityContextHolder.getContext().setAuthentication(auth);
    }

    fc.doFilter(req, res);
  }

  @Override
  public void destroy() {

  }

}

Класс аутентификации:

public class RemoteAuthentication implements Authentication {

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

  public RemoteAuthentication(final User user) {
    this.user = user;
  }

  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    return new ArrayList<>(0);
  }

  @Override
  public Object getCredentials() {
    return user.getAuth0id();
  }

  @Override
  public Object getDetails() {
    return user;
  }

  @Override
  public Object getPrincipal() {
    return user.getLogin();
  }

  @Override
  public boolean isAuthenticated() {
    return true;
  }

  @Override
  public void setAuthenticated(final boolean isAuthenticated)
      throws IllegalArgumentException {
  }

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

bean в src / main / webapp / WEB-INF / applicationContext.xml:

    <bean id="authTokenFilter" class="com.kodekonveyor.market.authentication.RemoteAuthenticationFilter" scope="singleton" />

src / main / webapp / WEB-INF / spring / security.xml:

<b:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:b="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">

<http >
   <custom-filter ref="authTokenFilter" after="BASIC_AUTH_FILTER" /> 
</http>

</b:beans>

Код в одном из сервлетов, который уже может аутентифицироваться вручную с помощью request.getRemoteUser ():

final Authentication authentication =
    SecurityContextHolder
        .getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
  if (null == authentication)
    loggerService.call("authentication is null");
  else {
    final String currentUserName = authentication.getName();
    loggerService.call("current username from spring:" + currentUserName);
  }
} else
  loggerService.call("spring sees anon user");

Я вижу "аутентификация нулевая" в журналах.

Что я пропустил? Я также заинтересован в других, более эффективных способах достижения того же самого. Если бы я мог получить имя удаленного пользователя без запроса http, мне этого было бы достаточно.

...