使用Resteasy客户端进行基本身份验证

时间:2014-02-28 12:30:05

标签: basic-authentication resteasy

我正在尝试使用REST对我的jboss上运行的登录模块执行基本身份验证。我已经找到了StackOverflow主题,该主题解释了如何使用凭据进行身份验证。

RESTEasy client framework authentication credentials

这不起作用。分析与Wireshark建立的连接我无法看到带有Authorization:Basic的HTTP包。经过更多的研究后,我发现了这篇文章http://docs.jboss.org/resteasy/docs/2.3.3.Final/userguide/html/RESTEasy_Client_Framework.html,其中介绍了如何将基本身份验证附加到ApacheHttpClient4Executor重新出现。

// Configure HttpClient to authenticate preemptively
// by prepopulating the authentication data cache.

// 1. Create AuthCache instance
AuthCache authCache = new BasicAuthCache();

// 2. Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put("com.bluemonkeydiamond.sippycups", basicAuth);

// 3. Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);

// 4. Create client executor and proxy
httpClient = new DefaultHttpClient();
ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor(httpClient, localContext);
client = ProxyFactory.create(BookStoreService.class, url, executor);

但这也不起作用。没有描述如何将基本身份验证的用户名和密码附加到构造中。为什么该信息与httpcomponent中的任何类无关?

4 个答案:

答案 0 :(得分:12)

可以使用与resteasy-client 3.x一起打包的org.jboss.resteasy.client.jaxrs.BasicAuthentication,专门用于基本身份验证。

Client client = ClientBuilder.newClient();    
ResteasyWebTarget resteasyWebTarget = (ResteasyWebTarget)client.target("http://mywebservice/rest/api");
resteasyWebTarget.register(new BasicAuthentication("username", "passwd"));

答案 1 :(得分:8)

考虑来自Adam Bien的solution

您可以将ClientRequestFilter附加到RESTEasy Client,这会在请求中添加Authorization标头:

public class Authenticator implements ClientRequestFilter {

    private final String user;
    private final String password;

    public Authenticator(String user, String password) {
        this.user = user;
        this.password = password;
    }

    public void filter(ClientRequestContext requestContext) throws IOException {
        MultivaluedMap<String, Object> headers = requestContext.getHeaders();
        final String basicAuthentication = getBasicAuthentication();
        headers.add("Authorization", basicAuthentication);

    }

    private String getBasicAuthentication() {
        String token = this.user + ":" + this.password;
        try {
            return "Basic " +
                 DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException ex) {
            throw new IllegalStateException("Cannot encode with UTF-8", ex);
        }
    }
}

Client client = ClientBuilder.newClient()
                     .register(new Authenticator(user, password));

答案 2 :(得分:4)

您可以通过在客户端配置中调用.header(HttpHeaders.AUTHORIZATION, authHeader)将原始授权标头添加到REST客户端。 凭证必须以“user:pass”格式打包在授权标头中,编码为base64字节数组,然后附加到标识基本身份验证的字符串“Basic”。

这是整个片段(受this post on baeldung启发)

    String auth = userName + ":" + password;
    byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("ISO-8859-1")));
    String authHeader = "Basic " + new String(encodedAuth);

    authToken = restClient.target(restApiUrl + loginPath)
            .request()
            .accept(MediaType.TEXT_PLAIN)
            .header(HttpHeaders.AUTHORIZATION, authHeader)
            .get(String.class);

这对Resteasy客户来​​说很有用。有关信息,使用wget进行测试时,我必须使用--auth-no-challenge标记。

答案 3 :(得分:0)

我最近升级到resteasy-client:4.0.0.Final来处理某些Jackson升级问题,并且我注意到设置标头的工作方式似乎有所不同(我收到401:先前有效的每个已验证请求的授权错误) 。我也找不到太多的文档,(如果我的经验可以代表更广泛的情况,则4.0.0.Final版本只有一个月的发行时间,并且存在一些依赖问题)。

该代码先前将标头注入ClientRequestContext:

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

    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        String token = username + ":" + password;
        String base64Token = Base64.encodeString(token);
        requestContext.getHeaders().add("Authorization", "Basic " + base64Token);
    }
}

然后我们在ResteasyClient上设置过滤器,如下所示:

ResteasyClient client = new ResteasyClientBuilder()
            .sslContext(buildSSLContext())
            .hostnameVerifier(buildHostVerifier())
            .build();

client.register(new AddAuthHeadersRequestFilter(user, pass));

但是,这似乎没有设置HeaderDelegate,在4.x(?)以及更早的版本中可以检索标头。

诀窍是在4.0.0最终版本的 ResteasyWebTarget 上注册过滤器,而不是在 client 上注册(最终版本(您可能会注意到clientBuilder现在的工作原理有所不同)也是如此)。

    ResteasyClient client = (ResteasyClient)ResteasyClientBuilder.newBuilder()
            .sslContext(buildSSLContext())
            .hostnameVerifier(buildHostVerifier())
            .build();

    ResteasyWebTarget target = client.target(url);

    target.register(new AddAuthHeadersRequestFilter(user, pass));