github地址:https://github.com/intfish123/oauth.git
需要2個服務,一個認證授權服務,一個資源服務
認證授權服務為客戶端頒發令牌,資源服務用於客戶端獲取用戶信息。
1. 總體架構:

2.認證授權服務
pom文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.intfish</groupId> <artifactId>auth-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>auth-server</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-oauth2 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.1 項目目錄:

2.2 代碼
AuthorizationConfig.java
package com.intfish.authorization.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.factory.PasswordEncoderFactories; 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.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; @Configuration public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Bean public TokenStore memoryTokenStore(){ //token存在內存中 return new InMemoryTokenStore(); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { //tokenKeyAccess("permitAll()")表示誰都可以獲取令牌 checkTokenAccess("isAuthenticated()")表示只有認證之后才可以檢查令牌 security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients(); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory().withClient("client1") //客戶端id .authorizedGrantTypes("authorization_code", "refresh_token") //允許authorization_code和refresh_token授權 .scopes("test") //權限范圍 可以是 read,write 自己填 .secret(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("123456")) //客戶端secret .redirectUris("http://www.baidu.com"); //回調地址,用於接收code和access_token }
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
// .tokenServices(tokenService())
.tokenStore(tokenStore())
.userDetailsService(userDetailsService);
}
@Bean
public DefaultTokenServices tokenService() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
//配置token存儲
tokenServices.setTokenStore(tokenStore());
//開啟支持refresh_token,此處如果之前沒有配置,啟動服務后再配置重啟服務,可能會導致不返回token的問題,解決方式:清除redis對應token存儲
tokenServices.setSupportRefreshToken(true);
//復用refresh_token
tokenServices.setReuseRefreshToken(true);
//token有效期,設置12小時
tokenServices.setAccessTokenValiditySeconds(12 * 60 * 60);
//refresh_token有效期,設置一周
tokenServices.setRefreshTokenValiditySeconds(7 * 24 * 60 * 60);
return tokenServices;
}
}
SecurityConfig.java
package com.intfish.authorization.config; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean @Override public UserDetailsService userDetailsService() { //基於內存查詢用戶 InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager(); userDetailsManager.createUser( User.withUsername("admin") .password( PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("admin") ).authorities("USER").build() ); return userDetailsManager; } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()); } }
啟動類 AuthServerApplication.java
package com.intfish.authorization; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @SpringBootApplication @EnableAuthorizationServer //啟用認證授權服務 public class AuthServerApplication { public static void main(String[] args) { SpringApplication.run(AuthServerApplication.class, args); } }
配置文件 application.properties
//默認配置即可 什么都不用配置
到此認證授權服務配置完成,直接啟動即可。
3. 資源服務(用於根據access_token查詢用戶信息)
pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.intfish</groupId> <artifactId>resource-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>resource-server</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.1 資源服務項目目錄

3.2 代碼
UserController.java
package com.intfish.resourceserver.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class UserController { private Logger log = LoggerFactory.getLogger(this.getClass()); @PostMapping("getUserInfo") public Object getUserInfo(Authentication authentication){ log.info("獲取用戶信息;"+ authentication); return authentication; } }
啟動類 ResourceServerApplication.java
package com.intfish.resourceserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @SpringBootApplication @EnableResourceServer //開啟資源服務 public class ResourceServerApplication { public static void main(String[] args) { SpringApplication.run(ResourceServerApplication.class, args); } }
配置文件 application.properties
server.port=9090 auth-server-url=http://localhost:8080 security.oauth2.client.client-id=client1 security.oauth2.client.client-secret=123456 security.oauth2.client.scope=test security.oauth2.client.access-token-uri=${auth-server-url}/oauth/token security.oauth2.client.user-authorization-uri=${auth-server-url}/oauth/authorize security.oauth2.resource.token-info-uri=${auth-server-url}/oauth/check_token
到此資源服務配置完成,啟動服務即可。
4. 認證授權+獲取令牌(access_token)
4.1 用瀏覽器訪問 認證授權服務
http://localhost:8080/oauth/authorize?response_type=code&client_id=client1&redirect_uri=http://www.baidu.com
然后自動跳入登錄地址,輸入賬號密碼登錄: admin/admin

登錄成功提示用戶是否允許授權,點Approve允許

登錄成功,自動調轉到回調地址,並在url中帶有code參數

那着這個code用postman發請求獲取令牌

成功拿到令牌access_token。
接着用這個令牌訪問資源服務

請求成功。也可以這樣請求
http://localhost:9090/user/getUserInfo?access_token=2f3c1803-dbb8-4f95-acf6-88a298309ecd
到此全部結束。!!!!!
