写在开篇
本改编课程基于《OAuth 2.0 Cookbook_Protect Your Web Applications using Spring Security-Packt Publishing(2017)》。这本书侧重通过一个个精简的小例子来学习,如何使用spring security和oauth2.0来保护你的资源,。
课程从第二章开始,在Chaptor2,我们将学习以下内容:
本节为隐式模式的用例,该模式直接运行在浏览器上(例如Javascript 应用)。本例将允许客户端以资源所有者的名义通过OAuth2.0保护的api。
Getting ready
How to do it…
接下来的步骤将指导你使用Spring Security OAuth2 搭建一个授权中心和一个资源服务器:
1.使用Spring Initializr 新建一个Springboot工程,加入web,security依赖,本例使用的springboot版本为“1.5.4.RELEASE”。
2.打开pom.xml,加入以下依赖:
org.springframework.security.oauth
spring-security-oauth2
3.打开application.properties文件,输入:
security.user.name=adolfo
security.user.password=123
4.新建UserProfile类与UserController类,内容与《学习3》中一致,这个是获取资源的接口。
5.新建OAuth2ResourceServer类,内容与《学习3》中一致,这个是资源管理器配置。
6.新建OAuth2AuthorizationServer类,即配置授权中心,注意其中的不同之处:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter{
@Override
public void configure(ClientDetailsServiceConfigurer clients)throws Exception{
clients.inMemory()
.withClient("clientapp")
.secret("123456")
.redirectUris("http://localhost:9000/callback")
.authorizedGrantTypes("implicit")
.accessTokenValiditySeconds(120)
.scopes("read_profile","read_contacts");
}
}
7.至此,我们已经完成了所有步骤,可以看出,在spring security框架中,授权码模式和隐式模式的构建模式很相似,仅仅在于配置授权中心时,设置不同的authorizedGrantTypes。
How it works…
当我们使用@EnableAuthorizationServer 和@EnableResourceServer 这两个标签时,意味着,我们将Oauth 2.0的 endpoint加入到我们的项目中,与上一节的不同之处在于,我们使用了不同的授权模式,因此验证流程有一点点不同。此外,我们还必须知道的是,我们无需再往/oauth/token 发请求,因为我们现在是隐式模式。
接下来,我们来运行这个项目
1.首先,我们往授权中心发送如下请求:
http://localhost:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://localhost:9000/callback&response_type=token&scope=read_profile&state=xyz
注意,此时response_type 的参数值为token ,而不是之前的code。并且,我们的url没有使用编码,此处是作为教学用例所以省略,但在实际生产项目中,请记住要对所有参数进行编码。
当请求到达授权中心的endPoint后,授权中心将会要求资源所有者做身份验证
输入用户名密码后,将会跳到授权页面:
2.选择所需的scope ,点击Authorize ,你将跳回到之前设置的redirect uri,正如你所见,回调路径携带了我们需要的access token和之前输入的state
http://localhost:9000/callback#access_token=a68fce80-522f-43ee-85d4-6705c34 e555c&token_type=bearer&state=xyz&expires_in=119
除了access token和state,我们还得到了两个参数:token_type和expires_in。在上一节,使用授权码模式时,也获得了这些返回参数。重要的是要记住,隐式授权类型不允许按照OAuth2规范发布刷新令牌(refresh token)。这种行为是有必要的,它要求在使用运行在浏览器中的程序时,用户必须在场,这样可以在任何需要的时候,给第三方应用授权。
除此之外,授权中心有充分的能力来识别用户的session,避免重复要求资源中心来对客户端进行验证和授权。
隐式模式不允许发布refresh token的另一个理由是,隐式模式是应用在那些无法保护机密数据的公共应用,而这是refresh token要做的。
3.现在我们可以从api/profile 这个endpoint取回用户资料了,就像我们在上一节所做的,记住需携带access token,具体参见上一节。
There's more…
当使用隐式模式时,第三方应用始终需要通过重定向URI来注册,这样能确保不会将access token传给不需要验证的客户端。如果不这样做,一些心怀不轨的用户可能先注册一个应用,然后试图让其他的应用来顶替,接收这个access token,这样可能导致灾难性的结果。