【Spring Security + OAuth2 + JWT入门到实战】17. oauth2授权码模式

痴心易碎 提交于 2020-03-17 13:40:10

某厂面试归来,发现自己落伍了!>>>

简介

https://gitee.com/hekang_admin/spring-security

做oauth2之前项目架构给调整了一下,spring-boot更新到最新版本,真是一代版本一代神两天遇到很多问题这里一一解决。

<spring-boot.version>2.2.4.RELEASE</spring-boot.version> 
<spring-cloud.version>Hoxton.SR2</spring-cloud.version> 
<security.oauth.version>2.3.6.RELEASE</security.oauth.version>

授权码模式

授权码模式是最能体现OAuth2协议,最严格,流程最完整的授权模式,流程如下所示:

A. 客户端将用户导向认证服务器;

B. 用户决定是否给客户端授权;

C. 同意授权后,认证服务器将用户导向客户端提供的URL,并附上授权码;

D. 客户端通过重定向URL和授权码到认证服务器换取令牌;

E. 校验无误后发放令牌。

其中A步骤,客户端申请认证的URI,包含以下参数:

  1. response_type:表示授权类型,必选项,此处的值固定为”code”,标识授权码模式

  2. client_id:表示客户端的ID,必选项

  3. redirect_uri:表示重定向URI,可选项

  4. scope:表示申请的权限范围,可选项

  5. state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:

  1. grant_type:表示使用的授权模式,必选项,此处的值固定为”authorization_code”。

  2. code:表示上一步获得的授权码,必选项。

  3. redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。

  4. client_id:表示客户端ID,必选项。

认证服务器

app项目根目录创建HkAuthorizationServerConfig类

package com.spring.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;

/**
 * 认证服务器
 */
@Configuration
@EnableAuthorizationServer
public class HkAuthorizationServerConfig{

}

启动项目控制台输出:

访问:http://127.0.0.1:8080/oauth/authorize?response_type=code&client_id=6edc003b-bf47-4b1b-a4c1-13a63b0df14b&redirect_uri=http://example.com&scope=all

关于参数上面有详细解释

错误一:

错误原因:用户必须通过Spring Security的身份验证才能访问/oauth/authorize

User must be authenticated with Spring Security before authorization can be completed.

解决办法配置不需要身份验证:

同目录创建WebSecurityConfigurer认证相关配置类

package com.spring.security;


import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * 认证相关配置
 */
@Primary
@Order(90)
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http
                .requestMatchers().antMatchers("/oauth/**", "/login/**", "/logout/**", "/token/**", "/actuator/**")
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated()
                .and()
                .formLogin().permitAll(); //新增login form支持用户登录及授权
    }

}

启动项目再次访问,记得修改client_id为本次启动控制台的输出client-id:

输入admin,123456   这个是之前MyUserDetailsService里面配置的:

错误二:

错误原因:意思是说我们没有配置redirect_uri,实际上我们是配置了的为什么还报这错,是因为像QQ互联的回调地址是需要配置的我们这

个也需要配置到白名单

error="invalid_request", error_description="At least one redirect_uri must be registered with the client."

解决办法,配置到白名单:

security:
  oauth2:
    client:
      registered-redirect-uri: http://example.com
      client-id: myhk
      client-secret: myhk123

重启项目访问,输入账号密码:

Approve:同意授权

Deny:拒绝

选择Approve点Authoriez:

code已经获取现在去获取token

获取令牌Token

使用postman发送如下请求POST请求http://127.0.0.1:8080/oauth/token

这里要填的参数和上面介绍的授权码模式D步骤介绍的一致。grant_type固定填authorization_code,code为上一步获取到的授权码,client_id和redirect_uri必须和我们上面定义的一致。

除了这几个参数外,我们还需要在请求头中填写:

key为Authorization,value为Basic加上client_id:client_secret经过base64加密后的值(可以使用http://tool.chinaz.com/Tools/Base64.aspx):

参数填写无误后,点击发送便可以获取到令牌Token:

一个授权码只能换一次令牌,如果再次点击postman的发送按钮,将返回:

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!