qiuxuhui

导航

OAuth2 简化模式

4. 简化模式

简化模式,不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了“授权码”这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要授权。

 

 

  • (A)用户访问客户端,后者将前者跳转到到授权服务器。
  • (B)用户选择是否给予客户端授权。
  • (C)假设用户给予授权,授权服务器将用户导向客户端指定的"重定向URI",并在 URI 的 Hash 部分包含了访问令牌
  • (D)浏览器向资源服务器发出请求,其中不包括上一步收到的 Hash 值。
  • (E)资源服务器返回一个网页,其中包含的代码可以获取 Hash 值中的令牌。
  • (F)浏览器执行上一步获得的脚本,提取出令牌。
  • (G)浏览器将令牌发给客户端。

 

 

 

 

 

 

 

 

4.1 搭建授权服务器

复制出 lab-68-demo02-authorization-server-with-implicit 项目,修改搭建授权服务器。改动点如下图所示:

 

 

 

 

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    /**
     * 用户认证 Manager
     */
    @Autowired
    private AuthenticationManager authenticationManager;

    //配置使用的 AuthenticationManager 实现用户认证的功能
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    //设置 /oauth/check_token 端点,通过认证后可访问。
    //这里的认证,指的是使用 client-id + client-secret 进行的客户端认证,不要和用户认证混淆。
    //其中,/oauth/check_token 端点对应 CheckTokenEndpoint 类,用于校验访问令牌的有效性。
    //在客户端访问资源服务器时,会在请求中带上访问令牌。
    //在资源服务器收到客户端的请求时,会使用请求中的访问令牌,找授权服务器确认该访问令牌的有效性。
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.checkTokenAccess("isAuthenticated()");
    }

    //进行 Client 客户端的配置。
    //设置使用基于内存的 Client 存储器。实际情况下,最好放入数据库中,方便管理。
/*
*
* 创建一个 Client 配置。如果要继续添加另外的 Client 配置,可以在 <4.3> 处使用 #and() 方法继续拼接。
* 注意,这里的 .withClient("clientapp").secret("112233") 代码段,就是 client-id 和 client-secret。
*补充知识:可能会有胖友会问,为什么要创建 Client 的 client-id 和 client-secret 呢?
*通过 client-id 编号和 client-secret,授权服务器可以知道调用的来源以及正确性。这样,
*即使“坏人”拿到 Access Token ,但是没有 client-id 编号和 client-secret,也不能和授权服务器发生有效的交互。
*/
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory() // <4.1>
                .withClient("clientapp").secret("112233") // <4.2> Client 账号、密码。
                .authorizedGrantTypes("implicit") // <4.2> 简化模式
                .redirectUris("http://127.0.0.1:9090/callback02")
                .scopes("read_userinfo", "read_contacts") // <4.2> 可授权的 Scope
//                .and().withClient() // <4.3> 可以继续配置新的 Client
        ;
    }

}

  

仅仅需要修改 OAuth2AuthorizationServerConfig 类,设置使用 "implicit" 简化模式,并设置回调地址。

🙂 注意,这里设置的回调地址,稍后我们会在「4.2 搭建资源服务器」中实现。

 

4.2 搭建资源服务器

复制lab-68-demo02-resource-server 项目,主要是提供回调地址。如下图所示:

 

 

@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 设置 /login 无需权限访问
                .antMatchers("/login").permitAll()
                //设置/callback 无需权限访问
                .antMatchers("/callback").permitAll()
                //设置/callback 无需权限访问
                .antMatchers("/callback02").permitAll()
                // 设置其它请求,需要认证后访问
                .anyRequest().authenticated()
        ;
    }

}

  

@RestController
@RequestMapping("/")
public class Callback02Controller {

    @GetMapping("/callback02")
    public String login() {
        return "假装这里有一个页面";
    }

}

 

① 新建 Callback02Controller 类,提供 /callback02 回调地址。代码如下:

@RestController
@RequestMapping("/")
public class Callback02Controller {

    @GetMapping("/callback02")
    public String login() {
        return "假装这里有一个页面";
    }

}

  友情提示:考虑到暂时不想做页面,所以这里先假装一下,嘿嘿。

② 在 OAuth2ResourceServerConfig 配置类中,设置 /callback02 回调地址无需权限验证,不然回调都跳转不过来哈。

 

 

 

 

 

4.3 简单测试

执行 AuthorizationServerApplication 启动授权服务器。
执行 ResourceServerApplication 启动资源服务器。

① 使用浏览器,访问 http://127.0.0.1:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://127.0.0.1:9090/callback02&response_type=token&scope=read_userinfo 地址,获取授权。请求参数说明如下:

  

  • client_id 参数,必传,为我们在 OAuth2AuthorizationServer 中配置的 Client 的编号。
  • redirect_uri 参数,可选,回调地址。当然,如果 client_id 对应的 Client 未配置 redirectUris 属性,会报错。
  • response_type 参数,必传,返回结果为 token 访问令牌
  • scope 参数,可选,申请授权的 Scope 。如果多个,使用逗号分隔。
  • state 参数,可选,表示客户端的当前状态,可以指定任意值,授权服务器会原封不动地返回这个值。

 

友情提示:state 参数,未在上述 URL 中体现出来。

 

因为我们并未登录授权服务器,所以被拦截跳转到登录界面。如下图所示:

 

 

② 输入用户的账号密码「yunai/1024」进行登录。登录完成后,进入授权界面。如下图所示:

  旁白君:和我们日常使用的腾讯 QQ、微信、微博等等三方登录,是一模一样的,除了丑了点,嘿嘿~

 

 

 

 

 

 

 

③ 选择 scope.read_userinfo 为 Approve 允许,点击「Authorize」按钮,完成授权操作。浏览器自动重定向到 Redirection URI 地址,并且在 URI 上的 Hash 部分可以看到 access_token 访问令牌。如下图所示:

 

 

 

 

 

 

后续,可以通过编写 Javascript 脚本的代码,获取 URI 上的 Hash 部分的访问令牌。

 

posted on 2021-01-18 09:39  qiuxuhui  阅读(1053)  评论(0编辑  收藏  举报