基于spring-security-oauth2認證授權服務介紹與使用(一)
-
- 1、springCloud Oauth2 基本介紹
- 2、Oauth2 角色劃分
- 3、Oauth2的四種授權方式
- 4、Oauth2環境搭建
-
- 4.1、搭建 spring-security-oauth2 項目[pom]
-
- 4.1.1、pom.xml
- 4.2、搭建oauth2-server 認證授權中心服務
-
- 4.2.1、pom.xml
- 4.2.2、application.yml
- 4.2.3、配置資訊
- 4.2.4、啟動服務
- 4.3、搭建oauth2-resources-order 普通微服務,驗證授權服務
-
- 4.3.1、pom.xml
- 4.3.2、application.yml
- 4.3.3、配置資訊
- 4.3.4、認證授權接口
- 4.3.5、啟動服務
- 5、如何測試認證授權中心服務和通路資源伺服器
1、springCloud Oauth2 基本介紹
OAuth:OAuth(開放授權)是一個開放标準,允許使用者授權第三方網站通路他們存儲在另外的服務提供者上的資訊,而不需要将使用者名和密碼提供給第三方網站或分享他們資料的所有内容。
在Spring Cloud需要使用oauth2來實作多個微服務的統一認證授權,通過向OAUTH服務發送某個類型的grant type進行集中認證和授權,進而獲得access_token,而這個token是受其他微服務信任的,我們在後續的通路可以通過access_token來進行,進而實作了微服務的統一認證授權。
用戶端根據約定的ClientID、ClientSecret、Scope來從Access Token URL位址擷取AccessToken,并經過AuthURL認證,用得到的AccessToken來通路其他資源接口。
Spring Cloud oauth2 需要依賴Spring security
2、Oauth2 角色劃分
- Resource Sever --> 被授權通路的資源
- Authorization Server --> Oauth2認證授權中心
- Resource Owner --> 使用者
- Client --> 使用API 的用戶端(比如:Android、IOS、web app…)
3、Oauth2的四種授權方式
- 授權碼模式(authorization code)用在用戶端與服務端應用之間授權
- 簡化模式(implicit)用在移動ap或者web app(這些app是在使用者裝置上的,如在手機上調用微信來認證授權)
- 密碼模式(resource owner password credentials)應用直接都是受信任的
- 用戶端模式(client credentials)用在應用API通路
4、Oauth2環境搭建
目錄結構及項目位址:spring-security-oauth2

4.1、搭建 spring-security-oauth2 項目[pom]
4.1.1、pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
4.2、搭建oauth2-server 認證授權中心服務
4.2.1、pom.xml
<dependencies>
<!-- SpringBoot整合Web元件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- springboot整合freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-->spring-boot 整合security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- spring-cloud-starter-oauth2 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
</dependencies>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 注意: 這裡必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
4.2.2、application.yml
server:
port: 9090
4.2.3、配置資訊
package com.redmaple.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
* @Description 配置授權中心資訊
* @Author redMaple-gi
* @Date 2020/6/19 13:39
* @Version 1.0
*/
@Configuration
@EnableAuthorizationServer //開啟oauth2認證授權中心服務
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
// accessToken過期時間-1小時
private static int accessTokenValiditySeconds = 3600;
// accessToken的重新整理時間
private static int refreshTokenValiditySeconds = 3600;
/**
* 應該讀取資料庫,先固定寫
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("client_1")
.secret(passwordEncoder().encode("123456"))
// .authorizedGrantTypes("authorization_code","refresh_token") //授權碼模式
// .authorizedGrantTypes("password") //密碼模式
// .authorizedGrantTypes("client_credentials") //用戶端模式
//混合模式
.authorizedGrantTypes("authorization_code","password","refresh_token")
//回調位址
.redirectUris("http://www.baidu.com")
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.scopes("all");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
// 允許表單認證
security.allowFormAuthenticationForClients();
// 允許check_token 通路
security.checkTokenAccess("permitAll()");
}
/**
* 設定token類型
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager())
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);
}
@Bean
public AuthenticationManager authenticationManager(){
AuthenticationManager authenticationManager = new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
return daoAuthenticationProvider().authenticate(authentication);
}
};
return authenticationManager;
}
@Bean
public AuthenticationProvider daoAuthenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService());
daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return daoAuthenticationProvider;
}
/**
* 這裡是使用者名和密碼,需要從資料庫讀取
* 測試先固定
* @return
*/
@Bean
public UserDetailsService userDetailsService(){
InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
userDetailsService.createUser(User.withUsername("redmaple")
.password(passwordEncoder().encode("123456"))
.authorities("ROLE_USER").build()
);
userDetailsService.createUser(User.withUsername("admin")
.password(passwordEncoder().encode("123456"))
.authorities("ROLE_USER").build()
);
return userDetailsService;
}
/**
* 加密方式
* @return
*/
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
這裡必須要加上SecurityConfig 配置檔案,否則會報錯 User must be authenticated with Spring Security before authorization can be completed 錯誤,因為通路請求沒有放行。
package com.redmaple.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.stereotype.Component;
/**
* @Description 通路接口報錯
* User must be authenticated with Spring Security before authorization can be completed.
* 需要開發權限,允許所有的接口通路進來
* @Author redMaple-gi
* @Date 2020/6/19 14:13
* @Version 1.0
*/
@Component
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**")
.fullyAuthenticated().and().formLogin();
}
}
4.2.4、啟動服務
@SpringBootApplication
public class AppOauth2Server {
public static void main(String[] args) {
SpringApplication.run(AppOauth2Server.class,args);
}
}
4.3、搭建oauth2-resources-order 普通微服務,驗證授權服務
4.3.1、pom.xml
<dependencies>
<!-- SpringBoot整合Web元件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- springboot整合freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-->spring-boot 整合security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
</dependencies>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 注意: 這裡必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
4.3.2、application.yml
server:
port: 9091
logging:
level:
org.springframework.security: DEBUG
security:
oauth2:
resource:
## 從認證授權中心上驗證token
token-info-uri: http://localhost:9090/oauth/check_token
prefer-token-info: true
client:
access-token-uri: http://localhost:9090/oauth/token
user-authorization-uri: http://localhost:9090/oauth/authorize
## appid
client-id: client_1
## appSecret
client-secret: 123456
4.3.3、配置資訊
package com.redmaple.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
* @Description 配置攔截設定
* @Author redMaple-gi
* @Date 2020/6/19 14:51
* @Version 1.0
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// 對接口/api/order/** 進行攔截
http.authorizeRequests().antMatchers("/api/order/**").authenticated();
}
}
4.3.4、認證授權接口
package com.redmaple.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description
* @Author redMaple-gi
* @Date 2020/6/19 14:54
* @Version 1.0
*/
@RestController
@RequestMapping("/api/order")
public class OrderController {
@GetMapping("/getOrder")
public String getOrder(){
System.out.println("This is my first time I've intercepted a request with OAuth2!");
return "This is my first time I've intercepted a request with OAuth2!";
}
}
4.3.5、啟動服務
package com.redmaple;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
/**
* @Description
* @Author redMaple-gi
* @Date 2020/6/19 14:50
* @Version 1.0
*/
@SpringBootApplication
@EnableOAuth2Sso
public class AppOauth2Order {
public static void main(String[] args) {
SpringApplication.run(AppOauth2Order.class, args);
}
}
5、如何測試認證授權中心服務和通路資源伺服器
接下來就是測試如何使用oauth2-server和oauth2-resources-order服務
下一篇:基于spring-security-oauth2認證授權服務介紹與使用(二)
項目位址:https://gitee.com/kuiwang2/spring-security-oauth2.git
參考位址:螞蟻課堂