java - Jersey client using an authenticated session -


in given moment in time authenticated session created.

i need create jersey client (post method) using authenticated session.

i've tried set jsessionid in jersey client doesn't recognize session.

    client client = client.create();      final string url = "http://localhost:8080/api/send";      webresource wr = client.resource(url);      javax.ws.rs.core.cookie cookie=new javax.ws.rs.core.cookie("jsessionid", "521448844j5we54d");     wr.cookie(cookie);      // set post parameters     formdatamultipart multipart = new formdatamultipart();     formdatabodypart fdp = new formdatabodypart("file", uploadedinputstream, mediatype.multipart_form_data_type);     multipart.bodypart(fdp);      string response = wr.type(mediatype.multipart_form_data_type).post(string.class, multipart);      system.out.println(response); 

i've tried code below, in jersey client call first api authenticate session , try use same client object call api require auth session, didn't work.

    client client = client.create();      final string url = "http://localhost:8080/api/auth";      webresource wr = client.resource(url);       //set parametes request     multivaluedmap<string, string> queryparams = new multivaluedmapimpl();     queryparams.add("user", "admin");     queryparams.add("pass", "123456");     wr.queryparams(queryparams);      clientresponse response = wr.type(mediatype.multipart_form_data_type).post(clientresponse.class);      system.out.println(response.getcookies().tostring());      //------------------------------------------------------------      final string url2 = "http://localhost:8080/api/send";      webresource wr2 = client.resource(url2);      // set post parameters     formdatamultipart multipart = new formdatamultipart();      formdatabodypart fdp = new formdatabodypart("file", uploadedinputstream, mediatype.multipart_form_data_type);     multipart.bodypart(fdp);      string response2 = wr2.type(mediatype.multipart_form_data_type).post(string.class, multipart);      system.out.println(response2); 

how can ? mean, how use authenticated jsessionid in new jersey client connection ?

regards.

i think best way use jwt user authorization.

i assuming have authenticated user via api endpoint. once user authenticated, can reply header element. can read more jwt @ https://jwt.io/introduction/

your implementation should following steps.

1) authenticate user , upon successful authentication, add "authorization: " token response.

2) in every api call, expect user pass authorization header each request , use filter authorize user parsing jwt token. may want @inject parser , make sure parser threadsafe.

3-a) if jwt token valid, let request pass through resource.

3-b) if jwt token invalid, reply wit http 401.

here sample implementation.

import com.google.inject.inject; import com.nimbusds.jose.joseexception; import com.nimbusds.jose.proc.badjoseexception; import com.nimbusds.jose.proc.securitycontext; import com.nimbusds.jwt.jwt; import com.nimbusds.jwt.jwtclaimsset; import com.nimbusds.jwt.jwtparser; import com.nimbusds.jwt.proc.configurablejwtprocessor; import org.slf4j.logger; import org.slf4j.loggerfactory;  import javax.annotation.priority; import javax.ws.rs.priorities; import javax.ws.rs.webapplicationexception; import javax.ws.rs.container.containerrequestcontext; import javax.ws.rs.container.containerrequestfilter; import javax.ws.rs.container.prematching; import javax.ws.rs.core.multivaluedmap; import javax.ws.rs.core.response; import javax.ws.rs.ext.provider; import java.io.ioexception; import java.text.parseexception;   @prematching @priority(priorities.authentication) @provider @secured public class simpleauthorizationfilter implements containerrequestfilter {   static jwtparser jwtparser = null;   private static final logger logger = loggerfactory.getlogger(simpleauthorizationfilter.class);   @inject  private configurablejwtprocessor jwtprocessor;   public simpleauthorizationfilter() {   logger.debug("init {}", getclass().getname());  }   @override  public void filter(containerrequestcontext requestcontext) throws ioexception {    if (logger.isdebugenabled()) {    logger.debug("began authorization filter {}", requestcontext.geturiinfo().getpath());   }    multivaluedmap < string, string > headers = requestcontext.getheaders();    jwt jwt = null;    if (headers.containskey(accesstokens.authorization)) {     string accesstoken = headers.getfirst(accesstokens.authorization);      try {     jwt = jwtparser.parse(accesstoken);    } catch (parseexception parseexception) {     logger.error("unable parse jwt token {}, reason {}", requestcontext.geturiinfo().getpath(), parseexception.getmessage());     throw new webapplicationexception("unable parse jwt token", response.status.unauthorized);     }      // check if jwt has been init successfully.    if (jwt == null) {     logger.error("jwt null {}", requestcontext.geturiinfo().getpath());     throw new webapplicationexception("unable init jwt", response.status.unauthorized);    }      try {      if (jwt.getjwtclaimsset().getexpirationtime().before(new java.util.date())) {      logger.debug("jwt token expired on {}, requesting new token ", jwt.getjwtclaimsset().getexpirationtime().tostring());      } else {      // nothing, continue usual.     }     } catch (parseexception e) {     logger.error("authorization failed @ {} , due {}", requestcontext.geturiinfo().getpath(), e.getmessage());     throw new webapplicationexception("unable authorize " + e.getmessage(), response.status.unauthorized);    }      securitycontext ctx = null; // optional context parameter, not required here     jwtclaimsset claimsset = null;      try {     claimsset = jwtprocessor.process(accesstoken, ctx);    } catch (parseexception e) {     logger.error("authorization failed @ parseexception {} , due {}", requestcontext.geturiinfo().getpath(), e.getmessage());     throw new webapplicationexception("unable authorize " + e.getmessage(), response.status.unauthorized);    } catch (badjoseexception e) {     logger.error("authorization failed @ badjoseexception {} , due {}", requestcontext.geturiinfo().getpath(), e.getmessage());     throw new webapplicationexception("unable authorize " + e.getmessage(), response.status.unauthorized);    } catch (joseexception e) {     logger.error("authorization failed @ joseexception {} , due {}", requestcontext.geturiinfo().getpath(), e.getmessage());     throw new webapplicationexception("unable authorize " + e.getmessage(), response.status.unauthorized);    }      // should not have happened.    if (claimsset == null) {     logger.error("jwt claim null failed @ {} , due {}", requestcontext.geturiinfo().getpath());     throw new webapplicationexception("unable authorize", response.status.unauthorized);    }    } else {    logger.error("authorization header missing {}", requestcontext.geturiinfo().getpath());    throw new webapplicationexception("authorization header missing", response.status.unauthorized);   }    }  } 

i created annotation @secured , resource method annotated @secured greeted first filter.

here annotation:

import javax.ws.rs.namebinding; import java.lang.annotation.retention; import java.lang.annotation.target;  import static java.lang.annotation.elementtype.method; import static java.lang.annotation.elementtype.type; import static java.lang.annotation.retentionpolicy.runtime;  @namebinding @retention(runtime) @target({type, method}) public @interface secured { } 

then created dynamicfeature as:

import org.slf4j.logger; import org.slf4j.loggerfactory;  import javax.ws.rs.container.dynamicfeature; import javax.ws.rs.container.resourceinfo; import javax.ws.rs.core.featurecontext; import javax.ws.rs.ext.provider;  @provider public class resourcefilterbindingfeature implements dynamicfeature {      private static final logger logger = loggerfactory.getlogger(resourcefilterbindingfeature.class);      @override     public void configure(resourceinfo resourceinfo, featurecontext context) {         if (resourceinfo.getresourcemethod().isannotationpresent(secured.class)) {             logger.info("{} annotated secure method " , resourceinfo.getresourcemethod().getname() );             context.register(customauthorizationfilter.class);         }      } } 

you need register above dyamicfeature in jersey as

register(simpleauthorizationfilter.class) 

finally, here resource used test

import javax.annotation.security.rolesallowed; import javax.ws.rs.consumes; import javax.ws.rs.get; import javax.ws.rs.path; import javax.ws.rs.produces; import javax.ws.rs.core.mediatype; import javax.ws.rs.core.response;   @path("/authorizationtest") @consumes({mediatype.application_json}) @produces({mediatype.application_json}) public class authorizationtest {      @get     @path("/secure")     @secured     public response secure(){          return response.ok(mediatype.application_json).build();     }      @get     @path("/unsecure")     public response unsecure(){         return response.ok(mediatype.application_json).build();      }  } 

hope helps.


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -