实现服务提供商,就是要实现认证服务器、资源服务器。

现在做的都是app的东西,所以在app项目写代码

 认证服务器:

新建 ImoocAuthenticationServerConfig 类,@EnableAuthorizationServer 注解就说明该项目是一个 认证服务器:

  1. @Configuration
  2. @EnableAuthorizationServer //这个注解就是实现了一个认证服务器
  3. public class ImoocAuthenticationServerConfig {
  4.  
  5. }

OAuth协议流程:

实现授权码模式:

  服务提供商需要提供两个服务:

  1,用户调过来点击授权的地址 (如qq微信登录的授权页)

  2,点完授权后带着授权码换取access_token的地址(对用户不可见)

加上了@EnableAuthorizationServer 注解的项目,启动后控制台会打印如下的信息:

/oauth/authorize 就是让用户授权的地址,启动应用,访问/oauth/authorize,需要一些参数:

  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

其中client_id 在启动应用时控制台会打印:

实现授权码模式第一步:获取授权码

拼接访问串:

localhost:8080/oauth/authorize?response_type=code&client_id=f835525e-cbdb-4609-8dae-fbf5ef2b2484&redirect_uri=http://example.com&scope=all

我们的应用相当于 服务提供商,它需要知道三件事

1,哪个应用在请求授权 :通过client_id,第三方应用在应用服务器上注册时分配的id,通过client_id 识别是哪个应用在请求授权

2,在请求哪个用户在给你授权:上图中的form表单就是确认系统中的哪个用户在授权

3,赋予哪些权限:scope参数标识赋予哪些权限

demo项目引用app项目,启动的都是demo项目,

demo项目里有处理认证的类MyUserDetailsService 类,用户名没有处理,只要密码是123456就行

  1. private SocialUserDetails buildUser(String userId) {
  2. String password = passwordEncoder.encode("123456");
  3. System.err.println("加密后密码: "+password);
  4. //参数:用户名|密码|是否启用|账户是否过期|密码是否过期|账户是否锁定|权限集合
  5. return new SocialUser(userId,password,true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
  6. }

在认证表单输入密码123456,用户名随便,点击登录,403 拒绝访问

原因是默认情况下,认证服务器上请求需要有ROLE_USER的角色才能访问,在MyUserDetailsService 里加上:

  1. private SocialUserDetails buildUser(String userId) {
  2. String password = passwordEncoder.encode("123456");
  3. System.err.println("加密后密码: "+password);
  4. //参数:用户名|密码|是否启用|账户是否过期|密码是否过期|账户是否锁定|权限集合
  5. return new SocialUser(userId,password,true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER"));
  6. }

把client_id 配置到application.properties 配置文件:

security.oauth2.client.clientId = imooc
#注意clientSecret 大写
security.oauth2.client.clientSecret = imoocsecret

再次访问:http://localhost:8080/oauth/authorize?response_type=code&client_id=imooc&redirect_uri=http://example.com&scope=all

这个页面相当于qq登录授权页或微信登录的扫码页,询问是否同意授权,点击同意,返回到http://example.com,并携带了授权码

http://example.com/?code=lUDDeG

实现授权码模式第二步:授权码换取access_token:

此时就该拿着授权码去获取access_token了,post请求 /oauth/token ,使用Resetlet Client,在请求头里新建一个Authentication(Authorization 设置HTTP身份验证的凭证https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Authorization),用户名输入imooc,密码输入 imoocsecret

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

  • grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
  • code:表示上一步获得的授权码,必选项。
  • redirect_uri:表示重定向URI,必选项,且必须与上边步骤中的该参数值保持一致。
  • client_id:表示客户端ID,必选项。
  • client_secret:客户端密钥

完整的请求:

响应:

 
{
"access_token": "66e4e300-deb0-4bfa-a171-a6e5a34c922e",
"token_type": "bearer",
"refresh_token": "4bd03df8-f150-402f-8aee-6f16e4838b6e",
"expires_in": 43199,
"scope": "all"
}

 密码模式:

参数是用户名密码,其实是用户把在 服务提供商上的 用户名/密码 告诉了第三方,第三方拿着用户名密码去给服务提供商说用户已经授权了。

在app场景下是可用的,因为第三方是app,是公司前端,提供商是服务端,都是一伙的,不涉及安全问题

响应:

可以看到,用同一个用户名登录,响应的access_token是同一个,只要这个token还没过期。

 资源服务器:

和认证服务器类似

  1. /**
  2. * 资源服务器,和认证服务器在物理上可以在一起也可以分开
  3. * ClassName: ImoocResourceServerConfig
  4. * @Description: TODO
  5. * @author lihaoyang
  6. * @date 2018年3月13日
  7. */
  8. @Configuration
  9. @EnableResourceServer
  10. public class ImoocResourceServerConfig {
  11.  
  12. }

启动demo项目,由于没有配置token存储策略,所以生成的token都是在内存中的,在这里重新用密码模式获取一下token:

http://127.0.0.1:8080/oauth/token

{
"access_token": "864defd9-b62a-4d59-a133-9247d9dc546d",
"token_type": "bearer",
"refresh_token": "4fd9b93b-ca72-4efe-ae11-d9ac491bdf2f",
"expires_in": 43199,
"scope": "all"
}
访问http://127.0.0.1:8080/user/me 获取用户信息
  1.   @GetMapping("/me")
  2. public Object getCurrentUser(@AuthenticationPrincipal UserDetails user) {
  3. return user;
  4. }
需要在请求头里加上参数token和返回的token_type   bearer,和token用空格隔开 ,因为Authorization格式为   Authorization: <type> <credentials>

响应:

  1. {
  2. "password": null,
  3. "username": "user",
  4. "authorities":[
  5. {
  6. "authority": "ROLE_USER"
  7. },
  8. {
  9. "authority": "admin"
  10. }
  11. ],
  12. "accountNonExpired": true,
  13. "accountNonLocked": true,
  14. "credentialsNonExpired": true,
  15. "enabled": true,
  16. "userId": "user"
  17. }

通过token 获取到了用户信息。

到目前为止获取token和用token 访问服务已完成,但是都是用的OAuth标准的规范和spring security默认的实现。认证方式只能是OAuth规定的四种模式,还不能用手机验证码登录,token也是存在了内存里,是不行的。token的样式也是默认的。

下一步个性化实现,改造 用户名密码登录、短信验证码登录、第三方登录

Spring Security构建Rest服务-1201-Spring Security OAuth开发APP认证框架之实现服务提供商的更多相关文章

  1. Spring Security构建Rest服务-1300-Spring Security OAuth开发APP认证框架之JWT实现单点登录

    基于JWT实现SSO 在淘宝( https://www.taobao.com )上点击登录,已经跳到了 https://login.taobao.com,这是又一个服务器.只要在淘宝登录了,就能直接访 ...

  2. Spring Security构建Rest服务-1200-SpringSecurity OAuth开发APP认证框架

    基于服务器Session的认证方式: 前边说的用户名密码登录.短信登录.第三方登录,都是普通的登录,是基于服务器Session保存用户信息的登录方式.登录信息都是存在服务器的session(服务器的一 ...

  3. Spring Security构建Rest服务-1202-Spring Security OAuth开发APP认证框架之重构3种登录方式

    SpringSecurityOAuth核心源码解析 蓝色表示接口,绿色表示类 1,TokenEndpoint 整个入口点,相当于一个controller,不同的授权模式获取token的地址都是 /oa ...

  4. Spring Security构建Rest服务-1203-Spring Security OAuth开发APP认证框架之短信验证码登录

    浏览器模式下验证码存储策略 浏览器模式下,生成的短信验证码或者图形验证码是存在session里的,用户接收到验证码后携带过来做校验. APP模式下验证码存储策略 在app场景下里是没有cookie信息 ...

  5. Spring Security构建Rest服务-1205-Spring Security OAuth开发APP认证框架之Token处理

    token处理之二使用JWT替换默认的token JWT(Json Web Token) 特点: 1,自包含:jwt token包含有意义的信息 spring security oauth默认生成的t ...

  6. Spring Security构建Rest服务-1204-Spring Security OAuth开发APP认证框架之Token处理

    token处理之一基本参数配置 处理token时间.存储策略,客户端配置等 以前的都是spring security oauth默认的token生成策略,token默认在org.springframe ...

  7. ASP.NET Core的身份认证框架IdentityServer4--(3)令牌服务配置访问控制跟UI添加

    使用密码保护API OAuth 2.0 资源所有者密码授权允许一个客户端发送用户名和密码到IdentityServer并获得一个表示该用户的可以用于访问api的Token. 该规范建议仅对" ...

  8. spring boot:构建多模块项目(spring boot 2.3.1)

    一,为什么要使用多模块? 1,结构更清晰,方便管理    如果只是一个小项目当然没有问题,    但如果功能越增越多则管理越来越复杂,    多模块可以使项目中模块间的结构分离   2,把项目划分成多 ...

  9. Android 从硬件到应用程序:一步一步爬上去 6 -- 我写的APP测试框架层硬件服务(终点)

    创Android Applicationproject:采用Eclipse的Android插入ADT创Androidproject,project名字Gpio,创建完成后,project文件夹pack ...

随机推荐

  1. c语言中几个常见的库函数strlen、strcmp、strcat、strcpy、strncpy、memset、memcpy、memmove、mmap

    1.strlen() 1)计算给定字符串的长度,不包括’\0’在内 unsigned int strlen(const char *s) { assert(NULL != s);//如果条件不满足,则 ...

  2. SPSS-单因素方差分析(ANOVA) 案例解析

    继续以上一期的样本为例,雌性老鼠和雄性老鼠,在注射毒素后,经过一段时间,观察老鼠死亡和存活情况. 研究的问题是:老鼠在注射毒液后,死亡和存活情况,会不会跟性别有关? 样本数据如下所示: (a代表雄性老 ...

  3. 第二届普适计算和信号处理及应用国际会议论文2016年 The 2nd Conference on Pervasive Computing, Signal Processing and Applications(PCSPA, 2016)

    A New Method for Mutual Coupling Correction of Array Output Signal 一种阵列输出信号互耦校正的新方法 Research of Robu ...

  4. Resharper 修改命名空间

    1. 使用Reshared 右键->Refactor->Rename 修改所有文件的命名空间(鼠标移动到对应类的命名空间) 2.修改类库中的命名空间 包括程序集信息 右键->属性 3 ...

  5. HDU6023 Automatic Judge 2017-05-07 18:30 73人阅读 评论(0) 收藏

    Automatic Judge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  6. EJB、RMI、XMLRPC、Hessian、Thrift 、Protobuf

    Java中实现分布式的方式有:EJB.RMI.XMLRPC.Web Service.Hessian.Thrift .Protobuf.NIO(Netty.Mina) EJB 优势:可扩展性好,安全性强 ...

  7. winform 批量控件取值赋值

    以前写winform 最多写几个文本框,最近需要入录一个人员信息,那好几十个字段,一下子干蒙了,这要是一个个取值赋值都写到明天了,于是就自己写了个方法,也不是什么高大上的,就是很简单很普通很low的方 ...

  8. 先装VS2008之后,又装了2013,然后启动VS2008提示“Tools Version”有问题?

    这个网上资料一搜很多,我就是按照下面这个链接去解决的,删除 “14.0” 整个键值文件夹之后重启VS2008就好了, 注意:上面第一张图是我在网上找的08和10版本弹出的错误,我自己弹出的是提示14. ...

  9. 异常测试之Socket网络异常

    本文由作者张雨授权网易云社区发布. 前言 不知道大家在测试的过程中有没有发现关于异常测试这样一个特点: 无论是分散在功能测试中的异常用例还是规模相对较大的专项异常测试中,异常测试的用例占比虽然不大但是 ...

  10. vhosetuser 和 vhostuservlient 差异

    Open vSwitch支持的vHost-user类型 在Open vSwitch中vHost User通过socket进行通信,模式为client-server,其中server端负责创建/管理/销 ...