forked from xkcoding/spring-boot-demo
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add spring-boot-demo-oauth-resource-server.
- Loading branch information
1 parent
dcfeb4f
commit a989d01
Showing
13 changed files
with
499 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
spring-boot-demo-oauth/spring-boot-demo-oauth-resource-server/README.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
= spring-boot-demo-oauth-resource-server | ||
Doc Writer <lzy@echocow.cn> | ||
v1.0, 2019-01-09 | ||
:toc: | ||
|
||
spring boot oauth2 资源服务器,同 授权服务器 一起使用。 | ||
|
||
> 使用 `spring security oauth` | ||
|
||
- JWT 解密,远程公钥获取 | ||
- 基于角色访问控制 | ||
- 基于应用授权域访问控制 | ||
== jwt 解密 | ||
|
||
要先获取 jwt 公钥 | ||
|
||
[source,java] | ||
.OauthResourceTokenConfig | ||
---- | ||
public class OauthResourceTokenConfig { | ||
// ...... | ||
private String getPubKey() { | ||
// 如果本地没有密钥,就从授权服务器中获取 | ||
return StringUtils.isEmpty(resourceServerProperties.getJwt().getKeyValue()) | ||
? getKeyFromAuthorizationServer() | ||
: resourceServerProperties.getJwt().getKeyValue(); | ||
} | ||
// ...... | ||
} | ||
---- | ||
|
||
然后配置进去 | ||
|
||
[source, java] | ||
.OauthResourceServerConfig | ||
---- | ||
public class OauthResourceServerConfig extends ResourceServerConfigurerAdapter { | ||
@Override | ||
public void configure(ResourceServerSecurityConfigurer resources) { | ||
resources | ||
.tokenStore(tokenStore) | ||
.resourceId(resourceServerProperties.getResourceId()); | ||
} | ||
} | ||
---- | ||
|
||
== 访问控制 | ||
|
||
通过 `@EnableGlobalMethodSecurity(prePostEnabled = true)` 注解开启 `spring security` 的全局方法安全控制 | ||
|
||
- `@PreAuthorize("hasRole('ADMIN')")` 校验角色 | ||
- `@PreAuthorize("#oauth2.hasScope('READ')")` 校验令牌授权域 | ||
|
||
== 测试 | ||
|
||
测试用例: `com.xkcoding.oauth.controller.TestControllerTest` | ||
|
||
先获取 `token`,携带 `token` 去访问资源即可。 |
31 changes: 31 additions & 0 deletions
31
spring-boot-demo-oauth/spring-boot-demo-oauth-resource-server/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?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> | ||
<artifactId>spring-boot-demo-oauth</artifactId> | ||
<groupId>com.xkcoding</groupId> | ||
<version>1.0.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>spring-boot-demo-oauth-resource-server</artifactId> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-security</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.security.oauth.boot</groupId> | ||
<artifactId>spring-security-oauth2-autoconfigure</artifactId> | ||
<version>${spring.boot.version}</version> | ||
</dependency> | ||
</dependencies> | ||
</project> |
21 changes: 21 additions & 0 deletions
21
...h-resource-server/src/main/java/com/xkcoding/oauth/SpringBootDemoResourceApplication.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.xkcoding.oauth; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; | ||
|
||
/** | ||
* 启动器. | ||
* | ||
* @author <a href="https://echocow.cn">EchoCow</a> | ||
* @date 2020/1/9 上午11:38 | ||
* @version V1.0 | ||
*/ | ||
@EnableResourceServer | ||
@SpringBootApplication | ||
public class SpringBootDemoResourceApplication { | ||
public static void main(String[] args) { | ||
SpringApplication.run(SpringBootDemoResourceApplication.class, args); | ||
} | ||
|
||
} |
43 changes: 43 additions & 0 deletions
43
...th-resource-server/src/main/java/com/xkcoding/oauth/config/OauthResourceServerConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.xkcoding.oauth.config; | ||
|
||
import lombok.AllArgsConstructor; | ||
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; | ||
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.oauth2.config.annotation.web.configuration.EnableResourceServer; | ||
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; | ||
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; | ||
import org.springframework.security.oauth2.provider.token.TokenStore; | ||
|
||
/** | ||
* 资源服务器配置. | ||
* 我们自己实现了它的配置,所以它的自动装配不会生效 | ||
* | ||
* @author <a href="https://echocow.cn">EchoCow</a> | ||
* @date 2020/1/9 下午2:20 | ||
*/ | ||
@Configuration | ||
@AllArgsConstructor | ||
@EnableResourceServer | ||
@EnableGlobalMethodSecurity(prePostEnabled = true) | ||
public class OauthResourceServerConfig extends ResourceServerConfigurerAdapter { | ||
|
||
private final ResourceServerProperties resourceServerProperties; | ||
private final TokenStore tokenStore; | ||
|
||
@Override | ||
public void configure(ResourceServerSecurityConfigurer resources) { | ||
resources | ||
.tokenStore(tokenStore) | ||
.resourceId(resourceServerProperties.getResourceId()); | ||
} | ||
|
||
@Override | ||
public void configure(HttpSecurity http) throws Exception { | ||
super.configure(http); | ||
// 前后端分离下,可以关闭 csrf | ||
http.csrf().disable(); | ||
} | ||
|
||
} |
102 changes: 102 additions & 0 deletions
102
...uth-resource-server/src/main/java/com/xkcoding/oauth/config/OauthResourceTokenConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package com.xkcoding.oauth.config; | ||
|
||
import cn.hutool.json.JSONObject; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import lombok.AllArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.HttpEntity; | ||
import org.springframework.http.HttpHeaders; | ||
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; | ||
import org.springframework.util.StringUtils; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
import java.io.IOException; | ||
import java.util.Base64; | ||
|
||
/** | ||
* token 相关配置,jwt 相关. | ||
* | ||
* @author <a href="https://echocow.cn">EchoCow</a> | ||
* @date 2020/1/9 下午2:39 | ||
*/ | ||
@Slf4j | ||
@Configuration | ||
@AllArgsConstructor | ||
public class OauthResourceTokenConfig { | ||
|
||
private final ResourceServerProperties resourceServerProperties; | ||
|
||
/** | ||
* 这里并不是对令牌的存储,他将访问令牌与身份验证进行转换 | ||
* 在需要 {@link TokenStore} 的任何地方可以使用此方法 | ||
* | ||
* @return TokenStore | ||
*/ | ||
@Bean | ||
public TokenStore tokenStore() { | ||
return new JwtTokenStore(jwtAccessTokenConverter()); | ||
} | ||
|
||
/** | ||
* jwt 令牌转换 | ||
* | ||
* @return jwt | ||
*/ | ||
@Bean | ||
public JwtAccessTokenConverter jwtAccessTokenConverter() { | ||
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); | ||
converter.setVerifierKey(getPubKey()); | ||
return converter; | ||
} | ||
|
||
/** | ||
* 非对称密钥加密,获取 public key。 | ||
* 自动选择加载方式。 | ||
* | ||
* @return public key | ||
*/ | ||
private String getPubKey() { | ||
// 如果本地没有密钥,就从授权服务器中获取 | ||
return StringUtils.isEmpty(resourceServerProperties.getJwt().getKeyValue()) | ||
? getKeyFromAuthorizationServer() | ||
: resourceServerProperties.getJwt().getKeyValue(); | ||
} | ||
|
||
/** | ||
* 本地没有公钥的时候,从服务器上获取 | ||
* 需要进行 Basic 认证 | ||
* | ||
* @return public key | ||
*/ | ||
private String getKeyFromAuthorizationServer() { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
HttpHeaders httpHeaders = new HttpHeaders(); | ||
httpHeaders.add(HttpHeaders.AUTHORIZATION, encodeClient()); | ||
HttpEntity<String> requestEntity = new HttpEntity<>(null, httpHeaders); | ||
String pubKey = new RestTemplate() | ||
.getForObject(resourceServerProperties.getJwt().getKeyUri(), String.class, requestEntity); | ||
try { | ||
JSONObject body = objectMapper.readValue(pubKey, JSONObject.class); | ||
log.info("Get Key From Authorization Server."); | ||
return body.getStr("value"); | ||
} catch (IOException e) { | ||
log.error("Get public key error: {}", e.getMessage()); | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* 客户端信息 | ||
* | ||
* @return basic | ||
*/ | ||
private String encodeClient() { | ||
return "Basic " + Base64.getEncoder().encodeToString((resourceServerProperties.getClientId() | ||
+ ":" + resourceServerProperties.getClientSecret()).getBytes()); | ||
} | ||
} |
Oops, something went wrong.