springSecurityOAuth2

前后端分离的场景,会采用基于token的认证方式,就需要用到spring security oauth2,是spring-security框架的一个子模块

IMG_256

IMG_256

IMG_256

作为一个服务提供商的角色,需要两大块内容,一个是认证服务器,一个是资源服务器,所谓认证服务器其实可以简单理解为就是生成token的逻辑,所谓资源服务器,就是我们的业务代码。这二者只是一个逻辑上的概念,并不是物理上独立的两台服务器。

角色

客户端

客户端本身不存储任何的资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:Andriod客户端、IOS客户端、浏览器端、微信客户端

资源拥有者

通常为用户,也可以是应用程序,既该资源的拥有者。

授权服务器(认证服务器)

来对资源拥有者的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有者授权后可访问。

常用术语

  1. 客户凭证 (client Credentials): 客户端的ClientID和密码用于认证客户。
  2. 令牌(tokens): 授权服务器在接受到用户的请求后,颁发的访问令牌
  3. 作用域(scopes): 客户请求访问令牌时,由资源拥有者额外制定的细分权限

常用令牌

  • 授权码:仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌
  • 访问令牌:用于代表一个用户或服务直接去访问受保护的资源
  • 刷新令牌:用于去授权服务器获取一个刷新访问令牌
  • BearerToken :不管谁拿到Token都可以访问资源,类似现金
  • Proof of Possession (Pop) Token:可以校验 client 是否对Token有明确的拥有权

认证服务器

app的认证服务器配置类

  @EnableAuthorizationServer注解表示为认证服务器,demo引入了app,所以demo现为认证服务器启动时会创建client-id和client-secret

    security.oauth2.client.client-id = 6abb1077-3205-482f-8e86-bcc757766a8a

    security.oauth2.client.client-secret = cbd1f3ae-13ac-40fe-89f0-e5113fc04e3c

为了避免每次重启输入的clientid的繁琐,在配置文件中配置一下clientid和clientsecret

授权码模式

获取授权码

访问 url=/oauth/authorize

它后面需要参数:

  http://localhost/oauth/authorize?response_type=code&client_id=bdee6824-1769-4787-b3df-3fcc90756885&redirect_uri=http://www.example.com&scope=all 

  response_type=code 必填value:code

访问出现以下报错信息

IMG_256

security5+ 认证默认为表单了也就是http.formLogin(),创建AppSecurityConfig

@Configuration
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
  @Autowired
  private UserDetailsService userDetailsService;
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    //security5+ 认证默认为表单了也就是http.formLogin()
    http.httpBasic();
  }
}

认证服务器需要知道三件事

  1. 哪个应用在请求授权

    通过client_id确认是哪个应用,每个应用注册时分配一个唯一的client_id

  2. 请求我的哪个用户授权

    用户登陆输入的用户名和密码,UserDetailsServiceImpl

  3. 给你什么授权

    请求什么样的权限,是通过scope参数带入,scope参数是认证服务器自定义的输入用户名和密码,走UserDetailsServiceImpl.loadUserByUsername方法

 

再访问出现以下报错信息

需要配置授权码回调域

security:
   oauth2:
      client:
        client-id: wangzhilei
        client-secret: 123456
      registered-redirect-uri: http://www.example.com

再次访问

这个页面类似QQ,微信扫码的页面

同意授权后返回授权码:https://www.example.com/?code=2vaBOy

拿到这个授权码以后我们就可以请求token了

根据授权码获取token
  1. 用postman完成,指定请求路径为/oauth/token,POST请求
  2. Authonzation

具体设置:

  TYPE: Basic Auth

    username: client_id

    password: client_secret

  Body

    form-data

      grant_type: authorization_code

      code: 2vaBOy  //获取的授权码

      client_id: wangzhilei

      scope: all

      redirect_uri: http://www.example.com

隐式授权码模式

不同点:

  1. 参数response_type=token
  2. 返回token,不是授权码,少一步

请求url : http://localhost/oauth/authorize?response_type=token&client_id=wangzhilei&redirect_uri=http://www.example.com&scope=all 

返回:http://www.example.com/#access_token=06ee7434-9499-4766-8502-5d858f3d53c4&token_type=bearer&expires_in=41970

密码模式

参数和授权码不同 这种模式适用于公司内相互信任的应用之间,可以直接提供用户名密码

POST请求

获取token url: /oauth/token

Body:x-www-form-urlencoded

  grant_type: password

  scope: all

  username: jone

  password: 123456

Authorization: 与授权码获取token一样

资源服务器

资源服务配置类,@EnableResourceServer开启资源服务器

@Configuration
@EnableResourceServer
public class ResourceServerConfig {
}

请求资源

获取token后,在请求

OAuth2.0

posted @ 2024-01-01 19:51  wangzhilei  阅读(183)  评论(0编辑  收藏  举报