A 抖音APP
B 微信APP
C 微信授權中心
1授權碼(authorization-code):
A前端跳轉C授權地址,授權中心喚醒B登錄后授權,跳轉指定的重定向地址(一般就是A)攜帶一個code,A后端再用client_secret、code獲取token 最最主流的應用模式
a.
http://127.0.0.1:8081/oauth/authorize?response_type=code&client_id=test&redirect_uri=http://127.0.0.1:8082/test&scope=read
b.
http://127.0.0.1:8082/test?code=drQ9y6
c.
http://127.0.0.1:8081/oauth/token?client_id=test&client_secret=test&grant_type=authorization_code&code=CGIFwy&redirect_uri=http://127.0.0.1:8082/test
2隱藏式(implicit):
A前端跳轉C授權地址,授權中心喚醒B登錄后授權,直接跳轉指定的重定向地址(一般就是A) #號攜帶token 適合純前端應用
http://127.0.0.1:8081/oauth/authorize?response_type=token&client_id=test&redirect_uri=http://127.0.0.1:8082/test&scope=read
3密碼式(password):
A前端直接要求用戶把登錄賬號密碼填充,然后請求C拿到token 非常不安全,適合高可信任的三方比如微服務網關zuul-gataway等
http://127.0.0.1:8081/oauth/token?grant_type=password&username=admin&password=admin&client_id=test&client_secret=test
4.客戶端憑證(client credentials):
明顯可以看出整個過程不涉及用戶信息,這種方式給出的令牌,是針對第三方應用的,而不是針對用戶的,即有可能多個用戶共享同一個令牌。
http://127.0.0.1:8081/oauth/token?grant_type=client_credentials&client_id=test&client_secret=test
實測tips
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
較新的版本需要注意授權服務器需要配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.requestMatchers().anyRequest()
.and()
.authorizeRequests()
.antMatchers("/oauth/**","/oauth/authorize").authenticated();
http.formLogin();
} authenticated 而不是 permitAll
否則提示
{"code":500,"msg":"User must be authenticated with Spring Security before authorization can be completed.","data":null,"timestamp":1603527083994}
同時,假如要在授權服務上做資源服務配置,
@EnableWebSecurity
@Order(2)
@EnableResourceServer
@Order(6)
即前者初始化要優先
否則提示
<oauth>
<error_description>Full authentication is required to access this resource</error_description>
<error>unauthorized</error>
</oauth>
參考文檔
http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
https://blog.csdn.net/qq_34997906/article/details/89609297
后續測試方向
1.微服務整合,資源服務配置,打算網關就做純網關路由,授權中心不和用戶資源服務做關聯,甚至可以不注冊到eureka
2.權限范圍測試及各個模式異同
2020-10-28
完成微服務整合以后我們在資源服務上面開啟安全注解,這樣我們就能愉快的使用注解來細顆粒的控制權限了
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
客戶端方式 client authorities以client表的authorities字段為准
授權碼、隱藏式、密碼登陸模式 authorities以user對應的role表為准
@GetMapping("/helloUser")
@Secured({"ROLE_normal","ROLE_admin"})
public String helloUser() {
return "hello,user";
}
說明:擁有normal或者admin角色的用戶都可以方法helloUser()方法。另外需要注意的是這里匹配的字符串需要添加前綴“ROLE_“。如果我們要求,只有同時擁有admin & noremal的用戶才能方法helloUser()方法,這時候@Secured就無能為力了。

我在申請token的時候指定read update
此時如果資源服務器的scope要求write或者create的scope權限就無權訪問了。
3.自定義登錄授權
增2020-11-03
經過實踐查閱認證自定義登錄的概念有兩類,第一種是針對Oauth四種模式的擴展,即獲取token的擴展,第二種是針對授權碼模式和隱藏模式在跳轉認證服務時登錄認證時的自定義擴展,即spring security的登錄擴展。兩種都能集成短信、社交、掃碼、用戶密碼的擴展,前者對調用者來說每次都要改調用方式,而后者授權流程不變,只是在認證服務的登錄頁面提供多元登錄操作,只需要服務方去集成,調用者不需要做任何調整。說的有點抽象哈,請看下圖。
a.縱向擴展比較簡單,繼承AbstractTokenGranter重寫getOAuth2Authentication方法,然后將新的授權方法塞入。
效果如下
b.橫向擴展,需要自定義登陸頁面和授權頁面(后期接入許多認證方式都要加對應前端的東西),指定spring security的登陸頁面地址和UsernamePasswordAuthenticationFilter的目標過濾地址,如果新增擴展自定義的過濾器需要注釋否則會走再經過上面提到spring security的UsernamePasswordAuthenticationFilter。還要再指定經過過濾器以后跳轉的授權頁地址替換默認的“oauth/comfirm_access”。
然后校驗的核心就是MyUsernamePasswordAuthenticationFilter自定義過濾器和MyAuthenticationManager自定義的認證類,然后加入配置
這樣授權碼和隱藏模式在登陸的時候可以自定義我們的規則,成功后點擊授權就可以發放code或者token了。
2021-01-29
嘗試將oauth服務接入eureka集群,gateway過濾認證且允許傳遞header。oauth自定義接口測試正常。前端通過gateway順利獲取到token。
再嘗試經過dateway授權碼模式獲取code時發現域名地址出現了變化。這里就涉及到eureka注冊服務的ip和主機名策略。
eureka:
instance:
prefer-ip-address: true
ip-address: localhost #為了讓授權碼模式跳轉在同一個域名 配置成和gateway同入口的域名
因為新老服務的關系,eureka client注冊存在差異。老版本默認ip注冊,新版本默認主機名注冊。導致gateway ip域名請求時的session在oauth主機名下跳轉登陸頁面獲取不到session
導致報錯404.把oauth的實例改成和gateway同一個域名ip可解決。