为什么80%的码农都做不了架构师?>>>
一、场景
三个角色:用户(user),web应用(client),资源服务器和授权服务器合为服务器(server)
用户登录登录后可查看自己的信息
二、准备
2.1 数据库
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
zetark-oauth2-server
修改数据库链接 resources.properties
#dataSource configure
connection.url=jdbc:mysql://mysql-server:3306/shiro
connection.username=r00t
connection.password=r00t
2.3 Client
zetark-oauth2-client
三、过程分析
1)2)用户访问client首页,检测到用户未登录,重定向到login
3)4)点击授权登录,输入admin/123456后点击登录并授权按钮
// 3)授权请求 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)授权响应
if (!isLogin && servletPath.startsWith("/login_response")) {String code = request.getParameter("code");if (code != null) {// 6)7)令牌请求及响应 http://localhost:8080/zetark-oauth2-server/accessTokenOAuthAccessTokenResponse 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) 根据token调用apiString 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);}
}
访问过程
client_uri:/
client_uri:/login
# 用户访问client首页/,由于未登录被重定向到/login页面client_uri:/login_authorize
server_uri:/oauth2login
# 用户在/login页面点击授权登录后,向server发起授权请求,server返回登录页面/oauth2loginserver_uri:/authorize
client_uri:/login_response
# 用户在/oauth2login填写用户名密码后点击授权登录后,server验证后重定向到/login_resposneserver_uri:/accessToken
server_uri:/checkAccessToken
# client在处理/login_response时接收code并再发起令牌请求,server返回令牌server_uri:/v1/openapi/userInfo
# client根据令牌信息请求api服务client_uri:/index
# 向用户返回/index页面
四、参考
https://github.com/ameizi/oltu-oauth2-example