JOAuth, основанная на Java библиотека OAuth 1 (окончательная версия) и OAuth 2 (черновик 10). Как мне это использовать? - PullRequest
5 голосов
/ 07 декабря 2010

Я видел слишком много вопросов здесь (SO), спрашивающих об OAuth и как подключиться к API Graph Facebook или Twitter API с помощью протокола OAuth.

Я обнаружил JOAuth (из Google Code), и мне было интересно, как я могу его использовать?Какие еще функции предоставляет JOAuth и хорошо ли он работает с другими библиотеками Java oauth?

1 Ответ

13 голосов
/ 07 декабря 2010

Видя, что я написал JOAuth, я подумал, что было бы целесообразно ответить на этот вопрос на SO.Я не нашел возможности сделать этот вопрос вики-сообществом.: (

Примечание Я здесь не для обсуждения Авторизация OAuth . Для этого есть различные сайты.

Приходит JOAuthс замечательной функцией. Он имеет контроллер OAuthServlet, который управляет вашим ответом HTTP Redirect от поставщика услуг. Чтобы настроить OAuthServlet для вашего веб-приложения, просто объявите его как <servlet> в вашем web.xml, как:

 <servlet>
  <description>An OAuth Servlet Controller</description>
  <display-name>OAuthServlet</display-name>
  <servlet-name>OAuthServlet</servlet-name>
  <servlet-class>com.neurologic.oauth.servlet.OAuthServlet</servlet-class>
  <init-param>
   <param-name>config</param-name>
   <param-value>/WEB-INF/oauth-config.xml</param-value>
  </init-param>
  <load-on-startup>3</load-on-startup>
 </servlet>

И ваше отображение сервлета:

 <servlet-mapping>
  <servlet-name>OAuthServlet</servlet-name>
  <url-pattern>/oauth/*</url-pattern>
 </servlet-mapping>

Теперь, когда у вас есть настройка сервлета OAuth (имейте в виду, что <load-on-startup> не требуется, но мне нравится иметьмои сервлеты инициализированы до того, как я его использую), давайте поговорим о настройке JOAuth.

Файл конфигурации JOAuth по умолчанию - /WEB-INF/oauth-config.xml (следовательно, он не должен быть <init-param> в вашем объявлении сервлета).файл выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<oauth-config>
 <!-- Twitter OAuth Config -->
 <oauth name="twitter" version="1">
  <consumer key="TWITTER_KEY" secret="TWITTER_SECRET" />
  <provider requestTokenUrl="https://api.twitter.com/oauth/request_token" authorizationUrl="https://api.twitter.com/oauth/authorize" accessTokenUrl="https://api.twitter.com/oauth/access_token" />
 </oauth>

 <!-- Facebook OAuth -->
 <oauth name="facebook" version="2">
  <consumer key="APP_ID" secret="APP_SECRET" />
  <provider authorizationUrl="https://graph.facebook.com/oauth/authorize" accessTokenUrl="https://graph.facebook.com/oauth/access_token" />
 </oauth>

 <service path="/request_token_ready" class="com.neurologic.music4point0.oauth.TwitterOAuthService" oauth="twitter">
  <success path="/start.htm" />
 </service>

 <service path="/oauth_redirect" class="com.neurologic.music4point0.oauth.FacebookOAuthService" oauth="facebook">
  <success path="/start.htm" />
 </service>
</oauth-config>

Вы заметите, что каждый элемент <oauth> имеет атрибут version (это обязательный атрибут, который необходим контроллеру, чтобы знать, какой поток oauth использовать). только имеют 2 возможных значения (1 для OAuth1 и 2 для OAuth 2).Для OAuth 2 элемент <consumer> не имеет атрибута requestTokenUrl, как его аналог версии 1.

Служба OAuth является ответственной за обработку OAuth.Каждый OAuthService вызывается контроллером с помощью метода execute().Существует 2 типа OAuthService:

  • com.neurologic.oauth.service.impl.OAuth1Service.
  • com.neurologic.oauth.service.impl.OAuth2Service.

Примечание Для каждогоЕсли вы используете OAuth 2, вы должны иметь услугу, которая расширяет OAuth2Service.То же самое относится и к OAuth 1. В противном случае выдается исключение.

Каждый <service> тег должен иметь атрибут name, который соответствует атрибут <oauth> name (с учетом регистра).

Оба OAuth1Service и OAuth2Service execute(HttpServletRequest, HttpServletResponse) были реализованы для best обработки потока протокола авторизации OAuth,но вы можете переопределить его, если вас это не устраивает.

Пример com.neurologic.music4point0.oauth.FacebookOAuthService:

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.oauth.enums.GrantType;
import net.oauth.exception.OAuthException;
import net.oauth.parameters.OAuth2Parameters;

import com.neurologic.oauth.service.impl.OAuth2Service;
import com.neurologic.oauth.util.Globals;

/**
 * @author The Elite Gentleman
 * @since 05 December 2010
 *
 */
public class FacebookOAuthService extends OAuth2Service {

 private static final String REDIRECT_URL = "http://localhost:8080/Music4Point0/oauth/oauth_redirect";

 /* (non-Javadoc)
  * @see com.neurologic.oauth.service.impl.OAuth2Service#processReceivedAuthorization(javax.servlet.http.HttpServletRequest, java.lang.String, java.util.Map)
  */
 @Override
 protected String processReceivedAuthorization(HttpServletRequest request, String code, Map<String, String> additionalParameters) throws OAuthException {
  // TODO Auto-generated method stub
  OAuth2Parameters parameters = new OAuth2Parameters();
  parameters.setCode(code);
  parameters.setRedirectUri(REDIRECT_URL);

  Map<String, String> responseMap = getConsumer().requestAcessToken(GrantType.AUTHORIZATION_CODE, parameters, null, (String[])null);
  if (responseMap == null) {
   //This usually should never been thrown, but we just do anyway....
   throw new OAuthException("No OAuth response retrieved.");
  }

  if (responseMap.containsKey("error")) {
   throwOAuthErrorException(responseMap);
  }

  if (responseMap.containsKey(OAuth2Parameters.ACCESS_TOKEN)) {
   String accessToken = responseMap.remove(OAuth2Parameters.ACCESS_TOKEN);
   request.getSession().setAttribute(Globals.SESSION_OAUTH2_ACCESS_TOKEN, accessToken);
   processAdditionalReceivedAccessTokenParameters(request, responseMap);
  }

  return null;
 }

 /* (non-Javadoc)
  * @see com.neurologic.oauth.service.impl.OAuth2Service#processAdditionalReceivedAccessTokenParameters(javax.servlet.http.HttpServletRequest, java.util.Map)
  */
 @Override
 protected void processAdditionalReceivedAccessTokenParameters(HttpServletRequest request, Map<String, String> additionalParameters) throws OAuthException {
  // TODO Auto-generated method stub

 }
}

Поскольку Facebook по-прежнему использует OAuth 2 draft 0 (ноль), ихМаркер доступа не выполняет перенаправление HTTP 302, и поэтому processReceivedAuthorization() возвращает ноль.Метод processReceivedAuthorization() позволяет клиенту обрабатывать полученную авторизацию code, а ожидает URL авторизации (поэтому он ожидает тип возврата String).Если метод возвращает null или пустую строку, перенаправление URL никогда не происходит.

После завершения потока oauth вызывается путь в элементе <success> (через RequestDispatcher), чтобы показать, что OAuth успешно завершен.

Чтобы получить доступ к токену доступа (после успешного входа через OAuth), выполните следующие действия:

AccessToken accessToken = (AccessToken)request.getSession().getAttribute(Globals.SESSION_OAUTH1_ACCESS_TOKEN); //For OAuth 1 access token
String accessToken = (String)request.getSession().getAttribute(Globals.SESSION_OAUTH2_ACCESS_TOKEN); //For OAuth 2 access token.

Надеюсь, этот небольшой пример поможет тем, ктостремятся сделать OAuth полезным опытом для своего развития.

Извините, что не смог найти флажок community wiki.Посетите мой блог (в котором почти ничего нет), когда у вас есть время.

Adieu :-)

PS Это реализация TwitterOAuthService:

import javax.servlet.http.HttpServletRequest;

import net.oauth.exception.OAuthException;
import net.oauth.signature.impl.OAuthHmacSha1Signature;
import net.oauth.token.AccessToken;
import net.oauth.token.AuthorizedToken;
import net.oauth.token.RequestToken;

import com.neurologic.oauth.service.impl.OAuth1Service;

/**
 * @author The Elite Gentleman
 * @since 05 December 2010
 *
 */
public class TwitterOAuthService extends OAuth1Service {

    public static final String REQUEST_TOKEN_SESSION = "TWITTER_REQUEST_TOKEN_SESSION";

    /* (non-Javadoc)
     * @see com.neurologic.oauth.service.impl.OAuth1Service#processReceivedAuthorizedToken(javax.servlet.http.HttpServletRequest, net.oauth.token.AuthorizedToken)
     */
    @Override
    protected AccessToken processReceivedAuthorizedToken(HttpServletRequest request, AuthorizedToken authorizedToken) throws OAuthException {
        // TODO Auto-generated method stub
        String requestTokenSecret = null;
        RequestToken requestToken = (RequestToken) request.getSession().getAttribute(REQUEST_TOKEN_SESSION);

        if (requestToken != null) {
            requestTokenSecret = requestToken.getTokenSecret();
        }

        return getConsumer().requestAccessToken(null, authorizedToken, requestTokenSecret, new OAuthHmacSha1Signature());
    }
}

Дополнительные ресурсы

...