java - 通过 HttpURLConnection 的浏览器身份验证

标签 java http authentication

目前我正在研究 TMDb API 的实现.有一种方法叫做 User Authentication .我已成功实现第 1 步

Step 1: Generate a Request Token

Start by making an API call to the new token method. This will return a new request token that will be valid for 60 minutes. The request token is not authorized by the user at this stage. Request tokens are API account specific and are the tie between your application and the user in step 2.

对于第 1 步,我有以下代码:

URL url = new URL("http://api.themoviedb.org/3/authentication/token/new?api_key=the_key");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringWriter writer = new StringWriter();
String line;
while ((line = reader.readLine()) != null) {
    writer.write(line);
}
reader.close();
Map<String, List<String>> headerFields = connection.getHeaderFields();
String callBackUrl = null;
for(Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
    if(entry.getKey() != null && entry.getKey().equals("Authentication-Callback")) {
        callBackUrl = entry.getValue().get(0);
    }
}

它在控制台中打印回调 url 以及请求 token (如果我将 writer.toString() 转换为 Json 对象)。

但第二部分是通过用户名和密码进行用户身份验证。回调 url 将用户重定向到 TMDb 的登录页面。我通过将回调 url 从控制台复制粘贴到浏览器来测试它。

第 2 步指出:

Step 2: Request Authorization From the User

Once you have a valid request token, your application needs to open a web browser and send them to TMDb. The HTTP response when generating a new token will include a Authentication-Callback header that you can easily use for the redirect.

If the user is not logged in to TMDb, they will be redirected to the login page before being asked to grant your application permission to use their account. Once the user has granted your application permission to use their account, the browser-based part of this process is over and you can return them to your application.

Just like the request for a new token, the approved response will include a Authentication-Callback header which again, is a convenient way to redirect your application back to the API and generate the real session id.

现在我的问题是:如果我有用户名和密码,我可以通过 HttpURLConnection 或任何其他方式验证该用户吗?

我试过这个:

url = new URL(callBackUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");        
BASE64Encoder encoder = new BASE64Encoder();
String usernamepassword = "myusername" + ":" + "mypassword";
String encodedAuthorization = encoder.encode(usernamepassword.getBytes());
connection.setRequestProperty("Authorization", "Basic "+ encodedAuthorization);
headerFields = connection.getHeaderFields();

for(Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
    System.out.println(entry.getKey() + " : " +entry.getValue());
}

但在控制台中我得到:

null : [HTTP/1.1 404 Not Found]
Status : [404 Not Found]
X-Frame-Options : [sameorigin]
Date : [Tue, 28 Feb 2012 08:30:17 GMT]
Vary : [Accept-Encoding]
X-Cascade : [pass]
Content-Length : [7835]
X-XSS-Protection : [1; mode=block]
Set-Cookie : [tmdb.session=BAh7CUkiD3Nlc3Npb25faWQGOgZFRiJFNGRkMjc5ODYwMjJmYWYwZDlmOGE5%0AOTVjY2E0NWFjMzhhYTRiOGFjOGJiYjQ5ZGFhNzExNDdkMGM4MWNhZGUyMEki%0ADWxhbmd1YWdlBjsARkkiB2VuBjsARkkiC2xvY2FsZQY7AEZJIgd1cwY7AEZJ%0AIg5sb2dnZWRfaW4GOwBGRg%3D%3D%0A; path=/; expires=Thu, 29-Mar-2012 08:30:17 GMT; HttpOnly]
Content-Type : [text/html;charset=utf-8]
Connection : [keep-alive]
Server : [nginx]

如你所见:

Status : [404 Not Found]

所以最后的程序没有结果。

我是否以错误的方式实现了身份验证?

非常感谢您的建议。

提前致谢。

最佳答案

我不熟悉 TmDB,但我已经阅读了有关其用户身份验证过程的页面,我认为您误解了它。

他们明确表示他们希望第三方应用程序存储用户名/密码凭证,或在请求中传递它(“这个系统的好处是我们永远不会传递通过空中传输用户名或密码或需要第三方应用程序将其存储在本地”)。 callbackUrl 上的页面不是您(第三方应用程序)应该发布任何内容的页面;它是供人类使用的。用户看到此页面时会询问“是否要授予对 [第三方应用程序名称] 的访问权限?如果是,请在此处登录”。您的应用程序无法控制该过程;它有意与您分开,因此用户的凭据永远不会被您拦截或存储。用户批准您后,您将能够获得您使用的不透明 token ( session ID)而不是凭据。

这与三足OAuth基本相同;主要区别是 OAuth 需要一些额外的字段和签名计算,所以这更简单。但它与HTTP basicauth无关。

我相信你想要做的是:

  1. 照原样执行第 1 步。但是不要只是获取 Authentication-Callback header ;还解析 JSON 响应并获取“request_token”的值。

  2. 通过调用 new session API 检查用户是否已经授权您,再次传递您的 API key 以及先前获取的“request_token”。如果您获得带有“session_id”的成功响应,则您已获得授权,可以跳过其余步骤。

  3. 否则,将用户重定向到 Authentication-Callback 中指定的 URL(或者打开浏览器,如果您尚未在浏览器中)。

  4. 现在,由于登录/批准过程与您的应用程序是分开的,您如何知道它何时完成?文档对此不清楚,并且没有描述任何方式让您获得有关它的通知(或使 TMDb 重定向回您的应用程序)。您可能只需要在某个合理的时间间隔内轮询结果(即返回步骤 2)。

关于java - 通过 HttpURLConnection 的浏览器身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9478769/

相关文章:

http - ListenAndServe 返回 net.DNSError "nodename nor servname provided"

javascript - 使用 ReactJS 时如何将 JWT 存储在 cookie 中

authentication - Tomcat 7 : authentication with multiple UserDatabaseRealms for multiple webapps

http - Ionic2,Angular2 :How to avoid CORS issue while using http get for REST API service call?

java - 我应该使用什么 xml 解析器?

java - 如何使用 Joiner 仅加入特定属性?

java - 为 JMS 消息创建分配并行流处理

java - Dropwizard命令行输入

javascript - SPA 和 node.js 服务器的身份验证

java - JOOQ 中事务未回滚