gpt4 book ai didi

java - 使用经过身份验证的 session 的 Jersey 客户端

转载 作者:太空宇宙 更新时间:2023-11-04 13:37:31 24 4
gpt4 key购买 nike

在给定时刻创建经过身份验证的 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com