增加 Spring Security OAuth2 的 四种认证类型

This commit is contained in:
YunaiV
2018-09-13 20:14:26 +08:00
parent 6ecc3a6939
commit f8d701cbd9
22 changed files with 392 additions and 72 deletions

View File

@@ -1,51 +0,0 @@
> 直接饮用 https://github.com/geektime-geekbang/oauth2lab/blob/0e0f380a670718225fcfc86c60ca4cf7cc5c24d4/lab01/authcode-server/README.md
> 作者:杨波
基于授权码模式+Spring Security OAuth2的最简授权服务器
======
# 操作方式
## 1. 获取授权码
浏览器请求:
http://localhost:8080/oauth/authorize?client_id=clientapp&redirect_uri=http://localhost:9001/callback&response_type=code&scope=read_userinfo
**注意state参数暂忽略**
响应案例:
http://localhost:9001/callback?code=8uYpdo
## 2. 获取访问令牌
curl -X POST --user clientapp:123456 http://localhost:8080/oauth/token -H
"content-type: application/x-www-form-urlencoded" -d
"code=8uYpdo&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalh
ost%3A9001%2Fcallback&scope=read_userinfo"
案例响应:
```json
{
"access_token": "36cded80-b6f5-43b7-bdfc-594788a24530",
"token_type": "bearer",
"expires_in": 43199,
"scope": "read_userinfo"
}
```
## 3. 调用API
curl -X GET http://localhost:8080/api/userinfo -H "authorization: Bearer 36cded80-b6f5-43b7-bdfc-594788a24530"
案例响应:
```json
{
"name": "bobo",
"email": "bobo@spring2go.com"
}
```

View File

@@ -13,32 +13,24 @@
<artifactId>authorization-code-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- for Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for OAuth 2.0 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<!-- for test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -13,12 +13,12 @@ public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdap
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientapp")
// .secret("112233") // 目前非必须,因为开启的是 authorization_code 模式
.redirectUris("http://localhost:9001/callback")
// 授权码模式
.authorizedGrantTypes("authorization_code")
.scopes("read_userinfo", "read_contacts"); // TODO 芋艿,后续优化
.withClient("clientapp").secret("112233") // Client 账号、密码。
.redirectUris("http://localhost:9001/callback") // 配置回调地址,选填。
.authorizedGrantTypes("authorization_code") // 授权码模式
.scopes("read_userinfo", "read_contacts") // 授权的 Scope
// .and().withClient() // 可以继续配置新的 Client
;
}
}

View File

@@ -13,6 +13,7 @@ public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 对 "/api/**" 开启认证
.anyRequest()
.authenticated()
.and()

View File

@@ -0,0 +1,37 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>client-credentials-server</artifactId>
<dependencies>
<!-- for Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- for Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for OAuth 2.0 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package lab01;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,23 @@
package lab01.authorization;
import org.springframework.context.annotation.Configuration;
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;
// 授权服务器配置
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientapp").secret("112233") // Client 账号、密码。
.authorizedGrantTypes("client_credentials") // 授权码模式
.scopes("read_userinfo", "read_contacts") // 可授权的 Scope
// .and().withClient() // 可以继续配置新的 Client
;
}
}

View File

@@ -0,0 +1,27 @@
package lab01.resource;
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;
// 资源服务配置
@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 对 "/api/**" 开启认证
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/api/**");
}
}
// 实际OAuth2ResourceServer 不是和 OAuth2AuthorizationServer 一起。
// 主要考虑简化 demo 所以改成这样

View File

@@ -0,0 +1,18 @@
package lab01.resource.api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 示例模块 Controller
*/
@RestController
@RequestMapping("/api/example")
public class ExampleController {
@RequestMapping("/hello")
public String hello() {
return "world";
}
}

View File

@@ -0,0 +1,36 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>implicit-server</artifactId>
<dependencies>
<!-- for Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- for Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for OAuth 2.0 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package lab01;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,24 @@
package lab01.authorization;
import org.springframework.context.annotation.Configuration;
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;
// 授权服务器配置
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientapp").secret("112233") // Client 账号、密码。
.redirectUris("http://localhost:9001/callback") // 配置回调地址,选填。
.authorizedGrantTypes("implicit") // 授权码模式
.scopes("read_userinfo", "read_contacts") // 可授权的 Scope
// .and().withClient() // 可以继续配置新的 Client
;
}
}

View File

@@ -0,0 +1,30 @@
package lab01.resource;
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;
// 资源服务配置
@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 对 "/api/**" 开启认证
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/api/**")
// .and()
// .cors()
;
}
}
// 实际OAuth2ResourceServer 不是和 OAuth2AuthorizationServer 一起。
// 主要考虑简化 demo 所以改成这样

View File

@@ -0,0 +1,19 @@
package lab01.resource.api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 示例模块 Controller
*/
@RestController
@RequestMapping("/api/example")
public class ExampleController {
// @CrossOrigin
@RequestMapping("/hello")
public String hello() {
return "world";
}
}

View File

@@ -0,0 +1,3 @@
# Spring Security Setting
security.user.name=yunai
security.user.password=1024

View File

@@ -13,6 +13,9 @@
<packaging>pom</packaging>
<modules>
<module>authorization-code-server</module>
<module>resource-owner-password-credentials-server</module>
<module>implicit-server</module>
<module>client-credentials-server</module>
</modules>

View File

@@ -0,0 +1,36 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>resource-owner-password-credentials-server</artifactId>
<dependencies>
<!-- for Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- for Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- for OAuth 2.0 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package lab01;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,35 @@
package lab01.authorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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;
// 授权服务器配置
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
// 用户认证
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientapp").secret("112233") // Client 账号、密码。
.authorizedGrantTypes("password") // 密码模式
.scopes("read_userinfo", "read_contacts") // 可授权的 Scope
// .and().withClient() // 可以继续配置新的 Client
;
}
}

View File

@@ -0,0 +1,27 @@
package lab01.resource;
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;
// 资源服务配置
@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 对 "/api/**" 开启认证
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/api/**");
}
}
// 实际OAuth2ResourceServer 不是和 OAuth2AuthorizationServer 一起。
// 主要考虑简化 demo 所以改成这样

View File

@@ -0,0 +1,18 @@
package lab01.resource.api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 示例模块 Controller
*/
@RestController
@RequestMapping("/api/example")
public class ExampleController {
@RequestMapping("/hello")
public String hello() {
return "world";
}
}

View File

@@ -0,0 +1,3 @@
# Spring Security Setting
security.user.name=yunai
security.user.password=1024