?單點登錄
單點登錄,英文是 Single Sign On(縮寫為 SSO)。即多個站點共用一臺認證授權服務器,用戶在站點登錄后,可以免登錄訪問其他所有站點。而且,各站點間可以通過該登錄狀態直接交互。例如:
業務邏輯的使用
鑒權:
網關鑒權 微服務
沒有 需要
鑒權 補充
CAS 是 Central Authentication Service 的縮寫 —— 中央認證服務,一種獨立開放指令協議,是 Yale 大學發起的一個企業級開源項目,旨在為 Web 應用系統提供一種可靠的 SSO 解決方案。
SSO是一種思想,而CAS只是實現這種思想的一種框架而已
CAS支持oauth2 協議
SSO是一種思想,或者說是一種解決方案,是抽象的,我們要做的就是按照它的這種思想去實現它
OAuth2是用來允許用戶授權第三方應用訪問他在另一個服務器上的資源的一種協議,它不是用來做單點登錄的,但我們可以利用它來實現單點登錄。
OAuth2
1 介紹
OAuth2是目前最流行的授權機制,用來授權第三方應用,獲取用戶數據。允許用戶授權B應用不提供帳號密碼的方式去訪問該用戶在A應用服務器上的某些特定資源。
2 oauth2.0四個角色
四個角色:
resource owner:資源所有者,這里可以理解為用戶。
client:客戶端,可以理解為一個第三方的應用程序 即微博 CSDN。
resource server:資源服務器,它存儲用戶或其它資源。
authorization server:
認證/授權服務器,它認證resource owner的身份,為 resource owner提供授權審批流程,并最終頒發授權令牌(Access Token)。
認證服務器只有一個 sysauth
資源服務器 訂單 商品 支付
認證的流程
3 四種授權模式
* authorization_code 授權碼模式
* password 密碼模式
* implicit 簡單模式
* client_credentials 客戶端模式
* refresh_token 這個不是一種模式 是支持刷新令牌的意思
1 授權碼模式
一般用于提供給第三方使用
2 簡單模式
一般不會使用
3 密碼模式
一般僅用于系統內部使用
4 客戶端模式
一般不會使用
4 OAUTH2的spring cloud 微服務單點登錄
用戶:就是注冊的用戶
客戶端:就是我們的前端項目
授權服務器:我們可以專門在后臺創建一個專門管授權的微服務
資源微服務:像其他的訂單微服務,什么搜索微服務拉都可以看做用戶能夠訪問的資源
如果我們自己去用java實現OAUTH2.0標準,太麻煩了,幸好有spring-security-oauth2這個插件,就簡單多了,spring-security-oauth2是基于spring-security框架完整實現oauth2協議的框架,具有oauth2中4種模式訪問和第三方登錄等功能。
?四種模式測試
所有授權端點(EndterPoints),意思就是授權微服務啟動后 可以訪問哪些路徑
認證服務器的ip以及端口號 localhost:8500
localhost:8500/oauth/token
路徑 | 說明 |
/oauth/authoriz | 授權端點 |
/oauth/token | 令牌端點 獲取token |
/oauth/confirm_access | 用戶確認授權提交端點 |
/oauth/error | 授權服務錯誤信息端點 |
/oauth/check_token | 用于資源服務訪問的令牌解析端點 |
/oauth/token_key | 提供公有密匙的端點,如果你使用JWT(RSA)令牌的 |
5 spring cloud alibaba 使用oauth2
1 創建父項目
2 啟動nacos
3 創建授權微服務sys-auth
pom文件:
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<!--security使用的jwt-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
授權碼模式
1.配置核心的配置文件
授權的配置信息需要繼承AuthorizationServerConfigurerAdapter
將授權的客戶端的信息保存到內存里面
2.配置springsecurity的配置信息
@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin().permitAll();http.authorizeRequests().antMatchers("/userlogin","/oauth/**").permitAll();// 代表放行 "/login.html","/userlogin","/"http.authorizeRequests().anyRequest().authenticated();// csrf 方便html 文件 能夠通過http.csrf().disable();http.cors();//跨域}@Resource private BCryptPasswordEncoder passwordEncoder;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("aaa").password(passwordEncoder.encode("123456")).roles("ADMIN"); // auth.userDetailsService(userDetailsService).passwordEncoder(getPassword());}public void printJsonData(HttpServletResponse response, Result result) {try {response.setContentType("application/json;charset=utf8"); // json格式 編碼是中文ObjectMapper objectMapper = new ObjectMapper();String s = objectMapper.writeValueAsString(result);// 使用ObjectMapper將result轉化json為字符串PrintWriter writer = response.getWriter();writer.print(s);writer.flush();writer.close();}catch (Exception e){e.printStackTrace();}} }
3.訪問授權站點
?
訪問后登錄?
登錄后獲得授權碼
4.?根據授權碼生成token
localhost:8500/oauth/token?grant_type=authorization_code&code=4WXzET&client_id=admin&redirect_url=http://www.baidu.com&scope=all
登錄
獲得token
簡單模式:
修改oauth2
訪問登錄
localhost:8500/oauth/authorize?response_type=token&client_id=admin&scope=all
獲得token
客戶端模式:
登錄訪問
獲得token
密碼模式?
修改springsecurity的配置信息
修改oauth2配置信息
獲得token
不想重復的輸入第三方的用戶名和密碼放行
校驗token
jwt類型的token
加jar
dependency>
????<groupId>org.springframework.security</groupId>
????<artifactId>spring-security-jwt</artifactId>
????<version>1.1.0.RELEASE</version>
</dependency>
配置bean
使用bean
認證之后直接生成token
安全配置文件中配置認證成功之后使用第三方工具 hutool 發出post請求 ?生成token 返回客戶端
資源服務器
1.添加jar包
<dependency>
????<groupId>org.springframework.security.oauth</groupId>
????<artifactId>spring-security-oauth2</artifactId>
????<version>2.3.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure -->
<dependency>
????<groupId>org.springframework.security.oauth.boot</groupId>
????<artifactId>spring-security-oauth2-autoconfigure</artifactId>
????<version>2.3.5.RELEASE</version>
</dependency>
2.編寫controller
3.編寫bootstrap
4.添加配置中心
5.配置config文件
package com.example.controller.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @Configuration @EnableResourceServer @EnableGlobalMethodSecurity(jsr250Enabled = true,prePostEnabled = true,securedEnabled=true) public class MyResConfig extends ResourceServerConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated()//.access("@RbacConfig.hasPermission(request,authentication)").and().csrf().disable();}@Beanpublic TokenStore tokenStore() {return new JwtTokenStore(jwtAccessTokenConverter());}@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter(){JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();jwtAccessTokenConverter.setSigningKey("test"); // return jwtAccessTokenConverter;} }
測試token是否生效
攜帶token 訪問資源服務器
Authorization??放在headers里面的
Token的值 要求必須是bearer 類型的 token前面加上這個類型