本文是Spring Security OAuth2学习系列文章中的第四篇;主要讲解授权码模式(AuthenticationCode)及简化模式(Implicit)的使用。
关于密码模式、客户端模式及Spring Security OAuth2的一些基础知识,请移步本博客文章清单进行查看。
授权码模式主要使用在客户端与授权、资源服务器不在同一公司的情况;在这种场景下,客户端并不是可信的,因此用户密码不能直接授予客户端。
授权码模式流程如下:
在授权码模式中,授权服务器配置与密码模式基本一致,除在客户端的authorizedGrantTypes中添加authorization_code外,其它并无不同。
具体配置参考https://blog.csdn.net/icarusliu/article/details/87968090一文;不同在于:
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("test")
.resourceIds("testResource")
.authorizedGrantTypes("password", "client_credentials", "authorization_code")
.authorities("ROLE_CLIENT")
.scopes("read", "write")
.secret("secret")
.redirectUris("http://localhost:8081/test");
}
资源服务器配置与密码模式中完全一致。
授权码模式的测试需要使用浏览器访问对应地址才成。
访问地址:
http://localhost:8080/oauth/authorize?client_id=test&client_secret=secret&state=test&response_type=code
注意,如果不带response_type的话将会报送unsupported_response_type错误。
访问后,将提示用户进行登录;登录完成后转到授权页面:
用户可以选择是否进行授权;授权成功后会跳转到指定的客户端页面中去;
客户端页面接收到code后,需要使用这个code在后台去授权服务器获取accessToken,然后再使用这个Token去访问资源服务器中的资源。
response_type也可以指定为token,此时即implicit模式,也即简化模式。
注意如果通过这种方式访问时,需要在授权服务器端上该客户端访问模式中加上implicit;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("test")
.resourceIds("testResource")
.authorizedGrantTypes("password", "client_credentials", "authorization_code", "implicit")
.authorities("ROLE_CLIENT")
.scopes("read", "write")
.secret("secret")
.redirectUris("http://localhost:8081/test");
}
否则,在浏览器中访问以下地址
http://localhost:8080/oauth/authorize?client_id=test&client_secret=secret&state=test&response_type=token
会跳转到重定向页面中并附带错误信息:
http://localhost:8081/test#error=invalid_client&error_description=Unauthorized%20grant%20type:%20implicit&state=test
添加支持后再访问时,它会跳转到以下地址(将直接获取的Token附加到链接后面然后进行调用):
http://localhost:8081/test#access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGVzdFJlc291cmNlIl0sInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXhwIjoxNTUxMzAxMjI4LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiOTZlN2FkNzAtNTJmNC00NjlmLWJiZmYtYjZhNDM2Y2ExYTQwIiwiY2xpZW50X2lkIjoidGVzdCJ9.hhobUkmOLFaXp4PNoNbPhF0FvwXQfaQZX3skbzpS9z0&token_type=bearer&state=test&expires_in=43199&scope=read%20write&jti=96e7ad70-52f4-469f-bbff-b6a436ca1a40
因此在此客户端就可以获取到Token,然后再使用这个Token去访问资源服务器资源了。