我想从方法implUserDetailsService类的loadUserByUsername()方法中获取客户端IP地址,但这是无效的
@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公开当前 请求。
答案 0 :(得分:0)
有多种选择可以使@Autowired
能够将HttpServletRequest
注入到bean中:
RequestContextListener
RequestContextFilter
。确保将其放在过滤器链的最开始(例如springSecurityFilterChain
之前)如果您使用的是Spring Boot,并且在类路径上具有spring-mvc,则其自动配置默认应为您注册一个RequestContextFilter。
答案 1 :(得分:-2)
将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自动装配。