有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用Jersey客户端对支持JAAS的Web服务器进行身份验证?

我有以下情况:

服务器:Jetty(配置JAAS)

客户端:通过JUnit(通过Maven)调用Jersey

我在网络服务器上安装了JAAS。我将客户端部分用作测试

在服务器端,用户通过表单进行身份验证,基本身份验证通过JAAS处理。显然,用户在能够查看某些页面之前需要经过身份验证

我想在尝试访问安全页面之前能够通过Jersey登录。如何做到这一点?我已经检查过你是否可以定义一个过滤器,但我不太确定如何使用它。而且——一旦用户通过表单登录,我如何(从客户端)进入我真正感兴趣的页面

如果有人能给我举一个例子,说明泽西在客户方面是如何做到这一点的,我将不胜感激

我有以下JUnit测试用例方法:

@Test
public void testLogin()
        throws IOException
{
    String URL_LOGIN = "http://localhost:9080/foo/auth.html";
    Client client = Client.create();

    String username = "me";
    String password = "me";

    final HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter(username, password);
    client.addFilter(authFilter);
    client.addFilter(new LoggingFilter());

    WebResource webResource = client.resource(URL_LOGIN);
    // I even tried:
    // webResource.header("Authorization", "Basic " + "base64encoded_userid:password").type("application/xml");

    String page = webResource.post(String.class);

    System.out.println(page);
}

请注意:

1)http://localhost:9080/foo/auth.html是我在成功创作时应该看到的页面

2)我实际上看到了http://localhost:9080/foo/login.html的输出

3)显然,通过浏览器,我可以通过登录成功登录。html页面

我错过了什么


共 (4) 个答案

  1. # 1 楼答案

    对我来说,这些改变解决了这个问题:

    String URL_LOGIN = "http://localhost:9080/foo/j_security_check";
    String URL_DATA = "http://localhost:9080/foo/auth.html";
    Client client = Client.create();
    
    // add a filter to set cookies received from the server and to check if login has been triggered
    client.addFilter(new ClientFilter() {
        private ArrayList<Object> cookies;
    
        @Override
        public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
            if (cookies != null) {
                request.getHeaders().put("Cookie", cookies);
            }
            ClientResponse response = getNext().handle(request);
            // copy cookies
            if (response.getCookies() != null) {
                if (cookies == null) {
                    cookies = new ArrayList<Object>();
                }
                // A simple addAll just for illustration (should probably check for duplicates and expired cookies)
                cookies.addAll(response.getCookies());
            }
            return response;
        }
    });
    
    String username = "me";
    String password = "me";
    
    
    // Get the protected web page: (this will make the server know that someone will try to access the protected resource)
    WebResource  webResource = client.resource(URL_DATA);
    String response = webResource.get(String.class);
    
    
    // Login:
    webResource = client.resource(URL_LOGIN);
    
    com.sun.jersey.api.representation.Form form = new Form();
    form.putSingle("j_username", username);
    form.putSingle("j_password", password);
    webResource.type("application/x-www-form-urlencoded").post(form);
    
    
    // Get the protected web page: (this time the service will return the data)
    webResource = client.resource(URL_DATA);
    response = webResource.get(String.class);
    
  2. # 2 楼答案

    要从基于表单的身份验证访问Rest端点,需要向JAX-RS客户端注册表单身份验证过滤器。下面的git hub链接给出了一个有用的过滤器类

    https://github.com/imixs/imixs-melman/blob/master/src/main/java/org/imixs/melman/FormAuthenticator.java

    使用FormAuthenticator。java在您的项目和Rest客户端中执行以下操作:

    // Constructor of jersey Rest client
    public RestClass(String username, String password)
    {
        private WebTarget webTarget;
        private Client client;
    
        private static final String BASE_URI = "http://localhost:8080/SampleRest/webresources";
    
        client = javax.ws.rs.client.ClientBuilder.newClient();
        client.register(new FormAuthenticator(BASE_URI, user,  password));
    
        webTarget = client.target(BASE_URI).path("restpath");
    }
    

    一切正常。我用过了,这个问题解决了。JAX-RS API必须在其发行版中提供此验证器

    注意:在基于表单的身份验证中使用的相同用户名和密码将由Servlet中的调用客户端提供

    as RestClient rs = new RestClient(username, password);
    

    **应用程序类应注册RoleAllowedDynamic功能以使角色生效** 我的申请。Web项目中的java,其中包含Rest类和FormAuthenticator。java rest包

    @ApplicationPath("webresources")
    
    public class MyApplication extends ResourceConfig {
    
        public MyApplication() {
            packages("entity.service");
            packages("rest");
            register(RolesAllowedDynamicFeature.class);
        }
    }
    
  3. # 3 楼答案

    JAAS的自动化:

        String URL_DATA = "http://localhost:9080/foo/auth.html";
        Client client = Client.create();
    
        String username = "me";
        String password = "me";
    
        client.addFilter(new HTTPBasicAuthFilter(username, password));
    
        // Get the protected web page:
        WebResource webResource = client.resource(URL_DATA);
        String response = webResource.get(String.class);
        System.out.println(response);
    
  4. # 4 楼答案

    使用Basic auth,您根本不需要进入任何登录页面。如果服务器配置为使用基本身份验证,则如果在请求中包含基本身份验证标头,则可以向任何受保护页面发出请求。球衣过滤器会处理这些。因此,如果基本身份验证真的是服务器正在使用的,那么您的代码应该可以工作

    考虑到它不起作用以及它不起作用的方式,我非常确定服务器被配置为使用基于表单的身份验证,而不是基本的身份验证

    为了使基于表单的身份验证能够工作,您必须发送一个post请求,其中包含登录所需的用户名和密码等表单数据,然后将从服务器收到的cookie设置为后续请求(因为一旦您登录,服务器将设置会话cookie)

    看看如何登录。html看起来像——它应该包含一个表单。如果它使用的是标准servlet表单auth。,该表单的操作URL应该是“j_security_check”,并且应该有两个表单参数:j_用户名和j_密码。如果是这种情况,您可以尝试以下方法:

    String URL_LOGIN = "http://localhost:9080/foo/j_security_check";
    String URL_DATA = "http://localhost:9080/foo/auth.html";
    Client client = Client.create();
    
    // add a filter to set cookies received from the server and to check if login has been triggered
    client.addFilter(new ClientFilter() {
        private ArrayList<Object> cookies;
    
        @Override
        public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
            if (cookies != null) {
                request.getHeaders().put("Cookie", cookies);
            }
            ClientResponse response = getNext().handle(request);
            // copy cookies
            if (response.getCookies() != null) {
                if (cookies == null) {
                    cookies = new ArrayList<Object>();
                }
                // A simple addAll just for illustration (should probably check for duplicates and expired cookies)
                cookies.addAll(response.getCookies());
            }
            return response;
        }
    });
    
    String username = "me";
    String password = "me";
    
    // Login:
    WebResource webResource = client.resource(URL_LOGIN);
    
    com.sun.jersey.api.representation.Form form = new Form();
    form.putSingle("j_username", username);
    form.putSingle("j_password", password);
    webResource.type("application/x-www-form-urlencoded").post(form);
    
    // Get the protected web page:
    webResource = client.resource(URL_DATA);
    String response = webResource.get(String.class);
    

    我还没有测试过这个,所以可能会有一些拼写错误或bug