OAuth2.0之OLTU实现举例

一、场景

三个角色:用户(user),web应用(client),资源服务器和授权服务器合为服务器(server)

用户登录登录后可查看自己的信息

各个角色之间的关系,可以通过国外网站介绍了解一下, 如下

OAuth 2.0 defines the following roles of users and applications:

  • Resource Owner
  • Resource Server
  • Client Application
  • Authorization Server

These roles are illustrated in this diagram:

OAuth 2.0 roles as defined in the specification.

The resource owner is the person or application that owns the data that is to be shared. For instance, a user on Facebook or Google could be a resource owner. The resource they own is their data. The resource owner is depicted in the diagram as a person, which is probably the most common situation. The resource owner could also be an application. The OAuth 2.0 specification mentions both possibilities.

The resource server is the server hosting the resources. For instance, Facebook or Google is a resource server (or has a resource server).

The client application is the application requesting access to the resources stored on the resource server. The resources, which are owned by the resource owner. A client application could be a game requesting access to a users Facebook account.

The authorization server is the server authorizing the client app to access the resources of the resource owner. The authorization server and the resource server can be the same server, but it doesn't have to. The OAuth 2.0 specification does not say anything about how these two servers should communicate, if they are separate. This is an internal design decision to be made by the resource server + authorization server developers.

上述内容来源:http://tutorials.jenkov.com/oauth2/roles.html

二、准备

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/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) 根据token调用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);
    }
}

访问过程

client_uri:/
client_uri:/login
# 用户访问client首页/,由于未登录被重定向到/login页面

client_uri:/login_authorize
server_uri:/oauth2login
# 用户在/login页面点击授权登录后,向server发起授权请求,server返回登录页面/oauth2login

server_uri:/authorize
client_uri:/login_response
# 用户在/oauth2login填写用户名密码后点击授权登录后,server验证后重定向到/login_resposne

server_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

来源: https://www.cnblogs.com/okokabcd/p/8526239.html