- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在给定时刻创建经过身份验证的 session 。
我需要使用该经过身份验证的 session 创建一个 Jersey 客户端(post 方法)。
我尝试在 Jersey 客户端中设置 JSESSIONID,但它无法识别 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);
我还尝试了下面的代码,在 Jersey 客户端中,我首先调用一个 API 来验证 session ,然后尝试使用相同的客户端对象调用另一个需要身份验证 session 的 API,但不起作用。
Client client = Client.create();
final String url = "http://localhost:8080/api/auth";
WebResource wr = client.resource(url);
//set parametes for 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);
我怎样才能做到这一点?我的意思是,如何在新泽西客户端连接中使用经过身份验证的 JSESSIONID?
问候。
最佳答案
我认为最好的方法是使用 JWT 进行用户授权。
我假设您已经通过 API 端点对用户进行了身份验证。用户通过身份验证后,您可以回复 header 元素。您可以阅读有关智威汤逊的更多信息 @ https://jwt.io/introduction/
您的实现应类似于以下步骤。
1) 对用户进行身份验证,身份验证成功后,将“Authorization:” token 添加到响应中。
2) 在每个 API 调用中,期望用户在每个请求中传递 Authorization header 并使用 Filter通过解析 JWT Token 来授权用户。您可能想要 @Inject 解析器并确保您的解析器是线程安全的。
3-a) 如果 JWT token 有效,您可以让请求传递到您的资源。
3-b) 如果 JWT token 无效,您将使用 HTTP 401 进行回复。
这是一个示例实现。
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 for {}", 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 to parse JWT Token {}, reason {}", requestContext.getUriInfo().getPath(), parseException.getMessage());
throw new WebApplicationException("Unable to parse JWT Token", Response.Status.UNAUTHORIZED);
}
// Check if JWT has been init successfully.
if (jwt == null) {
LOGGER.error("JWT is null {}", requestContext.getUriInfo().getPath());
throw new WebApplicationException("Unable to 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 {
// Do nothing, continue as usual.
}
} catch (ParseException e) {
LOGGER.error("Authorization failed @ {} , due to {}", requestContext.getUriInfo().getPath(), e.getMessage());
throw new WebApplicationException("Unable to 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 to {}", requestContext.getUriInfo().getPath(), e.getMessage());
throw new WebApplicationException("Unable to Authorize " + e.getMessage(), Response.Status.UNAUTHORIZED);
} catch (BadJOSEException e) {
LOGGER.error("Authorization failed @ BadJOSEException {} , due to {}", requestContext.getUriInfo().getPath(), e.getMessage());
throw new WebApplicationException("Unable to Authorize " + e.getMessage(), Response.Status.UNAUTHORIZED);
} catch (JOSEException e) {
LOGGER.error("Authorization failed @ JOSEException {} , due to {}", requestContext.getUriInfo().getPath(), e.getMessage());
throw new WebApplicationException("Unable to Authorize " + e.getMessage(), Response.Status.UNAUTHORIZED);
}
// This should not have happened.
if (claimsSet == null) {
LOGGER.error("JWT Claim is null failed @ {} , due to {}", requestContext.getUriInfo().getPath());
throw new WebApplicationException("Unable to Authorize", Response.Status.UNAUTHORIZED);
}
} else {
LOGGER.error("Authorization header is missing {}", requestContext.getUriInfo().getPath());
throw new WebApplicationException("Authorization header is missing", Response.Status.UNAUTHORIZED);
}
}
}
我实际上创建了一个注释@Secured
,任何使用@Secured
注释的资源方法都将首先受到此过滤器的欢迎。
这是我的注释:
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 { }
然后我创建了一个 DynamicFeature:
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("{} is annotated to be a secure method " , resourceInfo.getResourceMethod().getName() );
context.register(CustomAuthorizationFilter.class);
}
}
}
您需要将 Jersey 中的上述 DyamicFeature 注册为
register(SimpleAuthorizationFilter.class)
最后,这是我用来测试的资源
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();
}
}
希望有帮助。
关于java - 使用经过身份验证的 session 的 Jersey 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31566512/
我已阅读 Jersey documentation ,并表示 Jersey 在读取实体后自动关闭连接(例如 response.readEntity(SomeObject.class)) 但是当抛出异常
Jersey vs Jersey (Standalone) vs Jersey with Grizzly vs Jersey with Tomcat - for REST services 有什么区别
如何通过 guice 使用非 Jersey 资源和 Jersey 资源? 我希望“/”由普通 servlet 处理。但我希望 Jersey 处理“/users”。 假设我有一个带@Path("/use
我正在尝试使用 Maven、Apache Tomcat 7.0、Eclipse IDE 创建一个基本的 RESTful 应用程序。我在 google 提供的一些示例代码中遇到了 jersey-serv
我已经从 Jersey 1.7 升级到 2.16,但 Jersey 似乎无法找到我的资源(请参阅下面的堆栈)。任何想法发生了什么?我尝试在扩展 ResourceConfig 的自定义应用程序类中初始化
我正在使用 com.yammer.dropwizard.config.Environment addProvider 方法在 Jersey 中注册提供程序。我也有一个自定义提供程序,它执行类似于 Dr
在 Jersey 1.x 中,您可以使用 ContainerRequest.getFormParameters()对表单数据进行请求过滤,但我在 Jersey 2.x 中看不到明显的等价物。我已经实现
我正在使用Jersey的集成Jackson处理将传入的JSON转换为POJO,例如: @POST @Consumes(MediaType.APPLICATION_JSON) public Respon
我正在尝试以编程方式创建 Jersey 资源(没有注释)。我有一个将 Name 和 id 作为输入参数的方法 raiseAlarm。我想从 JSON 输入中获取名称,并且我希望 id 来自路径参数。代
Dropwizard official documentation Jersey 客户端不可测试,有人有 dropwizard Jersey 客户端样本吗? 最佳答案 我发现在 Dropwizard
我一直在寻找解决这个问题的方法,但没有成功。我发现的最新帖子可以追溯到 2010 年。我正在使用带有嵌入式 grizzly 2.2.1 的 Jersey 1.12。 如果我理解正确,除非我将 Jers
我想开发一个 Web API,它将生成和使用 JSON 和 XML 数据。 我已经使用JAXB来支持XML,并且工作正常。现在我想添加 JSON 类型。我研究了不同的教程,所有教程都使用不同的依赖项,
如此处所述:http://wikis.sun.com/display/Jersey/WADL 我在 Tomcat 6 中使用 Jersey 1.4。 我已经尝试了所有可能的带有“/applicatio
我是jax-rs的新手,并且已经用jersey和glassfish构建了Web服务。 我需要的是一种方法,服务启动后即被称为。在这种方法中,我想加载自定义配置文件,设置一些属性,编写日志等等。 我尝试
当客户端请求 Not Acceptable MIME 类型时,如何防止 Jersey 在客户端发送 HTML 页面?我想使用 ExceptionMapper,但我不确定要捕获什么异常,或者这是否是处理
我试图在它的 JSON 被解码后拦截一个资源调用。通过阅读一些论坛和帖子,我发现我可以通过实现 来做到这一点。 org.glassfish.jersey.server.spi.internal.Res
我的 webapp 包含一个库,其中包含一个用 @javax.ws.rs.ext.Provider 注释的类。 .如果存在此类,我的 web 应用程序(在 EAR 中部署为 WAR)将无法启动并显示以
我想自定义404响应,即服务器(不是我)在找不到请求的资源时抛出(或自己抛出一个自定义的WebApplicationException,如果可以测试一个应用程序中是否存在请求的资源)?资源列表存储在某
我有一个受 Shibboleth(SSO 实现)保护的 Jersey API。 Shibboleth 将登录用户的 ID 放入请求属性中。在后端,我使用 Shiro 进行授权。 Shiro 希望了解登
我目前正在使用 Jersey 返回 JSON。我该如何返回 JSONP?例如我当前的RESTful方法是: @GET @Produces(MediaType.APPLICATION_JSON) pub
我是一名优秀的程序员,十分优秀!