Oauth2是个什么东西?

简介: 在之前的项目中只用到了SpringSecurity,后来发现公司的架构中有Oauth2,虽然自己在业务中没有过接触,但是觉得还是需要去了解一下,因此就有了这篇博客。本博客会从概念和简单的应用出发,讲解Oauth2的理论及实践,不涉及数据库等操作。

听说微信搜索《Java鱼仔》会变更强!


本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看


(一)前言


在之前的项目中只用到了SpringSecurity,后来发现公司的架构中有Oauth2,虽然自己在业务中没有过接触,但是觉得还是需要去了解一下,因此就有了这篇博客。本博客会从概念和简单的应用出发,讲解Oauth2的理论及实践,不涉及数据库等操作。


(二)什么是OAuth2


OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。


OAuth2协议包含几种角色:Client(客户端)、Resource Owner(资源拥有者)、Authorization Server(认证服务器)、Resource Server(资源服务器)。


网络异常,图片无法展示
|


上面这副图很详细地描述了OAuth2协议的运行原理:


A:用户打开一个客户端,客户端发送请求给资源的拥有者


B:资源拥有者返回一个需要授权的结果


C:用户在客户端上进行授权,授权信息发送到认证服务器


D:认证服务器认证完成后返回令牌


E:客户端通过令牌去访问资源服务器


F:资源服务器返回相应的资源、

以某个网站使用微信第三方登陆为例:


A:用户通过客户端打开某网站


B:某网站返回需要第三方登陆的信息


C:用户通过扫码在客户端同意登陆


D:认证服务器返回登陆成功后的token给客户端


E:客户端拿着token访问资源服务器


F:资源服务器接收token返回相应的资源


(三)OAuth2的应用场景


微信第三方就是OAuth2的应用场景之一。


我们在使用微信第三方登陆时,都需要先向微信申请到AppID和AppKey,然后拿着id和key去调用授权接口。


一般情况下大部分公司会将Oauth2应用在统一的认证中心,供第三方服务去访问他们的某些资源。


网络异常,图片无法展示
|


(四)OAuth2协议的四种模式


4.1 授权码模式 authorization_code


最常用的模式,也是上面所讲的模式,根据请求获取token,用token来访问资源。因为不涉及用户名和密码的泄漏,因此更加安全。


4.2 密码形式  password


传递用户名和密码的方式,不安全。


4.3 简化模式 implicit


不通过授权码,直接向认证系统要token。用到的场景很少。


4.4 客户端模式 client_credentials


客户端通过自己的名义向认证服务器获取授权,这种场景也很少见,比如一台只有一台硬件可以访问某个系统,可以理解为客户端模式。


(五)OAuth2认证服务器的实现


OAuth2只是一种协议,spring-security-oauth2是该协议的一种实现方式。接下来就通过spring-security-oauth2来实现认证授权。


5.1 引入依赖


首先引入项目中必要的依赖包


<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.1.5.RELEASE</version></dependency>

5.2 SpringSecurity配置


如果使用spring-security-oauth2,在获取oauth2的授权之前,必须要先获取SpringSecurity的授权,因此我们先配置SpringSecurity:


@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter {
@Overrideprotectedvoidconfigure(AuthenticationManagerBuilderauth) throwsException {
auth.inMemoryAuthentication()
                .passwordEncoder(newBCryptPasswordEncoder())
                .withUser("root")
                .password(newBCryptPasswordEncoder().encode("123456"))
                .authorities("/*");
    }
@Overrideprotectedvoidconfigure(HttpSecurityhttp) throwsException {
http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic()
                .and()
                .csrf().disable();
    }
}


以上是最基本的SpringSecurity配置类,通过内存中设定的用户名root和密码123456进行登陆。


5.3 OAuth授权配置


AuthorizationServer配置的是一个认证服务器,当传入的条件满足配置时,就会在回调接口中带上对应的code值。下面的代码中主要配置了几个重要的参数,已经写在注释中。


@Component@EnableAuthorizationServerpublicclassAuthorizationConfigextendsAuthorizationServerConfigurerAdapter{
@AutowiredprivateBCryptPasswordEncoderbCryptPasswordEncoder;
@Overridepublicvoidconfigure(AuthorizationServerSecurityConfigurersecurity) throwsException {
//开启允许表单认证security.allowFormAuthenticationForClients()
                .checkTokenAccess("permitAll()");
    }
@Overridepublicvoidconfigure(ClientDetailsServiceConfigurerclients) throwsException {
clients.inMemory()
//client_id                .withClient("javayz")
//secret                .secret(bCryptPasswordEncoder.encode("my_secret"))
//授权模式                .authorizedGrantTypes("authorization_code")
//作用域,也就是权限范围                .scopes("all")
//资源的ID                .resourceIds("my_resource")
//回调地址                .redirectUris("http://localhost:8080/callback");
    }
@BeanpublicBCryptPasswordEncoderbCryptPasswordEncoder(){
returnnewBCryptPasswordEncoder();
    }
}

5.4 获取token方式


首先第一步,访问认证接口:


http://localhost:8080/oauth/authorize?client_id=javayz&response_type=code


第一次访问时,由于SpringSecurity的拦截,需要输入用户名和密码,我这里由于都是写在内存中的,因此输入root和123456即可。


网络异常,图片无法展示
|


输入用户名和密码之后,oauth会让你选择是否授权,这一步可以理解为微信第三方登陆时,微信扫码后在手机上点击授权。


授权成功之后,会跳转到回调接口中,并且带上一个code值。


http://localhost:8080/callback?code=KGNujV


接着我们要拿上这些code值去获取token:


网络异常,图片无法展示
|


当所有的参数都填写正确的情况下,就可以拿到access_token


由于在上面的代码中,我们开启了允许表单认证,因此可以通过接口判断token是否有效:


网络异常,图片无法展示
|


(六)Oauth2资源服务器的实现


写了认证后就需要写一个资源服务器进行验证,新建一个资源项目,启动的端口要和认证服务不同,编写资源服务器配置类:


@Configuration@EnableResourceServerpublicclassResourceConfigextendsResourceServerConfigurerAdapter {
privatestaticStringClientId="javayz";
privatestaticStringSecurity="my_secret";
@AutowiredprivateBCryptPasswordEncoderbCryptPasswordEncoder;
//token校验@BeanpublicRemoteTokenServicesremoteTokenServices(){
RemoteTokenServicestokenServices=newRemoteTokenServices();
tokenServices.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
tokenServices.setClientId(ClientId);
tokenServices.setClientSecret(Security);
returntokenServices;
    }
@Overridepublicvoidconfigure(HttpSecurityhttp) throwsException {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
http.authorizeRequests().anyRequest().authenticated();
    }
@Overridepublicvoidconfigure(ResourceServerSecurityConfigurerresources) throwsException {
resources.resourceId("my_resource").stateless(true);
    }
@BeanpublicBCryptPasswordEncoderbCryptPasswordEncoder(){
returnnewBCryptPasswordEncoder();
    }
}

这段代码的核心是remoteTokenServices,这里需要定义token校验的地址,以及对应的client和secret。


接着写一个接口用来测试:

@RestControllerpublicclassTestController {
@GetMapping("/test")
publicStringtest(){
return"测试接口";
    }
}

由于在配置类中设置了所有请求都需要认证,所以当我们直接访问时,会提示无权限:


网络异常,图片无法展示
|


这个时候需要将上面生成的token放入认证信息中,有两种方式,第一种是Postman在Authorization中设置Bearer token


网络异常,图片无法展示
|


第二种方式是在请求头header中设置认证,注意token的前缀


网络异常,图片无法展示
|


(七)总结


通过这篇博客,你应该知道了Oauth2是个什么东西,也可以在项目自己的项目中尝试着用一下。如果是公司层面的使用,还需要考虑其他的一些问题,比如用户信息的存储方式,token的生成方式等等。我是鱼仔,我们下期再见!



相关文章
|
9月前
|
存储 安全 Java
OAuth2.0
OAuth2.0
191 0
|
28天前
|
存储 安全 Java
|
5月前
|
JSON 安全 Cloud Native
什么是单点登录?什么又是 OAuth2.0?
什么是单点登录?什么又是 OAuth2.0?
|
8月前
|
存储 安全 数据安全/隐私保护
OAuth2.0与OAuth1.0你了解了吗?
OAuth2.0与OAuth1.0你了解了吗?
|
10月前
|
存储 JavaScript 前端开发
带你全面了解 OAuth2.0
最开始接触 OAuth2.0 的时候,经常将它和 SSO单点登录搞混。后来因为工作需要,在项目中实现了一套SSO,通过对SSO的逐渐了解,也把它和OAuth2.0区分开了。所以当时自己也整理了一篇文章《SSO单点登录原理及实现方式》 最近需要经常和各大电商平台进行对接,所以又和OAuth2.0重逢了。因此这里再次对OAuth2.0的原理及实现方式进行一个梳理,希望通过这套教程能够帮到大家。对于技术类的文章,这引言是有点过长了。好了下面我们进入正题。
348 0
|
10月前
|
存储 JSON 缓存
九.SpringCloud+Security+Oauth2实现微服务授权 - Oauth2&JWT的认识
SpringCloud+Security+Oauth2实现微服务授权 - Oauth2&JWT的认识
|
11月前
|
安全 JavaScript 前端开发
详解OAuth2.0
1.概述 OAUTH,Open Authorization,开放授权协议,为用户资源的授权提供了一个安全的、开放而又简易的标准。目的是让第三方对用户的数据只有有限访问权,而无法触及到用户的核心信息。 例如,在第三方网站上使用微信或者QQ作为账号进行登录,就是使用的oauth协议,只返回给第三方诸如用户名、头像等信息,而不会返回给第三方秘密等核心数据。 OAuth最初由Twitter的开发人员提出,后来成为了一个互联网标准,并得到了广泛应用。OAuth2.0是OAuth协议的第二个版本,是一种更加安全、可扩展、功能更加完备的授权协议。目前我们说OAuth一般指的就是OAuth 2.0。
1181 1
|
安全 应用服务中间件 API
JWT和OAuth2.0
JWT是一种认证协议,提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。SSO私钥加密token。应用端公钥解密token。 OAuth2.0是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源。
161 0
JWT和OAuth2.0
|
Java Spring
五分钟带你玩转oauth2(二十)spring security+oauth2通过EnableOAuth2Sso实现单点登录
五分钟带你玩转oauth2(二十)spring security+oauth2通过EnableOAuth2Sso实现单点登录
225 0
五分钟带你玩转oauth2(二十)spring security+oauth2通过EnableOAuth2Sso实现单点登录
|
存储 安全 Java
OAuth2.0介绍|学习笔记
快速学习 OAuth2.0介绍
94 0
OAuth2.0介绍|学习笔记