oauth2-authorization-server;oauth2-resource-server;oauth2-client
spring-security-oauth2-authorization-server
- 依赖项
<?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>2.5.12</version><relativePath/></parent><modelVersion>4.0.0</modelVersion><groupId>test</groupId><artifactId>default-authorizationserver</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.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-authorization-server</artifactId><version>0.2.3</version></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>2.1.212</version></dependency></dependencies> </project>
- 核心代码
package sample.config;import org.springframework.context.annotation.Bean; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; 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.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain;/** * Security配置 */ @EnableWebSecurity public class DefaultSecurityConfig {@BeanSecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorizeRequests ->authorizeRequests.anyRequest().authenticated()).formLogin(Customizer.withDefaults());return http.build();}@BeanUserDetailsService users() {UserDetails user = User.withUsername("user").password(passwordEncoder().encode("password")).roles("USER").build();return new InMemoryUserDetailsManager(user);}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}
package sample.config;import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.ClientSettings; import org.springframework.security.oauth2.server.authorization.config.ProviderSettings; import org.springframework.security.web.SecurityFilterChain; import sample.jose.Jwks;import java.util.UUID;/** * 认证客户端配置 */ @Configuration(proxyBeanMethods = false) public class AuthorizationServerConfig {//自定义用户授权页面/*private static final String CUSTOM_CONSENT_PAGE_URI = "/oauth2/consent";@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {OAuth2AuthorizationServerConfigurer<HttpSecurity> authorizationServerConfigurer =new OAuth2AuthorizationServerConfigurer<>();//自定义用户授权页面authorizationServerConfigurer.authorizationEndpoint(authorizationEndpoint ->authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI));RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();http.requestMatcher(endpointsMatcher).authorizeRequests(authorizeRequests ->authorizeRequests.anyRequest().authenticated()).csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher)).apply(authorizationServerConfigurer);return http.formLogin(Customizer.withDefaults()).build();}*/@Autowiredprivate PasswordEncoder passwordEncoder;@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SecurityFilterChain authenticationServerSecurityFilterChain(HttpSecurity http) throws Exception {OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);return http.formLogin(Customizer.withDefaults()).build();}/*获取codehttp://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=message.read&redirect_uri=https://baidu.com获取tokenpost请求: localhost:9000/oauth2/tokenAuthorization头: Basic Auth Username=client_id; Password=client_secretBody form-data参数: grant_type=authorization_code; redirect_uri=https://baidu.com; code=*/@Beanpublic RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()).clientId("messaging-client").clientSecret(passwordEncoder.encode("secret")).clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN).authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS).redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc").redirectUri("http://127.0.0.1:8080/authorized").scope(OidcScopes.OPENID).scope("message.read").scope("message.write").clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);registeredClientRepository.save(registeredClient);return registeredClientRepository;}@Beanpublic OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);}@Beanpublic OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);}@Beanpublic JWKSource<SecurityContext> jwkSource() {RSAKey rsaKey = Jwks.generateRsa();JWKSet jwkSet = new JWKSet(rsaKey);return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);}public static void main(String[] args) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();System.err.println(passwordEncoder.encode("secret"));}@Beanpublic ProviderSettings providerSettings() {return ProviderSettings.builder().issuer("http://localhost:9000").build();}@Beanpublic EmbeddedDatabase embeddedDatabase() {return new EmbeddedDatabaseBuilder().generateUniqueName(true).setType(EmbeddedDatabaseType.H2).setScriptEncoding("UTF-8").addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql").addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql").addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql").build();} }
package sample.jose;import com.nimbusds.jose.jwk.Curve; import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.OctetSequenceKey; import com.nimbusds.jose.jwk.RSAKey;import javax.crypto.SecretKey; import java.security.KeyPair; import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPrivateKey; import java.util.UUID;/** * jwk配置 */ public final class Jwks {private Jwks() {}public static RSAKey generateRsa() {KeyPair keyPair = KeyGeneratorUtils.generateRsaKey();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();return new RSAKey.Builder(publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();}public static ECKey generateEc() {KeyPair keyPair = KeyGeneratorUtils.generateEcKey();ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();Curve curve = Curve.forECParameterSpec(publicKey.getParams());return new com.nimbusds.jose.jwk.ECKey.Builder(curve, publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();}public static OctetSequenceKey generateSecret() {SecretKey secretKey = KeyGeneratorUtils.generateSecretKey();return new OctetSequenceKey.Builder(secretKey).keyID(UUID.randomUUID().toString()).build();} }
package sample.jose;import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.spec.ECFieldFp; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.EllipticCurve;/** * 生成key */ final class KeyGeneratorUtils {private KeyGeneratorUtils() {}static SecretKey generateSecretKey() {SecretKey hmacKey;try {hmacKey = KeyGenerator.getInstance("HmacSha256").generateKey();} catch (Exception ex) {throw new IllegalStateException(ex);}return hmacKey;}static KeyPair generateRsaKey() {KeyPair keyPair;try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);keyPair = keyPairGenerator.generateKeyPair();} catch (Exception ex) {throw new IllegalStateException(ex);}return keyPair;}static KeyPair generateEcKey() {EllipticCurve ellipticCurve = new EllipticCurve(new ECFieldFp(new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")),new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"),new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291"));ECPoint ecPoint = new ECPoint(new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"),new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109"));ECParameterSpec ecParameterSpec = new ECParameterSpec(ellipticCurve,ecPoint,new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"),1);KeyPair keyPair;try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");keyPairGenerator.initialize(ecParameterSpec);keyPair = keyPairGenerator.generateKeyPair();} catch (Exception e) {throw new IllegalStateException(e);}return keyPair;}}
- 配置文件
server:port: 9000logging:level:root: INFOorg.springframework.web: INFOorg.springframework.security: INFOorg.springframework.security.oauth2: INFO
- sql
CREATE TABLE oauth2_registered_client (id varchar(100) NOT NULL,client_id varchar(100) NOT NULL,client_id_issued_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,client_secret varchar(200) DEFAULT NULL,client_secret_expires_at timestamp DEFAULT NULL,client_name varchar(200) NOT NULL,client_authentication_methods varchar(1000) NOT NULL,authorization_grant_types varchar(1000) NOT NULL,redirect_uris varchar(1000) DEFAULT NULL,scopes varchar(1000) NOT NULL,client_settings varchar(2000) NOT NULL,token_settings varchar(2000) NOT NULL,PRIMARY KEY (id)
);
CREATE TABLE oauth2_authorization_consent (registered_client_id varchar(100) NOT NULL,principal_name varchar(200) NOT NULL,authorities varchar(1000) NOT NULL,PRIMARY KEY (registered_client_id, principal_name)
);
/*
IMPORTANT:If using PostgreSQL, update ALL columns defined with 'blob' to 'text',as PostgreSQL does not support the 'blob' data type.
*/
CREATE TABLE oauth2_authorization (id varchar(100) NOT NULL,registered_client_id varchar(100) NOT NULL,principal_name varchar(200) NOT NULL,authorization_grant_type varchar(100) NOT NULL,attributes blob DEFAULT NULL,state varchar(500) DEFAULT NULL,authorization_code_value blob DEFAULT NULL,authorization_code_issued_at timestamp DEFAULT NULL,authorization_code_expires_at timestamp DEFAULT NULL,authorization_code_metadata blob DEFAULT NULL,access_token_value blob DEFAULT NULL,access_token_issued_at timestamp DEFAULT NULL,access_token_expires_at timestamp DEFAULT NULL,access_token_metadata blob DEFAULT NULL,access_token_type varchar(100) DEFAULT NULL,access_token_scopes varchar(1000) DEFAULT NULL,oidc_id_token_value blob DEFAULT NULL,oidc_id_token_issued_at timestamp DEFAULT NULL,oidc_id_token_expires_at timestamp DEFAULT NULL,oidc_id_token_metadata blob DEFAULT NULL,refresh_token_value blob DEFAULT NULL,refresh_token_issued_at timestamp DEFAULT NULL,refresh_token_expires_at timestamp DEFAULT NULL,refresh_token_metadata blob DEFAULT NULL,PRIMARY KEY (id)
);
oauth2-resource-server的
- 依赖项
<?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>2.5.12</version><relativePath/></parent><modelVersion>4.0.0</modelVersion><groupId>test.oauth</groupId><artifactId>com.oauth2.resource</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-oauth2-resource-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency></dependencies></project>
- 核心代码
package sample.config;import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; /** * resource配置安全链 */ @EnableWebSecurity public class ResourceServerConfig {@BeanSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.mvcMatcher("/messages/**").authorizeRequests().mvcMatchers("/messages/**").access("hasAuthority('SCOPE_message.read')").and().oauth2ResourceServer().jwt();return http.build();}}
/** Copyright 2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ package sample.web;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;/*** @author Joe Grandja* 案例:受保护资源* @since 0.0.1*/ @RestController public class MessagesController {@GetMapping("/messages")public String[] getMessages() {return new String[] {"Message 1", "Message 2", "Message 3"};} }
- 配置文件
server:port: 8090logging:level:root: INFOorg.springframework.web: INFOorg.springframework.security: INFOorg.springframework.security.oauth2: INFO
# org.springframework.boot.autoconfigure: DEBUGspring:security:oauth2:resourceserver:jwt:issuer-uri: http://localhost:9000
oauth2-client
- 依赖项
<?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>2.5.12</version><relativePath/></parent><modelVersion>4.0.0</modelVersion><groupId>test.oauth</groupId><artifactId>com.oauth2.client</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.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webflux</artifactId><version>5.2.21.RELEASE</version></dependency><dependency><groupId>io.projectreactor.netty</groupId><artifactId>reactor-netty</artifactId><version>1.0.18</version></dependency></dependencies> </project>
- 核心代码
/** Copyright 2020-2021 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ package sample.config;import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.web.SecurityFilterChain;import static org.springframework.security.config.Customizer.withDefaults;/*** @author Joe Grandja* 配置oauth2 client* @since 0.0.1*/ @EnableWebSecurity public class SecurityConfig {/** OAuth2AuthorizationRequestRedirectFilter:* 处理 /oauth2/authorization 路径,主要场景是默认或手动配置的 oauth2login 路径,它会将上述路径处理转发给 认证中心 对应的路径 /oauth2/authorize* OAuth2AuthorizationCodeGrantFilter:* 该过滤器负责处理认证中心的授权码回调请求,主要场景就是认证中心生成授权码后的回调请求这里会进行诸如回调地址重定向、OAuth2AuthorizedClient 的创建等处理* OAuth2LoginAuthenticationFilter:* 处理 /login/oauth2/code/* 路径,默认的授权码回调路径,此过滤器会向认证中心请求对应的 Token 信息*/@BeanWebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().antMatchers("/webjars/**");}/** SecurityFilterChain 是 Spring Security 本身的组件* 此处是 Spring Boot 自动装配类提供的默认实例,其中* oauth2Login 是开启 oauth2Login 模式* oauth2Client 声明为 OAuth2 Client,引入对应组件* */@BeanSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorizeRequests ->authorizeRequests.anyRequest().authenticated()).oauth2Login(oauth2Login ->oauth2Login.loginPage("/oauth2/authorization/messaging-client-oidc")).oauth2Client(withDefaults());return http.build();} }
/** Copyright 2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ package sample.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.web.reactive.function.client.WebClient;/*** @author Joe Grandja* 配置webClient 请求携带token* @since 0.0.1*/ @Configuration public class WebClientConfig {@BeanWebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);return WebClient.builder().apply(oauth2Client.oauth2Configuration()).build();}@BeanOAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,OAuth2AuthorizedClientRepository authorizedClientRepository) {OAuth2AuthorizedClientProvider authorizedClientProvider =OAuth2AuthorizedClientProviderBuilder.builder().authorizationCode().refreshToken().clientCredentials().build();DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);return authorizedClientManager;} }
/** Copyright 2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ package sample.web;import org.springframework.beans.factory.annotation.Value; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient; import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.client.WebClient;import javax.servlet.http.HttpServletRequest;import java.util.Arrays; import java.util.Collections; import java.util.List;import static org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId; import static org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient;/*** @author Joe Grandja* 测试代码* @since 0.0.1*/ @RestController public class AuthorizationController {private final WebClient webClient;private final String messagesBaseUri;public AuthorizationController(WebClient webClient,@Value("${messages.base-uri}") String messagesBaseUri) {this.webClient = webClient;this.messagesBaseUri = messagesBaseUri;}@GetMapping(value = "/authorize", params = "grant_type=authorization_code")public List<String> authorizationCodeGrant(@RegisteredOAuth2AuthorizedClient("messaging-client-authorization-code")OAuth2AuthorizedClient authorizedClient) {String[] messages = this.webClient.get().uri(this.messagesBaseUri).attributes(oauth2AuthorizedClient(authorizedClient)).retrieve().bodyToMono(String[].class).block();return messages != null ? Arrays.asList(messages) : Collections.singletonList("没数据");}@GetMapping(value = "/authorize", params = "grant_type=client_credentials")public List<String> clientCredentialsGrant() {String[] messages = this.webClient.get().uri(this.messagesBaseUri).attributes(clientRegistrationId("messaging-client-client-credentials")).retrieve().bodyToMono(String[].class).block();return messages != null ? Arrays.asList(messages) : Collections.singletonList("没数据");} }
- 配置文件
server:port: 8080logging:level:root: INFOorg.springframework.web: INFOorg.springframework.security: INFOorg.springframework.security.oauth2: INFO # org.springframework.boot.autoconfigure: DEBUGspring:thymeleaf:cache: falsesecurity:oauth2:client:registration:messaging-client-oidc:provider: springclient-id: messaging-clientclient-secret: secretauthorization-grant-type: authorization_coderedirect-uri: "http://127.0.0.1:8080/login/oauth2/code/{registrationId}"scope: openidclient-name: messaging-client-oidcmessaging-client-authorization-code:provider: springclient-id: messaging-clientclient-secret: secretauthorization-grant-type: authorization_coderedirect-uri: "http://127.0.0.1:8080/authorized"scope: message.read,message.writeclient-name: messaging-client-authorization-codemessaging-client-client-credentials:provider: springclient-id: messaging-clientclient-secret: secretauthorization-grant-type: client_credentialsscope: message.read,message.writeclient-name: messaging-client-client-credentialsprovider:spring:issuer-uri: http://localhost:9000messages:base-uri: http://127.0.0.1:8090/messages
oauth2-authorization-server;oauth2-resource-server;oauth2-client相关推荐
- springboot oauth2登录成功处理器_Spring Boot Security 整合 OAuth2 设计安全API接口服务...
简介 OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版.本文重点讲解Spring Boot项目对OAuth2进行的实现,如果你对OAut ...
- Spring Cloud(6.1):搭建OAuth2 Authorization Server
配置web.xml 添加spring-cloud-starter-security和spring-security-oauth2-autoconfigure两个依赖. </dependency& ...
- Oauth2 resource server入门配置
Oauth2.0资源服务器配置 上一节:OAuth2.0 Authorization Server入门配置 pom.xml <dependencies><dependency> ...
- cte公用表表达式_CTE SQL删除; 在SQL Server中删除具有公用表表达式的数据时的注意事项
cte公用表表达式 In this article, the latest in our series on Common table expressions, we'll review CTE SQ ...
- adb server version (41) doesn‘t match this client (39); killing
adb server version (41) doesn't match this client (39); killing client 需要升级 android sdk中 win,找到adb.e ...
- react sql格式化_为SQL Server数据库损坏做准备; 初步React与分析
react sql格式化 Corruption is a looming thought through every administrator's mind, from sysadmins to d ...
- adb shell 运行时报错“adb server version (26) doesn‘t match this client (39); killing...“的解决方案
adb shell 运行时报错"adb server version (26) doesn't match this client (39); killing..."的解决方案 参 ...
- OAuth2.0协议入门(一):OAuth2.0协议的基本概念以及使用授权码模式(authorization code)实现百度账号登录
一 OAuth2.0协议的基本概念 (1)OAuth2.0协议 OAuth协议,是一种授权协议,不涉及具体的代码,只是表示一种约定的流程和规范.OAuth协议一般用于用户决定是否把自己在某个服务商上面 ...
- html页面授权码,spring boot 2.0 整合 oauth2 authorization code授权码模式
oauth2 authorization code 大致流程 用户打开客户端后,客户端要求用户给予授权. 用户同意给予客户端授权. 客户端使用授权得到的code,向认证服务器申请token令牌. 认证 ...
- SpringCloud 中 Feign 调用添加 Oauth2 Authorization Header
SpringCloud 中 Feign 调用添加 Oauth2 Authorization Header SpringCloud 中通过 Feign 调用其他服务,当服务使用 Oauth2 授权的时候 ...
最新文章
- 将IDEA工程代码提交到Github
- 少儿编程150讲轻松学Scratch(七)-Scratch学习中需要注意的地方
- Angular 下拉搜索框实现
- WSARecv参数lpNumberOfBytesRecvd的一个变态问题
- 单调栈解木板倒水问题
- Atitit attilax涉及到的大数据 数据分析 数据挖掘 ai人工智能的处理技术 目录 1.1. 大数据 机器视觉 图像处理 数据分析 数据挖掘 知识图谱 ai人工智能方面系列项目	1 2.
- C++ priority_queue
- 怎样杀计算机病毒,如何彻底查杀计算机病毒
- 天载免息股票汽车整车涨幅居前
- 深度学习在时空数据的应用
- React开发者工具 React Developer Tools 的下载
- 公众号和订阅号的区别
- 把阿拉伯数字全部转换为大写(1,2,3.... = 一、二、三、)
- Ural 2045 Richness of words
- LaTeX中正负号写法
- Linux 常用小工具
- ubuntu 调 2K 分辨率
- 拉结尔如何在电脑上玩 拉结尔模拟器玩法教程
- 软考是什么?软考有什么作用?
- html-css-js