サードパーティ上陸
41014 ワード
文書ディレクトリ OAuthプロトコル概要 微信自撮りデータ共有例 OAuthプロトコルの役割と実行フロー ロール フロー ライセンスモード 認証コードパターン Spring Social基本原理 Spring Social基本インタフェース 第三者登録:QQ APIインタフェース QQUserInfo QQ QQImpl ServiceProviderインタフェース QQServiceProvider QQOAuth2Template ApiAdapterインタフェース QQAdapter ConnectionFactory QQConnectionFactory UsersConnectionRepository 表構造 構成 OAuthプロトコルの概要 OAuthプロトコルはどのような問題を解決しますか OAuthプロトコルの主要な役割 OAuthプロトコル実行フロー 微信自撮りデータ共有の例
微信自撮りで得た写真は、第三者が写真を美化したいと応用している.どのようにしてサードパーティアプリケーションに微信のユーザー権限を取得させることができますか?難点 1、テンセントは第三者アプリケーションが直接ユーザーの私有データ情報にアクセスすることを許可しない
2、ユーザーが第三者アプリケーションのユーザーデータの読み取りに同意した場合、どのような「同意」法がありますか.
アカウントのパスワードを第三者に直接提供することはできないでしょう.
3、サードパーティアプリケーションがユーザーの微信でのユーザー名パスワードを取得した場合、以下の問題が発生する
1、サードパーティアプリケーションはユーザーが微信のすべてのデータにアクセスできる
2、ユーザーはパスワードを変更してこそ、権限を取り戻すことができる
3、パスワードの漏洩の可能性が大幅に高まる
この例では、OAuthプロトコルは、ライセンスの問題をこのように解決します.
微信のアカウントパスワードを第三者に適用するのではなく、このTokenに権限情報、期限切れ時間があり、このTokenでユーザー名パスワードを解読することはできません.
これにより、セキュリティ、利便性などの問題が同時に解決されます.
以上、OAuthプロトコルの基本的な紹介です
OAuthプロトコルの役割と実行プロセス
ロール#ロール#サービスプロバイダ:Provider トークンを提供する、例えば、本例の微信(テンセント)リソース所有者:ResourceOwner アクセスが必要なデータリソースの所有者、例えば、この例の微信ユーザサードパーティアプリケーション:Client 認証サーバ:Authorization Server ユーザのアイデンティティを認証し、トークンを生成するリソースサーバ:ResourceServer 1、ユーザーデータ資源の保存
2、検証トークン
一般的な実用開発では、認証サーバとリソースサーバは、1台のマシンであってもよい
プロセス
0、微信ユーザーが第三者応用にアクセスする
1、サードパーティのアプリケーションは微信ユーザーの授権を要求する
2、微信ユーザーは第三者アプリケーションの授権要求に同意する
3、第三者アプリケーション認証サーバー申請トークン
4、タスクサーバは今回のトークン申請が合法であるかどうかを検証する.すなわち、実際のユーザーが許可に同意したかどうかを検証し、トークンを発行する.
5、サードパーティアプリケーションはトークンを持って資源サーバーに行って資源データを申請する
6、資源サーバーはトークンが合法かどうかを検証し、合法的に資源を第三者に開放する
認証モード
認証コードパターン
最も完全で、最も包括的で、最も一般的なライセンスモデルです.
特徴:
1、ユーザーが授権に同意する動作は、認証サーバーで行われる
2.サードパーティアプリケーションは認証サーバの認証コードを受信し、トークンを取得する必要があるため、サードパーティアプリケーションには独自のサーバが必要である.サードパーティアプリケーションが通常の静的Webサイトである場合、ライセンスコードモードは使用できません.簡略化モードを使用可能
Spring Socialの基本原理
OAuthは本質的に認証プロトコルであり、ユーザが自分のユーザ名のパスワード情報を暴露せずに第三者アプリケーションを認証する問題を解決する
Spring Socialサードパーティのログインを実現
現在、多くのサイトやアプリがあります.私たちは微信やQQを使ってログインすることができます.許可さえすれば、アプリやサイトを再登録する必要はありません.
サードパーティアプリケーションはトークンを用いてユーザ基本情報を取得し,この情報をステップ7に従って処理することで,1回のログインに相当する.
Spring Socialは6、7の過程を
Spring Social基本インタフェース ……
第三者登録:QQ
QQの第三者登録は、標準的なOAuthプロトコルであり、微信はそうではなく、やや異なり、具体的な後続は述べられる.
サードパーティのログインは、Webページやアプリで使用できますので、
APIインタフェース
APIインタフェースはテンセントからユーザー情報を取得するために使用される.
関連クラス:
では、テンセントからユーザー情報をどのように取得しますか?これはテンセントの文書を見なければなりません.
テンセント
ユーザーの基本情報を取得するインタフェースはテンセントのドキュメントです
QQUserInfo
取得したQQユーザーの情報をカプセル化する
ここの内容はテンセントの文書によって決定されます
パラメータの説明
説明
ret
リターンコード
msg
ret<0の場合、対応するエラーメッセージが表示され、戻りデータはすべてUTF-8で符号化されます.
nickname
QQ空間でのユーザーのニックネーム.
figureurl
サイズ30×30ピクセルのQQ空間アバターURL.
figureurl_1
サイズ50×50ピクセルのQQ空間アバターURL.
figureurl_2
サイズは100×100画素のQQ空間の顔のURL.
figureurl_qq_1
サイズ40×40ピクセルのQQアイコンURL.
figureurl_qq_2
サイズは100×100ピクセルのQQアイコンURL.すべてのユーザーがQQの100 x 100の顔を持っているわけではありませんが、40 x 40ピクセルは必ずあります.
gender
性別.取得できない場合はデフォルトで「男」を返します.
QQ
インタフェース、QQユーザー情報を取得する
QQImpl
ServiceProviderインタフェース
QQServiceProvider
QQOAuth2Template
ApiAdapterインタフェース
テンセントが提供するユーザー情報フォーマットを必要なフォーマットに変換するために使用されます
QQAdapter
ConnectionFactory
QQConnectionFactory
ProviderId:プロバイダ固有のID、プロファイルからの取り込み
UsersConnectionRepository
操作UserConnectionテーブル、テーブル構造は
テーブル構造
コンフィギュレーション
微信自撮りで得た写真は、第三者が写真を美化したいと応用している.どのようにしてサードパーティアプリケーションに微信のユーザー権限を取得させることができますか?
2、ユーザーが第三者アプリケーションのユーザーデータの読み取りに同意した場合、どのような「同意」法がありますか.
アカウントのパスワードを第三者に直接提供することはできないでしょう.
3、サードパーティアプリケーションがユーザーの微信でのユーザー名パスワードを取得した場合、以下の問題が発生する
1、サードパーティアプリケーションはユーザーが微信のすべてのデータにアクセスできる
2、ユーザーはパスワードを変更してこそ、権限を取り戻すことができる
3、パスワードの漏洩の可能性が大幅に高まる
この例では、OAuthプロトコルは、ライセンスの問題をこのように解決します.
微信のアカウントパスワードを第三者に適用するのではなく、このTokenに権限情報、期限切れ時間があり、このTokenでユーザー名パスワードを解読することはできません.
これにより、セキュリティ、利便性などの問題が同時に解決されます.
以上、OAuthプロトコルの基本的な紹介です
OAuthプロトコルの役割と実行プロセス
ロール#ロール#
2、検証トークン
一般的な実用開発では、認証サーバとリソースサーバは、1台のマシンであってもよい
プロセス
0、微信ユーザーが第三者応用にアクセスする
1、サードパーティのアプリケーションは微信ユーザーの授権を要求する
2、微信ユーザーは第三者アプリケーションの授権要求に同意する
3、第三者アプリケーション認証サーバー申請トークン
4、タスクサーバは今回のトークン申請が合法であるかどうかを検証する.すなわち、実際のユーザーが許可に同意したかどうかを検証し、トークンを発行する.
5、サードパーティアプリケーションはトークンを持って資源サーバーに行って資源データを申請する
6、資源サーバーはトークンが合法かどうかを検証し、合法的に資源を第三者に開放する
認証モード
認証コードパターン
最も完全で、最も包括的で、最も一般的なライセンスモデルです.
特徴:
1、ユーザーが授権に同意する動作は、認証サーバーで行われる
2.サードパーティアプリケーションは認証サーバの認証コードを受信し、トークンを取得する必要があるため、サードパーティアプリケーションには独自のサーバが必要である.サードパーティアプリケーションが通常の静的Webサイトである場合、ライセンスコードモードは使用できません.簡略化モードを使用可能
Spring Socialの基本原理
OAuthは本質的に認証プロトコルであり、ユーザが自分のユーザ名のパスワード情報を暴露せずに第三者アプリケーションを認証する問題を解決する
Spring Socialサードパーティのログインを実現
現在、多くのサイトやアプリがあります.私たちは微信やQQを使ってログインすることができます.許可さえすれば、アプリやサイトを再登録する必要はありません.
サードパーティアプリケーションはトークンを用いてユーザ基本情報を取得し,この情報をステップ7に従って処理することで,1回のログインに相当する.
Spring Socialは6、7の過程を
SocialAuthenticationFilter
にカプセル化した.Spring Social基本インタフェース
AbstractOAuth2ServiceProvider
:サービスプロバイダOAuth2Operations
、 OAuth2Template
AbstractOAuth2ApiBinding
Connection
、 OAuth2Connection
ConnectionFactory
、 OAuth2ConnectionFactory
第三者登録:QQ
QQの第三者登録は、標準的なOAuthプロトコルであり、微信はそうではなく、やや異なり、具体的な後続は述べられる.
サードパーティのログインは、Webページやアプリで使用できますので、
imooc-security-core
プロジェクトに関連コードが書かれています.APIインタフェース
APIインタフェースはテンセントからユーザー情報を取得するために使用される.
関連クラス:
では、テンセントからユーザー情報をどのように取得しますか?これはテンセントの文書を見なければなりません.
テンセント
ユーザーの基本情報を取得するインタフェースはテンセントのドキュメントです
QQUserInfo
取得したQQユーザーの情報をカプセル化する
package com.imooc.security.core.social.qq.api;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* QQ
*
* @Author sherry
* @Description
* @Date Create in 2019-03-27
* @Modified By:
*/
@Data
@Accessors(chain = true)
public class QQUserInfo {
private int ret;
private String openId;
private String msg;
private String nickname;
private String figureurl;
private String figureurl_1;
private String figureurl_2;
private String figureurl_qq_1;
private String figureurl_qq_2;
private String gender;
private String is_yellow_vip;
private String vip;
private String yellow_vip_level;
private String level;
private String is_yellow_year_vip;
}
ここの内容はテンセントの文書によって決定されます
パラメータの説明
説明
ret
リターンコード
msg
ret<0の場合、対応するエラーメッセージが表示され、戻りデータはすべてUTF-8で符号化されます.
nickname
QQ空間でのユーザーのニックネーム.
figureurl
サイズ30×30ピクセルのQQ空間アバターURL.
figureurl_1
サイズ50×50ピクセルのQQ空間アバターURL.
figureurl_2
サイズは100×100画素のQQ空間の顔のURL.
figureurl_qq_1
サイズ40×40ピクセルのQQアイコンURL.
figureurl_qq_2
サイズは100×100ピクセルのQQアイコンURL.すべてのユーザーがQQの100 x 100の顔を持っているわけではありませんが、40 x 40ピクセルは必ずあります.
gender
性別.取得できない場合はデフォルトで「男」を返します.
インタフェース、QQユーザー情報を取得する
package com.imooc.security.core.social.qq.api;
import java.io.IOException;
/**
* @Author sherry
* @Description
* @Date Create in 2019-03-27
* @Modified By:
*/
public interface QQ {
QQUserInfo getUserInfo();
}
QQImpl
package com.imooc.security.core.social.qq.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.social.oauth2.AbstractOAuth2ApiBinding;
import org.springframework.social.oauth2.TokenStrategy;
import java.io.IOException;
@Slf4j
public class QQImpl extends AbstractOAuth2ApiBinding implements QQ {
private static final String URL_GET_OPENID = "https://graph.qq.com/oauth2.0/me?access_token=%s";
private static final String URL_GET_USERINFO = "https://graph.qq.com/user/get_user_info?oauth_consumer_key=%s&openid=%s";
private String appId;
private String openId;
private ObjectMapper objectMapper = new ObjectMapper();
public QQImpl(String accessToken, String appId) {
super(accessToken, TokenStrategy.ACCESS_TOKEN_PARAMETER);// access_token param
this.appId = appId;
String url = String.format(URL_GET_OPENID, accessToken);
String result = getRestTemplate().getForObject(url, String.class);
log.info(result);
this.openId = StringUtils.substringBetween(result, "\"openId\":", "}");
}
@Override
public QQUserInfo getUserInfo() {
String url = String.format(URL_GET_USERINFO, appId, openId);
String result = getRestTemplate().getForObject(url, String.class);
log.info(result);
return objectMapper.readValue(result, QQUserInfo.class);
}
}
/*
AbstractOAuth2ApiBinding accessToken , OAuth ,
token , , QQImpl
*/
ServiceProviderインタフェース
QQServiceProvider
package com.imooc.security.core.social.qq.connect;
import com.imooc.security.core.social.qq.api.QQ;
import com.imooc.security.core.social.qq.api.QQImpl;
import org.springframework.social.oauth2.AbstractOAuth2ServiceProvider;
public class QQServiceProvider extends AbstractOAuth2ServiceProvider<QQ> {
private String appId;
private static final String URL_AUTHORIZE="https://graph.qq.com/oauth2.0/authorize";
private static final String URL_ACCESS_TOKEN="https://graph.qq.com/oauth2.0/token";
/**
* Create a new {@link OAuth2ServiceProvider}.
*
* @param oauth2Operations the OAuth2Operations template for conducting the OAuth 2 flow with the provider.
*/
public QQServiceProvider(String appId,String appSecret) {
// QQOAuth2Template, 、
super(new QQOAuth2Template(appId, appSecret, URL_AUTHORIZE, URL_ACCESS_TOKEN));
this.appId = appId;
}
@Override
public QQ getApi(String accessToken) {
return new QQImpl(accessToken,appId);
}
}
QQOAuth2Template
package com.imooc.security.core.social.qq.connect;
import org.springframework.social.oauth2.*;
/**
* @Author sherry
* @Description
* @Date Create in 2019-03-28
* @Modified By:
*/
public class QQOAuth2Template extends OAuth2Template {
public QQOAuth2Template(String appId, String appSecret, String urlAuthorize, String urlAccessToken) {
super(appId,appSecret,urlAuthorize,urlAccessToken);
}
}
ApiAdapterインタフェース
テンセントが提供するユーザー情報フォーマットを必要なフォーマットに変換するために使用されます
QQAdapter
package com.imooc.security.core.social.qq.connect;
import com.imooc.security.core.social.qq.api.QQ;
import com.imooc.security.core.social.qq.api.QQUserInfo;
import org.springframework.social.connect.ApiAdapter;
import org.springframework.social.connect.ConnectionValues;
import org.springframework.social.connect.UserProfile;
public class QQAdapter implements ApiAdapter<QQ> {
/**
* Api
*
* @param api
* @return
*/
@Override
public boolean test(QQ api) {
return true;
}
/**
* Connection Api
*
* @param api
* @param values
*/
@Override
public void setConnectionValues(QQ api, ConnectionValues values) {
QQUserInfo qqUserInfo = api.getUserInfo();
// Api QQ Connection
values.setDisplayName(qqUserInfo.getNickname());
values.setImageUrl(qqUserInfo.getFigureurl_qq_1());
// QQ , ProfileUrl
values.setProfileUrl(null);
//QQ
values.setProviderUserId(qqUserInfo.getOpenId());
}
@Override
public UserProfile fetchUserProfile(QQ api) {
//
return null;
}
/**
* (QQ )
*
* @param api
* @param message
*/
@Override
public void updateStatus(QQ api, String message) {
// do nothing
}
}
ConnectionFactory
QQConnectionFactory
package com.imooc.security.core.social.qq.connect;
import com.imooc.security.core.social.qq.api.QQ;
import org.springframework.social.connect.support.OAuth2ConnectionFactory;
public class QQConnectionFactory extends OAuth2ConnectionFactory<QQ> {
public QQConnectionFactory(String providerId, String appId, String appSecret) {
super(providerId, new QQServiceProvider(appId, appSecret), new QQAdapter());
}
}
ProviderId:プロバイダ固有のID、プロファイルからの取り込み
UsersConnectionRepository
操作UserConnectionテーブル、テーブル構造は
テーブル構造
create table UserConnection (userId varchar(255) not null,
providerId varchar(255) not null,
providerUserId varchar(255),
rank int not null,
displayName varchar(255),
profileUrl varchar(512),
imageUrl varchar(512),
accessToken varchar(512) not null,
secret varchar(512),
refreshToken varchar(512),
expireTime bigint,
primary key (userId, providerId, providerUserId));
create unique index UserConnectionRank on UserConnection(userId, providerId, rank);
コンフィギュレーション
package com.imooc.security.core.social;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import javax.sql.DataSource;
@Configuration
@EnableSocial
@Order(1)
public class SocialConfigurer extends SocialConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
// , Connection ( , ), ( )
JdbcUsersConnectionRepository jdbcUsersConnectionRepository =
new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
return jdbcUsersConnectionRepository;
}
}