How to get public ip from desktop application call to our webservice - java

I need to capture public ip of the system calling our api, that system is a desktop Application thats calling our rest api and I am using the following code
#RequestMapping(value = "/api", method = RequestMethod.POST)
public #ResponseBody JSON_Response sendMessage(#RequestBody Objectjson objjson,HttpServletRequest
request) {
LOG.debug("sending message via payless server");
inputjson.setSentFrom("Message Sent From Api");
// inputjson.setHostip(""+request.getRemoteHost());
//I am using following to capture it
LOG.debug("--------------------------"+request.getRemoteUser());
LOG.debug("--------------------------"+request.getLocalAddr());
LOG.debug("--------------------------"+request.getRemoteHost());
LOG.debug("--------------------------"+request.getPathInfo());
LOG.debug("--------------------------"+request.getPathTranslated());
LOG.debug("--------------------------"+request.getRemoteUser());
LOG.debug("--------------------------"+request.getRemoteUser());
LOG.debug("--------------------------"+request.getRemoteUser());
LOG.debug("--------------------------"+request.getRemoteUser());
LOG.debug("--------------------------"+request.getRemoteUser());
JSON_Response response = sendMessageInterface.processInput(inputjson);
LOG.debug("sending response message " + response.getStatusDescription());
return response;
}
I am getting my own server ip in the ip address.If i call the rest api from postman i am getting the correct ip address.
Please let me know if you find any other way to retrieve public ip .
I am using Wildfly Server wildfly-10.1.0.Final

This is the method that i Use to get the remote user IP address. Hope it helps
public HttpServletRequest getRequest() {
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (attribs instanceof ServletRequestAttributes) {
HttpServletRequest request = ((ServletRequestAttributes)attribs).getRequest();
return request;
}
return null;
}
public String getClientIp() {
String remoteAddr = "";
HttpServletRequest request = getRequest();
if (request != null) {
remoteAddr = request.getHeader("X-FORWARDED-FOR");
if (remoteAddr == null || remoteAddr.trim().isEmpty()) {
remoteAddr = request.getRemoteAddr();
}
}
return remoteAddr;
}

Related

Retrofit2 response code=401, message=Unauthorized. How to solve?

I use Retrofit2 to make REST API requests. I have my dummy server (that runs with spring boot) on my machine:
#RestController
class SecureServiceController {
private int counter = 1;
#RequestMapping(value = "/nnrf-nfm/v1/nf-instances/bee75393-2ac3-4e60-9503-854e733309d4", method = RequestMethod.PUT)
public ResponseEntity<NFProfile> nNrfNfManagementNfRegister() {
System.out.println(counter++ + ". Got NrfClient register request. " + new Date());
NFProfile nfProfile = new NFProfile();
nfProfile.setHeartBeatTimer(2);
ResponseEntity<NFProfile> responseEntity = ResponseEntity.status(201).body(nfProfile);
return responseEntity;
}
}
When client make request from the same machine it works. But when client make request from remote machine I have error response:
Response{protocol=http/1.1, code=401, message=Unauthorized, url=https://myhostname:8443/nnrf-nfm/v1/nf-instances/bee75393-2ac3-4e60-9503-854e733309d4}
Response error body: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>Error</title></head><body><h1>Error</h1></body></html>
I've read that such error means that client don't have the rights to access and need to add access token. But my server does not ask any access token (at least explicitly) and it should not ask it.
How to solve this problem?
My apiClient:
public class ApiClient {
private Map<String, Interceptor> apiAuthorizations;
private Builder okBuilder;
private retrofit2.Retrofit.Builder adapterBuilder;
private JSON json;
//a lot setters and getters
public <S> S createService(Class<S> serviceClass) {
return this.adapterBuilder.client(this.okBuilder.build()).build().create(serviceClass);
}
public void configureFromOkclient(OkHttpClient okClient) {
this.okBuilder = okClient.newBuilder();
this.addAuthsToOkBuilder(this.okBuilder);
}
}
my interface:
public interface NfInstanceIdDocumentApi {
#Headers({"Content-Type:application/json"})
#PUT("nf-instances/{nfInstanceID}")
Call<NFProfile> registerNFInstance(#Body NFProfile body, #Path("nfInstanceID") UUID nfInstanceID, #Header("Content-Encoding") String contentEncoding, #Header("Accept-Encoding") String acceptEncoding);
}
How I do call:
OkHttpClient okHttpClient= ClientFactory.createClient();
ApiClient client = new ApiClient();
client.configureFromOkclient(okHttpClient);
NFProfile body = getNfProfile();
String baseUri = getBaseUri();
UUID uuid = getUUID();
//create call
client.getAdapterBuilder().baseUrl(baseUri);
NfInstanceIdDocumentApi service = client.createService(NfInstanceIdDocumentApi.class);
Call<NFProfile> call = service.registerNFInstance(body, uuid, null, null);
//make call
Response<NFProfile> response = call.execute();
UPD
I found the problem. Server was running on Windows machine and firewall blocked incoming requests.

Right way to get user's IP

I have the following code which is supposed to get user's IP:
public String getUserIP()
{
Object details = getDetails();
if (details instanceof WebAuthenticationDetails)
{
return ((WebAuthenticationDetails)details).getRemoteAddress();
}
return "";
}
#Nullable
public Object getDetails()
{
Authentication authentication = getCurrentUserAuth();
return authentication != null ? authentication.getDetails() : null;
}
However, under some unknown circumstances it returns 127.0.0.1 instead of real IP.
I decided to re-write like that:
public String getUserIP()
{
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attr.getRequest();
String ip = request.getHeader("X-Forwarded-For").split(',')[0];
return ip;
}
But in some cases the header X-Forwarded-For is null. The exception only occurs where getUserIP() from the first snippet returns valid IP address. What's the problem? The web server is tomcat. Thanks in advance.
You can update like this.
public String getUserIP()
{
ServletRequestAttributes attr = (ServletRequestAttributes)
RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = attr.getRequest();
return request.getRemoteAddr();
}
You Can Try this
public static String getUserIP(HttpServletRequest request) {
String xForwardedForHeader = request.getHeader("X-Forwarded-For");
if (xForwardedForHeader == null) {
return request.getRemoteAddr();
} else {
// As of https://en.wikipedia.org/wiki/X-Forwarded-For
// The general format of the field is: X-Forwarded-For: client, proxy1, proxy2 ...
// we only want the client
return new StringTokenizer(xForwardedForHeader, ",").nextToken().trim();
}
}

post request in Unirest Java result on a 302 http result

I m training my self on creating a restful server and a desktop java based client.
my backend is Spring Boot based, I have the following controller :
#RestController
#RequestMapping(NiveauAccessController.URL)
public class NiveauAccessController extends GenericController{
public static final String URL = "/acl";
#Autowired
private NiveauAccessRepository niveauAccessRepository;
#PostMapping
private ServerResponse createACL(
#RequestParam("aclTitle") final String aclTitle,
#RequestParam("roles") final List<String> roles
){
if(isSessionValid()){
final MNG_NIVEAU_ACCEE mng_niveau_accee = new MNG_NIVEAU_ACCEE();
mng_niveau_accee.setAclTitle(aclTitle);
List<Role> enumRoles = new ArrayList();
roles.stream().forEach(role->{
enumRoles.add(Role.valueOf(role));
});
mng_niveau_accee.setRoles(enumRoles);
niveauAccessRepository.save(mng_niveau_accee);
initSuccessResponse(mng_niveau_accee);
return serverResponse;
}
initFailLoginResponse();
return serverResponse;
}
.
.
.
}
for my java client I m using this sample code to send a post request over my server :
#FXML
private void doAdd(ActionEvent event) throws UnirestException {
if (titleACL.getText().isEmpty()) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.initModality(Modality.WINDOW_MODAL);
alert.initOwner(((Node) event.getSource()).getScene().getWindow());
alert.setContentText("Veuillez remplir le champ");
alert.showAndWait();
titleACL.requestFocus();
return;
}
String title = titleACL.getText();
Predicate<? super JFXCheckBox> selectedCheckboxes = checkbox -> {
return checkbox.isSelected();
};
List<JFXCheckBox> selectedCheckBoxesList = observableCheckBoxes.values().stream().filter(selectedCheckboxes).collect(Collectors.toList());
final List<String> roles = new ArrayList<>();
selectedCheckBoxesList.stream().forEach(checkbox -> {
roles.add(checkbox.getText());
});
HttpResponse<String> asString = Unirest.post(ACL_URL)
.header("accept", "application/json")
.field("aclTitle", title)
.field("roles", roles)
.asString();
System.out.println(asString.getStatus());
System.out.println(asString.getHeaders().values());
if (asString.getStatus() == 200) {
}
}
my output is :
302
[[0], [Thu, 10 May 2018 13:30:05 GMT], [https://localhost:8443/acl]]
I don't understand why I m getting the 302 status code which is for URL redirection.
I m trying to use this post to add data to my database.
What should I do to make my Server accept this request?
havins ssl enabled my request over 8080 got redirection to 8443 this is no issue using a web browser because it will handle redirection but in a javafx client you have to handle the redirect by your self so there is a possible solution
if (asString.getStatus() == 200) {
//your success handler code
}else if (asString.getStatus() == 302) {
// use your Rest api to do the request using the response body
}

Issues When Trying to Obtain Client's IP Address using Spring Boot Rest

Using Spring Boot and Java 1.7 to obtain a client's IP Address from a HTTP GET Call via Spring Rest.
RestController:
#RestController
#RequestMapping("/api/v1")
public class IpFinderController {
private HttpHeaders headers;
private static final String[] IP_HEADER_CANDIDATES = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA", "REMOTE_ADDR"
};
public IpFinderController() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
}
#RequestMapping(value = "/ipAddress", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<Object> getIpAddress(HttpServletRequest request)
throws IOException {
String remoteAddress = "";
if (request != null) {
remoteAddress = getClientIpAddress(request);
System.out.println("IP Address: " + remoteAddress);
}
return new ResponseEntity<Object>(remoteAddress, headers, HttpStatus.OK);
}
public static String getClientIpAddress(HttpServletRequest request) {
for (String header : IP_HEADER_CANDIDATES) {
String ip = request.getHeader(header);
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
return ip;
}
}
return request.getRemoteAddr();
}
}
I get this from stdout:
IP Address: 0:0:0:0:0:0:0:1
But I get this from the REST Call (via Swagger):
Response Body:
no content
Response Code:
0
Response Header:
{
"error": "no response from server"
}
When using curl from the command line:
curl -i -X GET --header 'Accept: application/json' 'http://localhost:8080/ipservice/api/v1/ipAddress'
Received this output:
curl: (3) Port number ended with ' '
0:0:0:0:0:0:0:1
Question(s):
Why am I getting 0:0:0:0:0:0:0:1 and not getting this as real IP address (is it because the client is behind a proxy / router)?
Why did I get a no content when running it via "Try it out" button on Swagger?
Why from the curl do I have problems and why is it not in JSON format?
Are there any 3rd party open source libraries which can help obtain a client's IP Address via HTTP Request? (ideal clients would be command line, web browsers, and mobile apps whether Android or iOS)?

how to sync cookies in gwt client application and google app engine server

I develop gwt client application for web and i used google app engine for server
I write the server in java
I send the requests to server with RequestBuilder
how I can sync the cookies between server and client.
every request client send to server the server create new session
I want to avoid it
in server I write code like this in every request
private void addCookies(){
String jsessionId = request.getParameter("JSESSIONID");
if (jsessionId != null && !jsessionId.isEmpty()) {
Cookie userCookie = new Cookie("JSESSIONID", jsessionId);
response.addCookie(userCookie);
} else {
String sessionId = request.getSession().getId();
Cookie userCookie = new Cookie("JSESSIONID", sessionId);
response.addCookie(userCookie);
}
}
So for the first request I created cookie with sessionId and I return the session id to client in response
In client I write code like this
public void setSessionId(String sessionId) {
Cookies.setCookie(JSESSIONID, sessionId);
}
I get the sessionId from server and add to cookie
When i send request with RequestBuilder is see like this
public void sendRequest(final BaseRequest baseReuest){
long currentTime = getApplicationServices().getTimeManager().getCurrentDate().getTime();
if(isSessionIdle()){
getBaseClientFactory().restart(true);
return;
}
if(baseReuest.getOptionsRequest().isShowLoader()){
showLoader(true);
loaderRequestsCounter++;
}
try {
String url = baseUrl + baseReuest.getMethodName();
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, url);
requestBuilder.setHeader("Content-type", "application/x-www-form-urlencoded");
baseReuest.addParam(JSESSIONID, getSessionId());
requestBuilder.sendRequest(baseReuest.getParamsAsString(), new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
requestFinish(baseReuest);
int status = response.getStatusCode();
if(status == 200){
String json = response.getText();
BaseRequestResponse baseRequestResponse = baseReuest.buildResponse(json);
if(!baseRequestResponse.isSuccess()){
showFailureMessage(baseRequestResponse.getFailureResponse());
}
baseReuest.notifyResponse(baseRequestResponse);
}
else{
onErrorResponse();
}
}
#Override
public void onError(Request request, Throwable exception) {
onErrorResponse();
}
private void onErrorResponse(){
requestFinish(baseReuest);
String message = getLabels().getLabel(IGeneralInfoLabels.THERE_IS_PROBLEM_ACCESSING_THE_SERVER);
if(!isOnline()){
message = getApplicationServices().getGeneralManager().getLocalLabel().connectionNotAvailable();
}
FailureResponse failureResponse = new FailureResponse(message);
showFailureMessage(failureResponse);
baseReuest.notifyFailureResponse(failureResponse);
}
private void showFailureMessage(FailureResponse failureResponse){
if(baseReuest.getOptionsRequest().isShowMessage()){
BaseRequestManager.this.showFailureMessage(failureResponse);
}
}
});
lastRequestSentTime = currentTime;
} catch (RequestException e) {
showLoader(false);
requestFinish(baseReuest);
}
}
for example for first request the sessionId is jk7br57mo1e5 so I add the sessionId to cookie in client
but in every request the server created new sessionId why?
thank you

Categories