Как получить IP-адрес клиента в ImpUserDetailsService - PullRequest
0 голосов
/ 18 мая 2019

Я хочу получить IP-адрес клиента в методе loadUserByUsername () из класса implUserDetailsService, это мой код, но он не работает

@Service
public class LoginServiceImpl implements UserDetailsService {

@Autowired
UserDao loginDao;

@Autowired
private HttpServletRequest request;

@Override
public UserDetails loadUserByUsername(String username) {
    try {
        final String ip = getClientIp(request);

        net.liyan.psc.main.entity.main.User user = loginDao.findByUserNameForLogin(username);
        if (user == null) throw new UsernameNotFoundException("User not found.");
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();

        if (isLocalZone()) {
            grantedAuthorities.add(new SimpleGrantedAuthority('ROLE_1'));
        } else {
            grantedAuthorities.add(new SimpleGrantedAuthority('ROLE_2'));
        }

        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                true,
                true,
                true,
                true,
                grantedAuthorities);
    } catch (UsernameNotFoundException ex) {
        throw new UsernameNotFoundException("User not found.");
    } catch (Exception ex) {
        throw new UsernameNotFoundException("User not found.");
    }
}

   private static String getClientIp(HttpServletRequest request) {

    String remoteAddr = "";

    if (request != null) {
        remoteAddr = request.getHeader("X-FORWARDED-FOR");
        if (remoteAddr == null || "".equals(remoteAddr)) {
            remoteAddr = request.getRemoteAddr();
        }
    }

    return remoteAddr;
}


private boolean isLocalZone(String Ip){
    // ...
}
}

Он получает исключение:

java.lang.IllegalStateException: Привязанный к потоку запрос не найден: Вы ссылаетесь на атрибуты запроса вне фактического веб-запроса или обрабатываете запрос вне первоначально принимающего потока?Если вы действительно работаете в веб-запросе и по-прежнему получаете это сообщение, ваш код, вероятно, выполняется за пределами DispatcherServlet / DispatcherPortlet: в этом случае используйте RequestContextListener или RequestContextFilter для предоставления текущего запроса.

Ответы [ 2 ]

0 голосов
/ 18 мая 2019

Существуют различные варианты, чтобы @Autowired мог вводить HttpServletRequest в bean-компонент:

  1. Регистрация RequestContextListener
  2. Регистрация RequestContextFilter.Убедитесь, что он находится в самом начале цепочки фильтров (например, перед springSecurityFilterChain)

Если вы используете загрузочную версию Spring и у вас есть spring-mvc на classpath, его автоконфигурация должназарегистрируйте один RequestContextFilter для вас по умолчанию.

0 голосов
/ 18 мая 2019

Измените loadUserByUsername(String username) на

loadUserByUsername(String username, HttpServletRequest request)

Передайте запрос от конца контроллера вашему сервисному концу. Что-то вроде ниже,

import javax.servlet.http.HttpServletRequest;
@Controller
public class YourControllerName {
       @Autowired
       UserDetailsService userDetailsService 
       @GetMapping("/your-url")
       public String methodName(HttpServletRequest request /*your other perams*/){
              UserDetails userDetails = userDetailsService .loadUserByUsername(String 
              username, request); 
              //other operations
             return "view";
        }
}

Удалите автопровод HttpServletRequest с конца службы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...