一废麻、場景
三個角色:用戶(user),web應(yīng)用(client)模庐,資源服務(wù)器和授權(quán)服務(wù)器合為服務(wù)器(server)
用戶登錄登錄后可查看自己的信息
二烛愧、準備
2.1 數(shù)據(jù)庫
schema
drop table if exists oauth2_client;
drop table if exists oauth2_user;
create table oauth2_user (
id bigint auto_increment,
username varchar(100),
password varchar(100),
salt varchar(100),
constraint pk_oauth2_user primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_oauth2_user_username on oauth2_user(username);
create table oauth2_client (
id bigint auto_increment,
client_name varchar(100),
client_id varchar(100),
client_secret varchar(100),
constraint pk_oauth2_client primary key(id)
) charset=utf8 ENGINE=InnoDB;
create index idx_oauth2_client_client_id on oauth2_client(client_id);
data
DELIMITER ;
delete from oauth2_user;
delete from oauth2_client;
insert into oauth2_user values(1,'admin','d3c59d25033dbf980d29554025c23a75','8d78869f470951332959580424d4bf4f');
insert into oauth2_client values(1,'chapter17-client','c1ebe466-1cdc-4bd3-ab69-77c3561b9dee','d8346ea2-6017-43ed-ad68-19c0f971738b');
2.2 Server
修改數(shù)據(jù)庫鏈接 resources.properties
#dataSource configure
connection.url=jdbc:mysql://mysql-server:3306/shiro
connection.username=r00t
connection.password=r00t
2.3 Client
三、過程分析
image
1)2)用戶訪問client首頁,檢測到用戶未登錄怜姿,重定向到login
image
3)4)點擊授權(quán)登錄慎冤,輸入admin/123456后點擊登錄并授權(quán)按鈕
image
image
// 3)授權(quán)請求 http://localhost:8080/zetark-oauth2-server/oauth2login
if (!isLogin && servletPath.startsWith("/login_authorize")) {
String authorizeUrl = ClientParams.OAUTH_SERVER_AUTHORIZE_URL;
authorizeUrl += "?client_id=c1ebe466-1cdc-4bd3-ab69-77c3561b9dee";
authorizeUrl += "&response_type=code";
authorizeUrl += "&&redirect_uri=" + ClientParams.OAUTH_SERVER_REDIRECT_URI;
response.sendRedirect(authorizeUrl);
return;
}
// 4)授權(quán)響應(yīng)
if (!isLogin && servletPath.startsWith("/login_response")) {
String code = request.getParameter("code");
if (code != null) {
// 6)7)令牌請求及響應(yīng) http://localhost:8080/zetark-oauth2-server/accessToken
OAuthAccessTokenResponse tokenResponse = null;
try {
tokenResponse = OauthClient.makeTokenRequestWithAuthCode(code);
} catch (OAuthProblemException e) {
e.printStackTrace();
} catch (OAuthSystemException e) {
e.printStackTrace();
}
if (tokenResponse != null) {
session.setAttribute("isLogin", true);
session.setAttribute("token", tokenResponse.getAccessToken());
session.setMaxInactiveInterval(tokenResponse.getExpiresIn().intValue());
// 10)11) 根據(jù)token調(diào)用api
String userInfoJson = OauthClient.getAuthedService(tokenResponse.getAccessToken());
Map<String, Object> userInfo = new Gson().fromJson(userInfoJson, Map.class);
System.out.println(userInfo);
session.setAttribute("user", userInfo);
response.sendRedirect("index");
return;
}
} else {
String errorDesc = request.getParameter("error_description");
System.out.println("登錄失敗:" + errorDesc);
}
}
訪問過程
image
client_uri:/
client_uri:/login
# 用戶訪問client首頁/,由于未登錄被重定向到/login頁面
client_uri:/login_authorize
server_uri:/oauth2login
# 用戶在/login頁面點擊授權(quán)登錄后沧卢,向server發(fā)起授權(quán)請求蚁堤,server返回登錄頁面/oauth2login
server_uri:/authorize
client_uri:/login_response
# 用戶在/oauth2login填寫用戶名密碼后點擊授權(quán)登錄后,server驗證后重定向到/login_resposne
server_uri:/accessToken
server_uri:/checkAccessToken
# client在處理/login_response時接收code并再發(fā)起令牌請求搏恤,server返回令牌
server_uri:/v1/openapi/userInfo
# client根據(jù)令牌信息請求api服務(wù)
client_uri:/index
# 向用戶返回/index頁面