I had just changed My IDE from Eclipse To Idea 14 ,and find a log loop problem.
I can't post image,here is the link:
http://img.rehulu.com/idea.png
Just like the picture,keep looping about half a second and there is no income request.
The same code in Eclipse is OK.
web.xml
<filter>
<filter-name>loggingFilter</filter-name>
<filter-class>com.rehulu.coreapi.service.impl.LoggingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loggingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
LoggingFilter.class
public class LoggingFilter extends OncePerRequestFilter {
protected static final Logger logger = Logger.getLogger(LoggingFilter.class);
private AtomicLong id = new AtomicLong(1);
private static final String REQUEST_PREFIX = "Req:%s sId:%s Ip:%s Method:%s Uri:%s Parameter:%s";
private static final String RESPONSE_PREFIX = "Resp:";
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {
long requestId = id.incrementAndGet();
request = new RequestWrapper(requestId, request);
response = new ResponseWrapper(requestId, response);
try {
filterChain.doFilter(request, response);
} finally {
logRequest(request);
logResponse((ResponseWrapper) response);
}
}
private void logRequest(final HttpServletRequest request) {
StringBuilder msg = new StringBuilder();
msg.append(REQUEST_PREFIX);
HttpSession session = request.getSession(false);
String id = "";
if (session != null) {
id = session.getId();
}
String uri = request.getRequestURI();
String method = request.getMethod();
String parameter = "";
if (request instanceof HttpServletRequest && !isMultipart(request)) {
HttpServletRequest requestWrapper = (HttpServletRequest) request;
Map<String, String[]> parameters = requestWrapper.getParameterMap();
for (Entry<String, String[]> entry : parameters.entrySet()) {
String[] value = entry.getValue();
String keyV = "";
if (value == null || value.length == 0) {
continue;
} else {
if (value.length == 1) {
keyV = value[0];
} else {
keyV = Arrays.toString(value);
}
}
parameter += "{" + entry.getKey() + ":" + keyV + "}";
}
}
logger.info(String.format(REQUEST_PREFIX, String.valueOf(((RequestWrapper) request).getId()), id,
IPUtil.getClientIP(request), method, uri, parameter));
}
private boolean isMultipart(final HttpServletRequest request) {
return request.getContentType() != null && request.getContentType().startsWith("multipart/form-data");
}
private void logResponse(final ResponseWrapper response) {
StringBuilder msg = new StringBuilder();
msg.append(RESPONSE_PREFIX).append((response.getId()));
try {
String contentType = response.getContentType();
if (contentType != null && contentType.contains("json")) {
msg.append(" Payload:").append(new String(response.toByteArray(), response.getCharacterEncoding()));
} else {
msg.append(" Content-Type:").append(contentType);
}
} catch (UnsupportedEncodingException e) {
logger.warn("Failed to parse response payload", e);
}
logger.info(msg.toString());
}
}
Thanks very much !!!
Related
I have this interface:
#FeignClient(name = "${test.feign.name}", url = "${test.feign.url}", configuration = TestConfiguration.class)
public interface TestFeignClient {
#GetMapping(value = "/users", produces = "application/json")
ResponseEntity<?> getAll();
}
And I want to track the log by creating this class CustomFeignLogger.
This CustomFeignLogger object should extends Slf4jLogger Object and override this method:
protected Response logAndRebufferResponse(String configKey,
Level logLevel,
Response response,
long elapsedTime)
throws IOException {
if (logger.isDebugEnabled()) {
return super.logAndRebufferResponse(configKey, logLevel, response, elapsedTime);
}
return response;
}
In the TestConfiguration class you need to inject new bean CustomFeignLogger
#AllArgsConstructor
public class TestConfiguration {
#Bean
public CustomFeignLogger feignLogger() {
return new CustomFeignLogger();
}
}
Then you need to override logAndRebufferResponse method tike this:
protected Response logAndRebufferResponse(String configKey, Logger.Level logLevel, Response response, long elapsedTime) throws IOException {
String responseBody = null;
String reason = response.reason() != null && logLevel.compareTo(Logger.Level.NONE) > 0 ? " " + response.reason() : "";
int status = response.status();
this.log(configKey, "<--- HTTP/1.1 %s%s (%sms)", status, reason, elapsedTime);
// ---------------- Logging headers ----------------
Iterator headersIterator = response.headers().keySet().iterator();
while(headersIterator.hasNext()) {
String field = (String) headersIterator.next();
Iterator valuesIterator = Util.valuesOrEmpty(response.headers(), field).iterator();
while(valuesIterator.hasNext()) {
String value = (String)valuesIterator.next();
this.log(configKey, "%s: %s", field, value);
}
}
// -------------------------------------------------
//----------------- Logging response body ---------------
int bodyLength = 0;
if (response.body() != null
&& status != HttpStatus.SC_NO_CONTENT
&& status != HttpStatus.SC_RESET_CONTENT) {
this.log(configKey, "");
byte[] bodyData = Util.toByteArray(response.body().asInputStream());
bodyLength = bodyData.length;
if (bodyLength > 0) {
String body = Util.decodeOrDefault(bodyData, Util.UTF_8, "Binary data");
responseBody = body.toString();
this.log(configKey, "%s", body);
}
this.log(configKey, "<--- END HTTP ttttt (%s-byte body)", bodyLength);
// trackingService.track
return response.toBuilder().body(bodyData).build();
}
this.log(configKey, "<--- END HTTP tttt (%s-byte body)", Integer.valueOf(bodyLength));
// -------------------------------------------------
return response;
}
I'm doing a private api in java, jwt, spring security and the first time come in the request a json object.
user: xxx
password: yyy
The api return a jwt token in the body.
The others call the token come in the body json and to validate it I use this:
sbody = servletRequest.getReader().lines().collect(Collectors.joining());
To get the field token and it get ok, but then of the filter it show the message:
"Required request body is missing: public org.springframework.http.ResponseEntity"
This is my api:
#SpringBootApplication
public class JwtApplication {
public static void main(String[] args) {
SpringApplication.run(JwtApplication.class, args);
}
#EnableWebSecurity
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.addFilterAfter(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests().antMatchers(HttpMethod.POST, "/user").permitAll()
.antMatchers(HttpMethod.POST, "/Autenticacion").permitAll().anyRequest().authenticated();
}
}
}
This is the filter:
public class JWTAuthorizationFilter extends OncePerRequestFilter {
private final String HEADER = "Authorization";
private final String SESSION = "sesion";
private final String PREFIX = "Bearer ";
private final String SECRET = "mySecretKey";
public static final long EXPIRATION_TIME = 900_000; // 15 mins
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
boolean resultado_checktoken = checkJWTToken(httpRequest, httpResponse);
if (resultado_checktoken) {
Claims claims = validateToken(request);
if (claims.get("authorities") != null) {
setUpSpringAuthentication(claims);
} else {
SecurityContextHolder.clearContext();
}
} else {
SecurityContextHolder.clearContext();
}
chain.doFilter(request, response);
} catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException e) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
return;
}
System.out.println("supuestamente no hubo problemas");
}
private Claims validateToken(HttpServletRequest request) {
//String jwtToken = request.getHeader(HEADER).replace(PREFIX, "");
String jwtToken="";
try {
jwtToken = this.getBodySession(request);
} catch (IOException e) {
e.printStackTrace();
};
return Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(jwtToken).getBody();
}
/**
* Authentication method in Spring flow
*
* #param claims
*/
private void setUpSpringAuthentication(Claims claims) {
#SuppressWarnings("unchecked")
List<String> authorities = (List<String>) claims.get("authorities");
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(claims.getSubject(), null,
authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
SecurityContextHolder.getContext().setAuthentication(auth);
}
private boolean checkJWTToken(HttpServletRequest request, HttpServletResponse res) throws IOException {
String authenticationHeader = "";
authenticationHeader = this.getBodySession(request);
if (authenticationHeader == null || !authenticationHeader.startsWith(PREFIX))
return false;
return true;
}
public String getBodySession(HttpServletRequest request) throws IOException {
String sbody = "";
HttpServletRequest servletRequest = new ContentCachingRequestWrapper(request);
//servletRequest.getParameterMap();
sbody = servletRequest.getReader().lines().collect(Collectors.joining());
String Field = SESSION;
String scampo = "";
if (sbody.contains(Field)) {
scampo = sbody.substring(sbody.indexOf(Field), sbody.indexOf("\n", sbody.indexOf(Field)))
.replace(Field + "\": \"", "").replace("\"", "").replace(",", "");
}
System.out.println("sbody: " + sbody + " sesion: " + scampo);
return scampo;
}
}
This needs to return a boolean explicitly you cannot have two return statements.
private boolean checkJWTToken(HttpServletRequest request, HttpServletResponse res) throws IOException {
String authenticationHeader = "";
authenticationHeader = this.getBodySession(request);
if (authenticationHeader == null || !authenticationHeader.startsWith(PREFIX))
**return false;**
**return true;**
}
I have HttpServletRequest req and HttpServletResponse res wont to use req and res variables in another place in code.
and I have another problem in if statement when I was pass function in compression
here my code
#WebServlet(name = "NaiveBayesExample", urlPatterns = {"/NaiveBayesExample"})
public class NaiveBayesExample extends HttpServlet {
String param="";
public static String[] readLines(URL url) throws IOException {
Reader fileReader = new InputStreamReader(url.openStream(), Charset.forName("UTF-8"));
List<String> lines;
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
lines = new ArrayList<>();
String line;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
}
return lines.toArray(new String[lines.size()]);
}
public void doPost(HttpServletRequest req,HttpServletResponse res) throws IOException
{
res.setContentType("text/html");
PrintWriter pw = res.getWriter();
param =req.getParameter("a");
pw.print("<br> <font color=blue size=5>POST METHOD</font>");
pw.print("Param is "+ param);
}
protected void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException
{
res.setContentType("text/html");
PrintWriter pw = res.getWriter();
param =req.getParameter("a");
pw.print("Param is "+ param);
}
public void handleRequest(HttpServletRequest req, HttpServletResponse res) throws IOException {
PrintWriter out = res.getWriter();
res.setContentType("text/plain");
String paramName = "param name";
String paramValue = req.getParameter(paramName);
out.write(paramName + " = ");
out.write(paramValue);
paramName = "UNKNOWN";
paramValue = req.getParameter(paramName);
if (paramValue==null) {
out.write("Parameter " + paramName + " not found");
}
out.close();
}
public static void main(String[] args) throws IOException {
//map of dataset files
Map<String, URL> trainingFiles = new HashMap<>();
trainingFiles.put("Paaass Request", NaiveBayesExample.class.getResource("/datasets/training.normaltraffic.nt.txt"));
trainingFiles.put("Sql Injectionnn Request", NaiveBayesExample.class.getResource("/datasets/training.sqlinjection.si.txt"));
//loading examples in memory
Map<String, String[]> trainingExamples = new HashMap<>();
for(Map.Entry<String, URL> entry : trainingFiles.entrySet()) {
trainingExamples.put(entry.getKey(), readLines(entry.getValue()));
}
//train classifier
NaiveBayes nb = new NaiveBayes();
nb.setChisquareCriticalValue(6.63); //0.01 pvalue
nb.train(trainingExamples);
//get trained classifier knowledgeBase
NaiveBayesKnowledgeBase knowledgeBase = nb.getKnowledgeBase();
nb = null;
trainingExamples = null;
//Use classifier
nb = new NaiveBayes(knowledgeBase);
// String PassTraffic = "http://www.testsite.com/catigories/index.php=1";
String output = nb.predict(req.getParameter("a"));
if (output!=trainingFiles.put("Pass", NaiveBayesExample.class.getResource("/datasets/training.normaltraffic.nt.txt")))
{
res.sendRedirect("SecondServlet");
}
else
{
}
// System.out.format("The Traffic \"%s\" was classified as \"%s\".%n", PassTraffic, outputpass);
//
String output2 = nb.predict(req.getParameter("a"));
if (output2!=trainingFiles.put("stop", NaiveBayesExample.class.getResource("/datasets/training.sqlinjection.si.txt")))
{
res.sendRedirect("SecondServlet");
}
else
{
} }
}
in if statement compiler said incomparable type: String and URL and res and req not accessible to get parameters
DonĀ“t compare strings with == or != only with the equals function.
And you must caste the URL to a string, after that you can only compare this two.
For example
if (output.equals(trainingFiles.put("Pass", NaiveBayesExample.class.getResource("/datasets/training.normaltraffic.nt.txt")).toString())) {
res.sendRedirect("SecondServlet");
}
I'm trying to develop my own CSRF filter in Spring MVC 3 (There are some extra trainings that made me do that, thats why Im not considering spring security.)
My filter works fine with all forms except those that have enctype="multipart/form-data". So I can not get request parameters from normal HttpServletRequest.
I've tried casting HttpServletRequest to MultipartHttpServletRequest but I found out I can not do that either.
My objective is not getting files from the request, but to only get simple form input named csrf. (Ive already uploaded files with my forms)
Here is my code till now:
CSRFilter
public class CSRFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
CSRF csrf = new CSRF(req);
if(csrf.isOk()){
chain.doFilter(req, res);
}else {
//todo : Show Error Page
String redirect = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/access-forbidden";
response.sendRedirect(redirect);
}
}
}
CSRF
public class CSRF {
HttpServletRequest request;
ServletRequest req;
String token;
boolean ok;
private static final Logger logger = Logger.getLogger(CSRF.class);
public CSRF(ServletRequest request) {
this.request = (HttpServletRequest) request;
this.req = request;
init();
}
public CSRF() {
}
public void setRequest(HttpServletRequest request) {
this.request = (HttpServletRequest) request;
this.req = request;
init();
}
private void init() {
if (request.getMethod().equals("GET")) {
generateToken();
addCSRFTokenToSession();
addCSRFTokenToModelAttribute();
ok = true;
} else if (request.getMethod().equals("POST")) {
if (checkPostedCsrfToken()) {
ok = true;
}
}
}
private void generateToken() {
String token;
java.util.Date date = new java.util.Date();
UUID uuid = UUID.randomUUID();
token = uuid.toString() + String.valueOf(new Timestamp(date.getTime()));
try {
this.token = sha1(token);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
this.token = token;
}
}
private void addCSRFTokenToSession() {
request.getSession().setAttribute("csrf", token);
}
private void addCSRFTokenToModelAttribute() {
request.setAttribute("csrf", token);
}
private boolean checkPostedCsrfToken() {
System.out.println("____ CSRF CHECK POST _____");
if (request.getParameterMap().containsKey("csrf")) {
String csrf = request.getParameter("csrf");
if (csrf.equals(request.getSession().getAttribute("csrf"))) {
return true;
}
}else {
//Check for multipart requests
MultipartHttpServletRequest multiPartRequest = new DefaultMultipartHttpServletRequest((HttpServletRequest) req);
if (multiPartRequest.getParameterMap().containsKey("csrf")) {
String csrf = multiPartRequest.getParameter("csrf");
if (csrf.equals(request.getSession().getAttribute("csrf"))) {
return true;
}
}
}
log();
return false;
}
private void log() {
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
if(username==null){
username = "unknown (not logged in)";
}
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
String userAgent = request.getHeader("User-Agent");
String address = request.getRequestURI();
System.out.println("a CSRF attack detected from IP: " + ipAddress + " in address \"" + address + "\" - Client User Agent : " + userAgent + " Username: " + username);
logger.error("a CSRF attack detected from IP: " + ipAddress + " in address \"" + address + "\" - Client User Agent : " + userAgent + " Username: " + username);
}
public boolean isOk() {
return ok;
}
static String sha1(String input) throws NoSuchAlgorithmException {
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
}
I have this line in my dispatcher too :
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="40000000"/>
</bean>
and also I use springMultipartResolver filter ...
<filter>
<display-name>springMultipartFilter</display-name>
<filter-name>springMultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springMultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</filter>
I get java.lang.IllegalStateException: Multipart request not initialized Exception when I try it on multipart/form-data forms.
I looked at many Examples in internet. Most of them was for file uploading purpose and could not help me, I also tried different ways to cast HttpServletRequest to any other object that gives me resolved multipart request, But I could not succeed.
How can I do it ?
Thanks.
You can not cast HttpServletRequest to MultipartHttpServletRequest, because you first have to resolve your request.
I used CommonsMultipartResolver Class and got MultipartHttpServletRequest using commonsMultipartResolver.resolveMultipart(request) method (where request is type of HttpServletRequest)
So, here is my CSRF class, checkPostedCsrfToken() method:
private boolean checkPostedCsrfToken() {
if (request.getParameterMap().containsKey("csrf")) {
String csrf = request.getParameter("csrf");
if (csrf.equals(request.getSession().getAttribute("csrf"))) {
return true;
}
} else if (request.getContentType() != null && request.getContentType().toLowerCase().contains("multipart/form-data")) {
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
MultipartHttpServletRequest multipartRequest = commonsMultipartResolver.resolveMultipart(request);
if (multipartRequest.getParameterMap().containsKey("csrf")) {
String csrf = multipartRequest.getParameter("csrf");
if (csrf.equals(request.getSession().getAttribute("csrf"))) {
return true;
}
}
}
log();
return false;
}
But, Note that you will end up loosing all request parameters and data with this approach. So you have to extend HttpServletRequestWrapper class to read request bytes and use them to get parameters if it matters to you that parameters don't get lost throw filter chain. In other words, you need a clone of your request.
Here is a good helper class I found in StackOverflow, (I cant find the question again, I will edit this if I find it).
MultiReadHttpServletRequest
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedBytes;
public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
}
#Override
public ServletInputStream getInputStream() throws IOException {
if (cachedBytes == null)
cacheInputStream();
return new CachedServletInputStream();
}
#Override
public BufferedReader getReader() throws IOException{
return new BufferedReader(new InputStreamReader(getInputStream()));
}
private void cacheInputStream() throws IOException {
/* Cache the inputstream in order to read it multiple times. For
* convenience, I use apache.commons IOUtils
*/
cachedBytes = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cachedBytes);
}
/* An inputstream which reads the cached request body */
public class CachedServletInputStream extends ServletInputStream {
private ByteArrayInputStream input;
public CachedServletInputStream() {
/* create a new input stream from the cached request body */
input = new ByteArrayInputStream(cachedBytes.toByteArray());
}
#Override
public int read() throws IOException {
return input.read();
}
}
}
now all you need to do is to use MultiReadHttpServletRequest instead of normal HttpServletRequest in filter :
public class CSRFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// The important part!! wrap the request:
MultiReadHttpServletRequest multiReadHttpServletRequest = new MultiReadHttpServletRequest(request);
CSRF csrf = new CSRF(multiReadHttpServletRequest);
if(csrf.isOk()){
chain.doFilter(multiReadHttpServletRequest, res);
}else {
//todo : Show Error Page
String redirect = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/access-forbidden";
response.sendRedirect(redirect);
}
}
}
I wish this helps someone :)
I needed to be able to inspect the Request's body without damaging it for the Servlet or subsequent Filters, so I created a mini-project that does just that.
The jar is < 10kb, and if you're using Tomcat then you don't need anything beyond that. Also, it's MIT licensed so you can use it in whatever project you may need.
You can find the project at https://github.com/isapir/servlet-filter-utils
All you have to do is wrap the incoming Request with RereadableServletRequest, e.g.
HttpServletRequest requestWrapper = new RereadableServletRequest(servletRequest);
I am trying to create a app for fitbit using fitbit4j . I found their sample code
at
https://github.com/apakulov/fitbit4j/blob/master/fitbit4j-example-client/src/main/java/com/fitbit/web/FitbitApiAuthExampleServlet.java
When i tried to implement it I am getting many errors.
below is their doGet function()
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
FitbitAPIClientService<FitbitApiClientAgent> apiClientService = new FitbitAPIClientService<FitbitApiClientAgent>(
new FitbitApiClientAgent(apiBaseUrl, fitbitSiteBaseUrl, credentialsCache),
clientConsumerKey,
clientSecret,
credentialsCache,
entityCache,
subscriptionStore
);
if (request.getParameter("completeAuthorization") != null) {
String tempTokenReceived = request.getParameter(OAUTH_TOKEN);
String tempTokenVerifier = request.getParameter(OAUTH_VERIFIER);
APIResourceCredentials resourceCredentials = apiClientService.getResourceCredentialsByTempToken(tempTokenReceived);
if (resourceCredentials == null) {
throw new ServletException("Unrecognized temporary token when attempting to complete authorization: " + tempTokenReceived);
}
// Get token credentials only if necessary:
if (!resourceCredentials.isAuthorized()) {
// The verifier is required in the request to get token credentials:
resourceCredentials.setTempTokenVerifier(tempTokenVerifier);
try {
// Get token credentials for user:
apiClientService.getTokenCredentials(new LocalUserDetail(resourceCredentials.getLocalUserId()));
} catch (FitbitAPIException e) {
throw new ServletException("Unable to finish authorization with Fitbit.", e);
}
}
try {
UserInfo userInfo = apiClientService.getClient().getUserInfo(new LocalUserDetail(resourceCredentials.getLocalUserId()));
request.setAttribute("userInfo", userInfo);
request.getRequestDispatcher("/fitbitApiAuthExample.jsp").forward(request, response);
} catch (FitbitAPIException e) {
throw new ServletException("Exception during getting user info", e);
}
} else {
try {
response.sendRedirect(apiClientService.getResourceOwnerAuthorizationURL(new LocalUserDetail("-"), exampleBaseUrl + "/fitbitApiAuthExample?completeAuthorization="));
} catch (FitbitAPIException e) {
throw new ServletException("Exception during performing authorization", e);
}
}
}
When i run the code it goes into the 'else' part first and i get the URL with
localhost:8080/fitbitApiAuthExample?completeAuthorization=&oauth_token=5bccadXXXXXXXXXXXXXXXXXXXXXXXXXX&oauth_verifier=h35kXXXXXXXXXXXXXXXXX, and i get the fitbit login screen and when i log in
and since the
'completeAuthorization==null',
it is executing the else part again.So i manually added a value so that it will enter the 'if' section .
So the new URL became
localhost:8080/fitbitApiAuthExample?completeAuthorization=Success&oauth_token=5bccadXXXXXXXXXXXXXXXXXXXXXXXXXX&oauth_verifier=h35kXXXXXXXXXXXXXXXXX and entered the 'if' section.
Now am getting the exception
'Unrecognized temporary token when attempting to complete authorization:'I tried many workarounds but still cant understand the error.
Please Help.
Solved the problem. the 'apiClientService' was going null when i reload the servlet. Made it member variable and everything started working.
public class NewServlet extends HttpServlet {
public String apiBaseUrl = "api.fitbit.com";
public String webBaseUrl = "https://www.fitbit.com";
public String consumerKey = "your key";
public String consumerSecret = "your secret";
public String callbackUrl = "*****/run?Controller=Verifier";
public FitbitAPIClientService<FitbitApiClientAgent> apiClientService = null;
public String oauth_token = null;
public String oauth_verifier = null;
public String token = null;
public String tokenSecret = null;
public String userId = null;
public APIResourceCredentials resourceCredentials=null;
public FitbitApiClientAgent agent =null;
public LocalUserDetail user=null;
public Gson gson =null;
public UserInfo userInfo=null;
private static Properties getParameters(String url) {
Properties params = new Properties();
String query_string = url.substring(url.indexOf('?') + 1);
String[] pairs = query_string.split("&");
for (String pair : pairs) {
String[] kv = pair.split("=");
params.setProperty(kv[0], kv[1]);
}
return params;
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, ParserConfigurationException, SAXException, Exception {
PrintWriter out = response.getWriter();
response.addHeader("Access-Control-Allow-Origin", "*");
// out.println(" ----- process Request Called-----");
String controllerValue = request.getParameter("Controller");
// out.println(" Controller Request : "+param);
if (controllerValue == null) {
// out.println(" inside if part ");
FitbitAPIEntityCache entityCache = new FitbitApiEntityCacheMapImpl();
FitbitApiCredentialsCache credentialsCache = new FitbitApiCredentialsCacheMapImpl();
FitbitApiSubscriptionStorage subscriptionStore = new FitbitApiSubscriptionStorageInMemoryImpl();
FitbitApiClientAgent apiClientAgent = new FitbitApiClientAgent(apiBaseUrl, webBaseUrl, credentialsCache);
out.println("testing2");
apiClientService
= new FitbitAPIClientService<FitbitApiClientAgent>(
apiClientAgent,
consumerKey,
consumerSecret,
credentialsCache,
entityCache,
subscriptionStore
);
// out.println("<script>localStorage.setItem('api',apiClientService);</script>");
LocalUserDetail userDetail = new LocalUserDetail("-");
try {
// out.println("testing4");
String authorizationURL = apiClientService.getResourceOwnerAuthorizationURL(userDetail, callbackUrl);
out.println("access by web browser: " + authorizationURL);
out.println("Your web browser shows redirected URL.");
out.println("Input the redirected URL and push Enter key.");
response.sendRedirect(authorizationURL);
} catch (FitbitAPIException ex) {
out.println("exception : " + ex);
//Logger.getLogger(NewServlet.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (controllerValue.equalsIgnoreCase("Verifier")) {
oauth_token = request.getParameter("oauth_token");
oauth_verifier = request.getParameter("oauth_verifier");
resourceCredentials = apiClientService.getResourceCredentialsByTempToken(oauth_token);
if (resourceCredentials == null) {
out.println(" resourceCredentials = null ");
throw new Exception("Unrecognized temporary token when attempting to complete authorization: " + oauth_token);
}
if (!resourceCredentials.isAuthorized()) {
resourceCredentials.setTempTokenVerifier(oauth_verifier);
apiClientService.getTokenCredentials(new LocalUserDetail(resourceCredentials.getLocalUserId()));
}
userId = resourceCredentials.getLocalUserId();
token = resourceCredentials.getAccessToken();
tokenSecret = resourceCredentials.getAccessTokenSecret();
user = new LocalUserDetail(userId);
userInfo = apiClientService.getClient().getUserInfo(new LocalUserDetail(resourceCredentials.getLocalUserId()));
user = new LocalUserDetail(userId);
agent = apiClientService.getClient();
response.sendRedirect("http://localhost:8084/FitbitClientCheck/");
}