本篇文章給大家分享的是有關(guān)SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán),小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
10年積累的成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先建設(shè)網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有龍馬潭免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
Spring Security是一個功能強(qiáng)大、高度可定制的身份驗(yàn)證和訪問控制框架。它用于保護(hù)基于Spring的應(yīng)用程序。Spring Security是一個專注于向Java應(yīng)用程序提供身份驗(yàn)證和授權(quán)的框架。 與所有Spring項目一樣,Spring安全的真正威力在于它可以很容易地擴(kuò)展以滿足定制需求。
OAuth 2.0是用于授權(quán)的行業(yè)標(biāo)準(zhǔn)協(xié)議。OAuth3.0注重客戶端開發(fā)人員的簡單性,同時為Web應(yīng)用程序、桌面應(yīng)用程序、移動電話和客廳設(shè)備提供特定的授權(quán)流。 更多請參考 OAuth3.0
OAuth3.0模式
模式 | 應(yīng)用場景 | 描述 |
---|---|---|
授權(quán)碼(Auth Code) | 成功后跳轉(zhuǎn)其他頁面,如第三方微信登錄等 | |
簡化模式(implicit) | 不通過第三方應(yīng)用程序的服務(wù)器,直接在瀏覽器中向認(rèn)證服務(wù)器申請令牌 | |
密碼模式(password credentials) | web頁面用戶名密碼登錄 | |
客戶端模式(client credentials) | 主要針對openapi,使用apikey和secretkey方式 |
JSON Web Token(縮寫 JWT)是目前最流行的跨域認(rèn)證解決方案。更多請參考 JWT入門教程
核心pom依賴如下:
org.springframework.boot spring-boot-starter-security org.springframework.security.oauth spring-security-oauth3 2.3.6.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-redis org.springframework.boot spring-boot-starter-security org.slf4j slf4j-api 1.7.25 org.projectlombok lombok
創(chuàng)建一個rest接口用于后面測試資源
@Slf4j @RestController public class TestSecurityController { @GetMapping("/product/{id}") public String getProduct(@PathVariable String id) { //for debug Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); return "product id : " + id; } @GetMapping("/order/{id}") public String getOrder(@PathVariable String id) { //for debug Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); return "order id : " + id; } }
很多文章寫的特別復(fù)雜,其實(shí)主要的內(nèi)容也就分為下面幾步
AuthorizationServerConfigurerAdapter
需要自定義授權(quán)服務(wù)器,繼承AuthorizationServerConfigurerAdapter
,詳細(xì)代碼如下
@Configuration @EnableAuthorizationServer public class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter { private static final String DEMO_RESOURCE_ID = "order"; @Autowired AuthenticationManager authenticationManager; @Autowired RedisConnectionFactory redisConnectionFactory; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { //配置兩個客戶端,一個用于password認(rèn)證一個用于client認(rèn)證 String secret = new BCryptPasswordEncoder().encode("123456");////對密碼進(jìn)行加密 clients.inMemory().withClient("client_1") .resourceIds(DEMO_RESOURCE_ID) .authorizedGrantTypes("client_credentials", "refresh_token") .scopes("select") .authorities("client") .secret(secret) .and().withClient("client_2") .resourceIds(DEMO_RESOURCE_ID) .authorizedGrantTypes("password", "refresh_token") .scopes("select") .authorities("client") .secret(secret); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(new RedisTokenStore(redisConnectionFactory)) .authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { //允許表單認(rèn)證 oauthServer.allowFormAuthenticationForClients(); } }
ResourceServerConfigurerAdapter
同上,需要實(shí)現(xiàn)自己的資源服務(wù)器,繼承ResourceServerConfigurerAdapter
,詳細(xì)代碼如下
@Configuration @EnableResourceServer public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { private static final String DEMO_RESOURCE_ID = "order"; @Override public void configure(ResourceServerSecurityConfigurer resources) { resources.resourceId(DEMO_RESOURCE_ID).stateless(true); } @Override public void configure(HttpSecurity http) throws Exception { // @formatter:off http // Since we want the protected resources to be accessible in the UI as well we need // session creation to be allowed (it's disabled by default in 2.0.6) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and() .requestMatchers().anyRequest() .and() .anonymous() .and() .authorizeRequests() // .antMatchers("/product/**").access("#oauth3.hasScope('select') and hasRole('ROLE_USER')") .antMatchers("/order/**").authenticated();//配置order訪問控制,必須認(rèn)證過后才可以訪問 // @formatter:on } }
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Bean @Override protected UserDetailsService userDetailsService(){ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); String pwd = new BCryptPasswordEncoder().encode("123456");//對密碼進(jìn)行加密 manager.createUser(User.withUsername("user_1").password(pwd).authorities("USER").build()); manager.createUser(User.withUsername("user_2").password(pwd).authorities("USER").build()); return manager; } @Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers().anyRequest() .and() .authorizeRequests() .antMatchers("/oauth/*").permitAll(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { AuthenticationManager manager = super.authenticationManagerBean(); return manager; } @Bean PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
我們設(shè)計的是product
服務(wù)可以匿名訪問,而order
服務(wù)需要簽名才可以訪問,驗(yàn)證如下:
password模式 利用postman進(jìn)行post訪問http://localhost:8080/oauth/token?username=user_1&password=123456&grant_type=password&scope=select&client_id=client_2&client_secret=123456
獲取如下結(jié)果
{ "access_token": "c2340190-48f3-4291-bb17-1e4d51bcb284", "token_type": "bearer", "refresh_token": "03ee113c-a942-452a-9918-7ffe24472a7f", "expires_in": 40399, "scope": "select" }
client模式 同樣利用postman的POST方式訪問http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456
結(jié)果如下
{ "access_token": "05a4e614-f34b-4c83-9ec1-89ea55c0afd2", "token_type": "bearer", "expires_in": 40396, "scope": "select" }
product服務(wù):訪問http://localhost:8080/product/1
得到如下數(shù)據(jù)
product id : 1
order服務(wù):訪問http://localhost:8080/order/1
,返回數(shù)據(jù)如下
Full authentication is required to access this resource unauthorized
驗(yàn)證結(jié)果,說明order服務(wù)需要簽名才可以訪問,接下來,我們輸入簽名訪問order服務(wù)。 我們分別利用上面password模式獲取的token,訪問 http://localhost:8080/order/1?access_token=c2340190-48f3-4291-bb17-1e4d51bcb284 得到數(shù)據(jù) order id : 1
通用利用client模式獲取的token,訪問 http://localhost:8080/order/1?access_token=05a4e614-f34b-4c83-9ec1-89ea55c0afd2 同樣可以得到 order id : 1
以上就是SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán),小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。