话很少说,先上图: spring
分析一波:数据库
其实无论微信或者QQ大致上都是使用这种OAuth2的基本流程:api
OAuth2 在服务提供者上可分为两类:安全
@Configuration
@EnableAuthorizationServer
public class CustomAuthenticationServerConfig extends AuthorizationServerConfigurerAdapter
复制代码
@Configuration
@EnableResourceServer
public class CustomResourceServerConfig extends ResourceServerConfigurerAdapter
复制代码
注:这二者有时候可能存在同一个应用程序中(即SOA架构)。在Spring OAuth中能够简便的将其分配到两个应用中(即微服务),并且可多个资源获取服务共享一个受权认证服务。服务器
主要的操做:微信
分析一波:
1)第一步操做:架构
注:其中client_id和client_secret都是受权服务器发送给第三方应用的,如:微信等一系列受权,在其平台上注册,获取其appid和secret一样道理(我的理解为帐号密码)。并发
既然是帐号秘密,总不能以get请求,也太不安全了。所以,OAuth2要求该请求必须是POST请求,同时,还必须时HTTPS服务,以此保证获取到的安全凭证(Access Token)的安全性。app
2)第二步操做:框架
3)第三步操做:
主要的操做:
spring OAuth2中,咱们配置一个受权认证服务,咱们最主要有如下三点:
spring中有三个配置与这三点一一对应:
除了上面说到的client_id和client_secret,还须要一些服务附带一些受权认证参数。
1).Grant Type
其实OAuth2不只提供受权码(code)这种格式受权方式,还提供几个其余类型。其中用Grant Type表明当前受权的类型。 Grant Type包括:
2).scope
其实受权赋予第三方用户能够在资源服务器获取资源,常常就是调取Api请求附带令牌,然而调取api有增删查改等功能,而scopes的值就是all(所有权限),read,write等权限。就是第三方访问资源的一个权限,访问范围。
3).accessTokenValiditySeconds
还能够设置accessTokenValiditySeconds属性来设置Access Token的存活时间。
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("catalpaFlat")
.secret("catalpaFlat-secret")
.accessTokenValiditySeconds(7200)
.authorizedGrantTypes("refresh_token","password")
.scopes("all");
}
复制代码
AccessToken的存在乎义:
1).AuthorizationServerTokenServices
AuthorizationServerTokenServices 提供了对AccessToken的相关操做建立、刷新、获取。
public interface AuthorizationServerTokenServices {
OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException;
OAuth2AccessToken refreshAccessToken(String refreshToken, TokenRequest tokenRequest)
throws AuthenticationException;
OAuth2AccessToken getAccessToken(OAuth2Authentication authentication);
}
复制代码
2).DefaultTokenServices
AuthorizationServerTokenServices居然能够操做AccessToken,那么OAuth2就默认为咱们提供了一个默认的DefaultTokenServices。包含了一些有用实现,可使用它来修改令牌的格式和令牌的存储等,可是生成的token是随机数。
3).TokenStore
建立AccessToken完以后,除了发放给第三方,确定还得保存起来,才可使用。所以,TokenStore为咱们完成这一操做,将令牌(AccessToken)保存或持久化。
TokenStore也有一个默认的实现类InMemoryTokenStore,从名字就知道是经过保存到内存进而实现保存Access Token。 TokenStore的实现有多种类型,能够根据业务需求更改Access Token的保存类型:
4).JWT Token
想使用jwt令牌,须要在受权服务中配置JwtTokenStore。以前说了,jwt将一些信息数据编码后存放在令牌,那么其实在传输的时候是很不安全的,因此Spring OAuth2提供了JwtAccessTokenConverter来怼令牌进行编码和解码。适用JwtAccessTokenConverter能够自定义秘签(SigningKey)。SigningKey用处就是在受权认证服务器生成进行签名编码,在资源获取服务器根据SigningKey解码校验。
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey("CatalpaFlat")
复制代码
受权认证是使用AuthorizationEndpoint这个端点来进行控制,通常使用AuthorizationServerEndpointsConfigurer 来进行配置。
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {}
复制代码
1).端点(endpoints)的相关属性配置:
2).端点(endpoints)的受权url: 要受权认证,确定得由url请求,才能够传输。所以OAuth2提供了配置受权端点的URL。
AuthorizationServerEndpointsConfigurer ,仍是这个配置对象进行配置,其中由一个pathMapping()方法进行配置受权端点URL路径,默认提供了两个参数defaultPath和customPath:
public AuthorizationServerEndpointsConfigurer pathMapping(String defaultPath, String customPath) {
this.patternMap.put(defaultPath, customPath);
return this;
}
复制代码
pathMapping的defaultPath有:
注:pathMapping的两个参数都将以 "/" 字符为开始的字符串
实际上咱们上面说到的端点,其实能够当作Controller,用于返回不一样端点的响应内容。
受权服务的错误信息是使用标准的Spring MVC来进行处理的,也就是 @ExceptionHandler 注解的端点方法,咱们能够提供一个 WebResponseExceptionTranslator 对象。最好的方式是改变响应的内容而不是直接进行渲染。
资源服务器,其实就是存放一些受令牌保护的资源,只有令牌而且有效正确才能获取到资源。 内部是经过Spring OAuth2的Spring Security Authentication filter 的过滤链来进行保护。
咱们能够继承ResourceServerConfigurerAdapter,来使用 ResourceServerSecurityConfigurer进行相关配置。
public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}
复制代码
ResourceServerTokenServices 是组成受权服务的另外一半。
1).如果资源服务器和受权服务在同一个应用,可使用DefaultTokenServices
2).如果分离的。ResourceServerTokenServices必须知道令牌的如何解码。
ResourceServerTokenServices解析令牌的方法:
注:受权认证服务须要把/oauth/check_toke暴露出来,而且附带上权限访问。
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')")
.checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
复制代码
(~ ̄▽ ̄)~未完待续... ...