Apache CFX基本身份验证HP质量中心

Apache CFX基本身份验证HP质量中心,apache,authentication,cookies,reset,basic-authentication,Apache,Authentication,Cookies,Reset,Basic Authentication,我正在使用ApacheCfx为HP质量中心编写一个REST连接器。我想使用CFX基础设施在向服务器发出请求时进行抢占式身份验证 HP Quality Center使用基于Basic的身份验证机制。要进行身份验证,将向发送get请求http:///qcbin/authentication-point/authenticate 具有标准的基本身份验证标头。然后,服务器返回一个cookie(“LWSSO”),该cookie必须包含在所有后续请求中。在进行身份验证之前从服务器请求资源将导致401 wit

我正在使用ApacheCfx为HP质量中心编写一个REST连接器。我想使用CFX基础设施在向服务器发出请求时进行抢占式身份验证

HP Quality Center使用基于Basic的身份验证机制。要进行身份验证,将向发送get请求http:///qcbin/authentication-point/authenticate 具有标准的基本身份验证标头。然后,服务器返回一个cookie(“LWSSO”),该cookie必须包含在所有后续请求中。在进行身份验证之前从服务器请求资源将导致401 with WWW Authenticate标头,其中包含身份验证点URI(例如LWSO realm=“http://:80/qcbin/authentication point)

理想情况下,我希望创建一个CFX HttpAuthProvider或拦截器,它通过拦截401响应、解析出WWW Authenticate头并在验证点URI上执行请求来处理身份验证,然后缓存cookie以用于所有后续请求

这将允许我使用工厂模式创建干净的基于代理的API。例如:

public QualityCenter create(String url, String username, String password) {
    JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
    bean.setAddress(url);
    bean.setUsername(username);
    bean.setPassword(password);
    bean.setServiceClass(QualityCenter.class);      

       // TODO: Setup authentication modules here that use AuthPolicy for credentials.

    return bean.create(QualityCenter.class);
}

我似乎不知道这是否可能,以及在哪里最好地实现功能。

我最终解决了这个问题,没有使用Apache CXF,而是选择了Jersey

为此,我创建了两个JAXRS过滤器。第一个过滤器截获来自服务器的401个响应,遵循“WWW Authenticate”头中返回的身份验证点地址,并执行基本身份验证。然后将原始请求重放到服务器

这个等式的第二部分是另一个过滤器,它负责维护会话cookie。因此,当重放初始请求时,身份验证cookie就存在了

这两个过滤器如下所示:

class AuthenticationFilter implements ClientResponseFilter {

private final String username;
private final String password;

public AuthenticationFilter(String username, String password) {
    this.username = username;
    this.password = password;
}

@Override
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
    if (responseContext.getStatus() == Response.Status.UNAUTHORIZED.getStatusCode()) {
        String header = responseContext.getHeaders().getFirst(WWW_AUTHENTICATE);

        // Check if we have been given the authentication redirect go-ahead.
        if (!header.startsWith("LWSSO")) {
            return;
        }

        String authUri = header.substring(13, header.length() - 1);
        Client client = ClientBuilder.newClient(requestContext.getConfiguration());
        String credentials = "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
        Response response = client.target(authUri).path("authenticate").request(MediaType.TEXT_PLAIN_TYPE).header(AUTHORIZATION, credentials).get();
        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            URI uri = requestContext.getUri();
            MediaType mediaType = requestContext.getMediaType();
            String method = requestContext.getMethod();
            NewCookie cookie = response.getCookies().get("LWSSO_COOKIE_KEY");
            MultivaluedMap<String, Object> headers = requestContext.getHeaders();
            headers.remove(WWW_AUTHENTICATE);
            Invocation.Builder builder = requestContext.getClient().target(uri).request(mediaType).headers(headers).cookie(cookie);

            Invocation invocation;
            if (requestContext.getEntity() != null) {
                invocation = builder.build(method, Entity.entity(
                        requestContext.getEntity(), mediaType));
            } else {
                invocation = builder.build(method);
            }

            Response replayed = invocation.invoke();
            responseContext.setStatus(replayed.getStatus());
            responseContext.setStatusInfo(replayed.getStatusInfo());
            if (replayed.hasEntity()) {
                responseContext.setEntityStream(replayed
                        .readEntity(InputStream.class));
            }
            responseContext.getHeaders().clear();
            responseContext.getHeaders()
                    .putAll(replayed.getStringHeaders());
        }
    }
}}


class SessionFilter implements ClientRequestFilter, ClientResponseFilter {

    private final Map<String, NewCookie> cookies = new HashMap<String, NewCookie>();

    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        cookies.putAll(responseContext.getCookies());
    }

    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        for(NewCookie cookie: cookies.values()) {
            requestContext.getHeaders().add("Cookie", cookie);          
        }
    }

}
class AuthenticationFilter实现ClientResponseFilter{
私有最终字符串用户名;
私有最终字符串密码;
公共身份验证筛选器(字符串用户名、字符串密码){
this.username=用户名;
this.password=密码;
}
@凌驾
公共无效筛选器(ClientRequestContext requestContext、ClientResponseContext responseContext responseContext)引发IOException{
if(responseContext.getStatus()==Response.Status.UNAUTHORIZED.getStatusCode()){
字符串头=responseContext.getHeaders().getFirst(WWW\u AUTHENTICATE);
//检查我们是否已获得身份验证重定向,然后继续。
如果(!header.startsWith(“LWSSO”)){
返回;
}
字符串authUri=header.substring(13,header.length()-1);
Client Client=ClientBuilder.newClient(requestContext.getConfiguration());
String credentials=“Basic”+Base64.getEncoder().encodeToString((用户名+”:“+密码).getBytes());
Response Response=client.target(authUri).path(“authenticate”).request(MediaType.TEXT\u PLAIN\u TYPE).header(AUTHORIZATION,credentials.get();
if(response.getStatus()==response.Status.OK.getStatusCode()){
URI=requestContext.getUri();
MediaType MediaType=requestContext.getMediaType();
String方法=requestContext.getMethod();
NewCookie cookie=response.getCookies().get(“LWSSO\u cookie\u KEY”);
多值Map headers=requestContext.getHeaders();
删除(WWW_-AUTHENTICATE);
Invocation.Builder=requestContext.getClient().target(uri).request(mediaType).headers(headers).cookie(cookie);
调用调用;
if(requestContext.getEntity()!=null){
调用=builder.build(方法,Entity.Entity(
requestContext.getEntity(),mediaType));
}否则{
调用=builder.build(方法);
}
Response replayed=invocation.invoke();
responseContext.setStatus(replayed.getStatus());
responseContext.setStatusInfo(replayed.getStatusInfo());
if(replayed.haseEntity()){
responseContext.setEntityStream(重播)
.readEntity(InputStream.class));
}
responseContext.getHeaders().clear();
responseContext.getHeaders()
.putAll(replayed.getStringHeaders());
}
}
}}
类SessionFilter实现ClientRequestFilter、ClientResponseFilter{
私有最终映射cookies=newhashmap();
@凌驾
公共无效筛选器(ClientRequestContext requestContext、ClientResponseContext responseContext responseContext)引发IOException{
cookies.putAll(responseContext.getCookies());
}
@凌驾
公共无效筛选器(ClientRequestContext requestContext)引发IOException{
for(NewCookie:cookies.values()){
requestContext.getHeaders().add(“Cookie”,Cookie);
}
}
}