Spring Cloud ?????????????????? OAuth2.0 ??????????????????

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud ?????????????????? OAuth2.0 ??????????????????相关的知识,希望对你有一定的参考价值。

?????????query   rfc   def   rect   work   ??????   tin   top   product   

??????????????????

????????? Spring Cloud ??????????????????????????????????????????????????????????????????(ZUUL ??? Spring APIGateway)??? HTTP ????????????????????????API ???????????????????????? Eureka ??????????????????????????????????????? Eureka ???????????????????????????????????????????????????????????? OAuth2 ????????????????????????????????????????????????????????????????????? API ?????????????????????????????????????????????????????????????????????????????????????????????????????? API ?????????API ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? OAuth2.0???OIDC(OpenID Connect) ???HMAC???JWT ??????

??????????????? RESTFUL API ?????????????????????????????????

OAuth2.0 ????????????

OAuth2.0 ??????????????????????????????????????????????????????????????????????????????

Authorization code?????????????????????
????????? Server ??????????????????????????? Server ?????? Web ???????????????????????????????????????????????????????????????????????????????????????????????? Web ???????????? URL ??????????????????????????????????????????code??????????????????????????? code ???????????????????????????access_token????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? refresh_token ?????????????????????????????????????????????????????????????????????????????????

Implicit Grant??????????????????
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????access_token????????????URL???#hash??????????????????????????????????????????????????????javascript???????????????????????????API???????????????????????????????????????code???????????????????????????refresh token?????????????????????????????????

Resource Owner Password Credentials??????????????????
??????????????????????????????????????????????????????????????????????????????????????????????????????access_token????????????????????????????????????????????????????????????API??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? OAuth ???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????token??????????????????????????????????????????????????????????????? username/password ???????????????????????????????????????

Client Credentials?????????????????????
???????????????????????????????????? APP ???????????????????????????????????? APP ????????????????????????????????????????????????????????????????????? API ??????????????????

??????????????? OAuth 2.0

Spring Security OAuth2 ??????

Spring Security OAuth2 ???????????? Spring Security ??????????????? OAuth2.0 ???????????????????????????????????????????????? Authorization Server???Resource Server ??? Client ?????? Spring ??????????????????????????????????????????????????????????????? Spring Cloud ????????????

Keycloak ???????????????????????????????????????????????????????????????????????????????????????????????????????????????Keycloak ?????????OpenID???Auth2.0???SAML?????????????????????????????????LDAP???Active Directory?????????OpenID Connect, SAML2.0 IdPs???Github???Google ???????????????????????????????????????????????????????????????????????????

???????????? 4.1 ????????????Spring Boot starter ????????? Spring Boot 2 adapter????????????????????????????????? Spring Boot ???????????????????????? keycloak-legacy-spring-boot-starter???

???????????? Authorization Server???Resource Server ??? Client ?????????????????????????????? Spring Security OAuth2 ??? Spring Cloud ????????????????????????

Authorization Server 

??? Authorization Server  ???????????? Spring Security OAuth2 ????????? AuthorizationServerConfigurerAdapter ?????????

public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {
    public AuthorizationServerConfigurerAdapter() {
    }

    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    }

    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    }

    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    }
}
  • ClientDetailsServiceConfigurer????????????????????????????????????????????????????????????????????????????????????????????????????????????client_id ???client_secret???redirect_uri ?????????????????????
  • AuthorizationServerSecurityConfigurer???????????????????????????(Token Endpoint)???????????????????????????
  • AuthorizationServerEndpointsConfigurer????????????????????????????????????Token????????????????????????????????????????????????????????????????????????????????????

Resource Server

??? Resource Server ???????????? Spring Security OAuth2 ????????? ResourceServerConfigurerAdapter ?????????

public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {
    public ResourceServerConfigurerAdapter() {
    }

    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    }

    public void configure(HttpSecurity http) throws Exception {
        ((AuthorizedUrl)http.authorizeRequests().anyRequest()).authenticated();
    }
}

ResourceServerConfigurerAdapter ???????????? OAuth2 ??????????????????????????????????????????client?????????token?????????(Bearer Auth)??????????????? OAuth2 ??????????????????????????????????????????????????????????????? Resource Server????????????????????????????????????????????????????????????????????????????????????????????????????????? URL ?????????

???????????? OAuth2.0 ?????????????????????????????? Basic ????????????????????????????????????????????????????????????

     POST /token HTTP/1.1
     Host: server.example.com
     Authorization: Basic 1sZCaJks20MzpnMsPOi
     Content-Type: application/x-www-form-urlencoded
     grant_type=password&username=irving&password=123456

????????? WebSecurityConfigurerAdapter ???????????????????????????????????????

  • AuthorizationServerConfigurerAdapter
  • ResourceServerConfigurerAdapter
  • WebSecurityConfigurerAdapter

Client

?????? OAuth2.0 ???????????????????????????????????? client_id ??? client_secret ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

   /*
    * ???????????????????????????(?????????JDBC?????????)
    *
    * */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //????????? Client ????????? DB
        clients.jdbc(dataSource)
       // clients.inMemory()
                .withClient("client_1")
                .authorizedGrantTypes("client_credentials")
                .scopes("all","read", "write")
                .authorities("client_credentials")
                .accessTokenValiditySeconds(7200)
                .secret(passwordEncoder.encode("123456"))

                .and().withClient("client_2")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("all","read", "write")
                .accessTokenValiditySeconds(7200)
                .refreshTokenValiditySeconds(10000)
                .authorities("password")
                .secret(passwordEncoder.encode("123456"))

                .and().withClient("client_3").authorities("authorization_code","refresh_token")
                .secret(passwordEncoder.encode("123456"))
                .authorizedGrantTypes("authorization_code")
                .scopes("all","read", "write")
                .accessTokenValiditySeconds(7200)
                .refreshTokenValiditySeconds(10000)
                .redirectUris("http://localhost:8080/callback","http://localhost:8080/signin")

                .and().withClient("client_test")
                .secret(passwordEncoder.encode("123456"))
                .authorizedGrantTypes("all flow")
                .authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token","password", "implicit")
                .redirectUris("http://localhost:8080/callback","http://localhost:8080/signin")
                .scopes("all","read", "write")
                .accessTokenValiditySeconds(7200)
                .refreshTokenValiditySeconds(10000);

            //https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql
           // clients.withClientDetails(new JdbcClientDetailsService(dataSource));
    }

???????????????????????????????????????????????? OAuth2.0 ?????????????????????

MAVEN

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/>
    </parent>

    <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>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <!--Spring Security ??? Security ??? 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.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!-- ??? token ????????? redis ??? -->
        <!--<dependency>-->
        <!--<groupId>org.springframework.boot</groupId>-->
        <!--<artifactId>spring-boot-starter-data-redis</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
SpringApplication
@SpringCloudApplication //@SpringBootApplication???@EnableDiscoveryClient???@EnableCircuitBreaker
public class MicrosrvOauth2ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(MicrosrvOauth2ServerApplication.class, args);
    }
}
/*
[/oauth/authorize]
[/oauth/token]
[/oauth/check_token]
[/oauth/confirm_access]
[/oauth/token_key]
[/oauth/error]
*/
@Configuration
@EnableAuthorizationServer
//@Order(2)
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

/*
    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Bean
    public RedisTokenStore tokenStore() {
        return new RedisTokenStore(connectionFactory);
    }
 */

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

//    @Bean(name = "dataSource")
//    @ConfigurationProperties(prefix = "spring.datasource")
//    public DataSource dataSource() {
//        return DataSourceBuilder.create().build();
//    }

    @Bean("jdbcTokenStore")
    public JdbcTokenStore getJdbcTokenStore() {
        return new JdbcTokenStore(dataSource);
    }

//    @Bean
//    public UserDetailsService userDetailsService(){
//        return new UserService();
//    }

    /*
    * ???????????????????????????(?????????JDBC?????????)
    *
    * */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //????????? Client ????????? DB
        clients.jdbc(dataSource)
       // clients.inMemory()
                .withClient("client_1")
                .authorizedGrantTypes("client_credentials")
                .scopes("all","read", "write")
                .authorities("client_credentials")
                .accessTokenValiditySeconds(7200)
                .secret(passwordEncoder.encode("123456"))

                .and().withClient("client_2")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("all","read", "write")
                .accessTokenValiditySeconds(7200)
                .refreshTokenValiditySeconds(10000)
                .authorities("password")
                .secret(passwordEncoder.encode("123456"))

                .and().withClient("client_3").authorities("authorization_code","refresh_token")
                .secret(passwordEncoder.encode("123456"))
                .authorizedGrantTypes("authorization_code")
                .scopes("all","read", "write")
                .accessTokenValiditySeconds(7200)
                .refreshTokenValiditySeconds(10000)
                .redirectUris("http://localhost:8080/callback","http://localhost:8080/signin")

                .and().withClient("client_test")
                .secret(passwordEncoder.encode("123456"))
                .authorizedGrantTypes("all flow")
                .authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token","password", "implicit")
                .redirectUris("http://localhost:8080/callback","http://localhost:8080/signin")
                .scopes("all","read", "write")
                .accessTokenValiditySeconds(7200)
                .refreshTokenValiditySeconds(10000);

            //https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql
           // clients.withClientDetails(new JdbcClientDetailsService(dataSource));
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

//        endpoints
//                .tokenStore(new RedisTokenStore(redisConnectionFactory))
//                .authenticationManager(authenticationManager);

           endpoints.authenticationManager(authenticationManager)
                     //?????? JwtAccessToken ?????????
                  //  .accessTokenConverter(jwtAccessTokenConverter())
                     //refresh_token ?????? UserDetailsService is required
                 //   .userDetailsService(userDetailsService)
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                    .tokenStore(getJdbcTokenStore());
    }


    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        //curl -i -X POST -H "Accept: application/json" -u "client_1:123456" http://localhost:5000/oauth/check_token?token=a1478d56-ebb8-4f21-b4b6-8a9602df24ec
        oauthServer.tokenKeyAccess("permitAll()")         //url:/oauth/token_key,exposes public key for token verification if using JWT tokens
                   .checkTokenAccess("isAuthenticated()") //url:/oauth/check_token allow check token
                   .allowFormAuthenticationForClients();
    }

    /**
     * ?????????????????????????????????Token????????????
     * @return
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        KeyPair keyPair = new KeyStoreKeyFactory(
                new ClassPathResource("keystore.jks"), "foobar".toCharArray())
                .getKeyPair("test");
        converter.setKeyPair(keyPair);
        return converter;
    }
}
/*
* ?????? user ??????????????? oauth2-server ????????????Resource Server
* */
@Configuration
@EnableResourceServer
//@Order(3)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter  {

//    @Override
//    public void configure(HttpSecurity http) throws Exception {
//        http
//                // Since we want the protected resources to be accessible in the UI as well we need
//                // session creation to be allowed (it???s disabled by default in 2.0.6)
//                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
//                .and()
//                .requestMatchers().anyRequest()
//                .and()
//                .anonymous()
//                .and()
//                .authorizeRequests()
////              .antMatchers("/product/**").access("#oauth2.hasScope(???select???) and hasRole(???ROLE_USER???)")
//                .antMatchers("/user/**").authenticated();//?????????????????????????????????
//    }


//    @Override
//    public void configure(HttpSecurity http) throws Exception {
//        http.requestMatchers().anyRequest()
//                .and()
//                .authorizeRequests()
//                .antMatchers("/api/**").authenticated();
//    }
}
@Configuration
@EnableWebSecurity
//@Order(1)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public UserDetailsService userDetailsService(){
        return new UserService();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("irving")
                .password(passwordEncoder().encode("123456"))
                .roles("read");
        // auth.userDetailsService(userDetailsService())
        //   .passwordEncoder(passwordEncoder());
    }

//    @Bean
//    public static NoOpPasswordEncoder passwordEncoder() {
//        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
//    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http
//                .formLogin().loginPage("/login").permitAll()
//                .and()
//                .requestMatchers()
//                .antMatchers("/", "/login", "/oauth/authorize", "/oauth/confirm_access")
//                .and()
//                .authorizeRequests()
//                .anyRequest().authenticated();


//        http.requestMatchers()
//                .antMatchers("/login", "/oauth/authorize")
//                .and()
//                .authorizeRequests()
//                .anyRequest().authenticated()
//                .and()
//                .formLogin().permitAll();

   //     http.csrf().disable();
        //????????? oauth ???????????????
        http.requestMatchers()
                .anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").permitAll();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
@RestController
@RequestMapping("/api/user")
public class UserController {

    @GetMapping("/me")
    public Principal user(Principal principal) {
        return principal;
    }

    @GetMapping("/{name}")
    public String getUserName(@PathVariable String name) {
        return "hello,"+ name;
    }
}

application.yml

#logging:
#  level:
#    root: DEBUG
logging:
  level:
      org.springframework: INFO #INFO
      org.springframework.security: DEBUG
spring:
  application:
    name: microsrv-oauth2-server
  datasource:
    url: jdbc:mysql://XXX.XXX.XXX.XXX:3306/oauth2?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
    username: root
    password: "!TEST"
    driver: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
        minIdle: 10
        idle-timeout: 10000
        maximumPoolSize: 30
server:
  port: 5000
config:
    oauth2:
        # openssl genrsa -out jwt.pem 2048
        # openssl rsa -in jwt.pem
        privateKey: |
            -----BEGIN RSA PRIVATE KEY-----
            MIICXQIBAAKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5
            mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099t
            hbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQAB
            AoGAImnYGU3ApPOVtBf/TOqLfne+2SZX96eVU06myDY3zA4rO3DfbR7CzCLE6qPn
            yDAIiW0UQBs0oBDdWOnOqz5YaePZu/yrLyj6KM6Q2e9ywRDtDh3ywrSfGpjdSvvo
            aeL1WesBWsgWv1vFKKvES7ILFLUxKwyCRC2Lgh7aI9GGZfECQQD84m98Yrehhin3
            fZuRaBNIu348Ci7ZFZmrvyxAIxrV4jBjpACW0RM2BvF5oYM2gOJqIfBOVjmPwUro
            bYEFcHRvAkEAz8jsfmxsZVwh3Y/Y47BzhKIC5FLaads541jNjVWfrPirljyCy1n4
            sg3WQH2IEyap3WTP84+csCtsfNfyK7fQdwJBAJNRyobY74cupJYkW5OK4OkXKQQL
            Hp2iosJV/Y5jpQeC3JO/gARcSmfIBbbI66q9zKjtmpPYUXI4tc3PtUEY8QsCQQCc
            xySyC0sKe6bNzyC+Q8AVvkxiTKWiI5idEr8duhJd589H72Zc2wkMB+a2CEGo+Y5H
            jy5cvuph/pG/7Qw7sljnAkAy/feClt1mUEiAcWrHRwcQ71AoA0+21yC9VkqPNrn3
            w7OEg8gBqPjRlXBNb00QieNeGGSkXOoU6gFschR22Dzy
            -----END RSA PRIVATE KEY-----
        # openssl rsa -in jwt.pem -pubout
        publicKey: |
            -----BEGIN PUBLIC KEY-----
            MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNQZKqTlO/+2b4ZdhqGJzGBDlt
            b5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE
            /myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26
            hL9dSAZuA8xExjlPmQIDAQAB
            -----END PUBLIC KEY-----
eureka:
  instance:
    preferIpAddress: true
#    instanceId: ${spring.cloud.client.ipAddress}:${server.port}
  client:
    serviceUrl:
      defaultZone: http://10.255.131.162:8000/eureka/,http://10.255.131.163:8000/eureka/,http://10.255.131.164:8000/eureka/

????????????

???????????????

POST http://localhost:5000/oauth/token HTTP/1.1
Authorization: Basic Y2xpZW50XzE6MTIzNDU2
cache-control: no-cache
Postman-Token: 86fd25cd-406d-4db1-a67a-eda3cf760ba5
User-Agent: PostmanRuntime/7.1.1
Accept: */*
Host: localhost:5000
content-type: application/x-www-form-urlencoded
accept-encoding: gzip, deflate
content-length: 29
Connection: keep-alive
grant_type=client_credentials
HTTP/1.1 200
{"access_token":"a1478d56-ebb8-4f21-b4b6-8a9602df24ec","token_type":"bearer","expires_in":1014,"scope":"all read write"}

????????????

POST http://localhost:5000/oauth/token HTTP/1.1
Authorization: Basic Y2xpZW50X3Rlc3Q6MTIzNDU2
cache-control: no-cache
Postman-Token: f97aca16-e2ea-4dda-b51f-eb95caa57560
User-Agent: PostmanRuntime/7.1.1
Accept: */*
Host: localhost:5000
content-type: application/x-www-form-urlencoded
grant_type=password&scope=all&username=irving&password=123456
HTTP/1.1 200
{"access_token":"dfe36394-8592-472f-b52b-24739811f6ee","token_type":"bearer","refresh_token":"c150594f-7d00-44cc-bbce-49e1a6e83552","expires_in":7190,"scope":"all"}

??????????????????

GET http://localhost:5000/api/user/me?access_token=a1478d56-ebb8-4f21-b4b6-8a9602df24ec HTTP/1.1
Host: localhost:5000
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Date: Fri, 20 Jul 2018 09:21:32 GMT
Content-Length: 674
{"authorities":[{"authority":"client_credentials"}],"details":{"remoteAddress":"0:0:0:0:0:0:0:1","sessionId":null,"tokenValue":"a1478d56-ebb8-4f21-b4b6-8a9602df24ec","tokenType":"Bearer","decodedDetails":null},"authenticated":true,"userAuthentication":null,"credentials":"","oauth2Request":{"clientId":"client_1","scope":["all","read","write"],"requestParameters":{"grant_type":"client_credentials"},"resourceIds":[],"authorities":[{"authority":"client_credentials"}],"approved":true,"refresh":false,"redirectUri":null,"responseTypes":[],"extensions":{},"refreshTokenRequest":null,"grantType":"client_credentials"},"clientOnly":true,"principal":"client_1","name":"client_1"}

??????

There is no PasswordEncoder mapped for the id ???null?????????

??????????????????????????? Spring Boot 2.0 ???????????? Spring 5????????????????????????????????????????????? Spring Security 5.0 New Features ???Spring Security ????????? PasswordEncoder ??????????????? ???????????????????????? PlainTextPasswordEncoder?????????????????????????????????????????? BCryptPasswordEncoder ???Client ??? Resource Server ??????????????????????????????????????????????????????????????????????????????????????????

//??????????????? ????????????
@Bean
PasswordEncoder passwordEncoder(){
    return NoOpPasswordEncoder.getInstance();
}

@Bean
PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

method_not_allowed(Request method ???GET??? not supported)  ??????

??????????????????????????? OAuth2.0 ??????????????????????????????????????????????????????????????????????????????????????????

@Configuration
public class OAuthSecurityConfig extends AuthorizationServerConfigurerAdapter {
...
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    ...
    endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);// add get method
    ...

    endpoints.tokenServices(tokenServices);
}
...
}

Token ?????? DB ????????????

??????????????? token ?????????????????????????????????????????????(????????????token LONGVARBINARY)?????????????????????????????? Spring Security OAuth2 ???????????????????????????https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql

2018-07-19 22:31:29.574 DEBUG 20084 --- [nio-5000-exec-6] .s.s.o.p.c.ClientCredentialsTokenGranter : Getting access token for: client_1
2018-07-19 22:31:29.574 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL query
2018-07-19 22:31:29.574 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL statement [select token_id, token from oauth_access_token where authentication_id = ?]
2018-07-19 22:31:29.575 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.datasource.DataSourceUtils      : Fetching JDBC Connection from DataSource
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.datasource.DataSourceUtils      : Returning JDBC Connection to DataSource
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.s.o.p.token.store.JdbcTokenStore     : Failed to find access token for authentication or[email protected]f5d4467d: Principal: client_1; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: TRUSTED_CLIENT
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean ???scopedTarget.clientDetailsService???
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean ???scopedTarget.clientDetailsService???
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL query
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL statement [select token_id, token from oauth_access_token where token_id = ?]
2018-07-19 22:31:29.623 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.datasource.DataSourceUtils      : Fetching JDBC Connection from DataSource
2018-07-19 22:31:29.650 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.datasource.DataSourceUtils      : Returning JDBC Connection to DataSource
2018-07-19 22:31:29.650  INFO 20084 --- [nio-5000-exec-6] o.s.s.o.p.token.store.JdbcTokenStore     : Failed to find access token for token ad587601-e0fd-4dea-8fcc-75144eb74101
2018-07-19 22:31:29.650 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL update
2018-07-19 22:31:29.650 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL statement [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]
2018-07-19 22:31:29.650 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.datasource.DataSourceUtils      : Fetching JDBC Connection from DataSource
2018-07-19 22:31:29.651 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.support.lob.DefaultLobHandler   : Set bytes for BLOB with length 691
2018-07-19 22:31:29.651 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.support.lob.DefaultLobHandler   : Set bytes for BLOB with length 1627
2018-07-19 22:31:29.665 DEBUG 20084 --- [nio-5000-exec-6] o.s.jdbc.datasource.DataSourceUtils      : Returning JDBC Connection to DataSource
2018-07-19 22:31:29.665 DEBUG 20084 --- [nio-5000-exec-6] s.j.s.SQLErrorCodeSQLExceptionTranslator : Unable to translate SQLException with Error code ???1366???, will now try the fallback translator
2018-07-19 22:31:29.665 DEBUG 20084 --- [nio-5000-exec-6] o.s.j.s.SQLStateSQLExceptionTranslator   : Extracted SQL state class ???HY??? from value ???HY000???
2018-07-19 22:31:29.665 DEBUG 20084 --- [nio-5000-exec-6] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]; SQL state [HY000]; error code [1366]; Incorrect string value: ???xACxEDx00x05sr...??? for column ???token??? at row 1; nested exception is java.sql.SQLException: Incorrect string value: ???xACxEDx00x05sr...??? for column ???token??? at row 1
2018-07-19 22:31:29.665 DEBUG 20084 --- [nio-5000-exec-6] .m.m.a.ExceptionHandlerExceptionResolver : Invoking @ExceptionHandler method: public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.exceptions.OAuth2Exception> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.handleException(java.lang.Exception) throws java.lang.Exception
2018-07-19 22:31:29.667 ERROR 20084 --- [nio-5000-exec-6] o.s.s.o.provider.endpoint.TokenEndpoint  : Handling error: UncategorizedSQLException, PreparedStatementCallback; uncategorized SQLException for SQL [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]; SQL state [HY000]; error code [1366]; Incorrect string value: ???xACxEDx00x05sr...??? for column ???token??? at row 1; nested exception is java.sql.SQLException: Incorrect string value: ???xACxEDx00x05sr...??? for column ???token??? at row 1

org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]; SQL state [HY000]; error code [1366]; Incorrect string value: ???xACxEDx00x05sr...??? for column ???token??? at row 1; nested exception is java.sql.SQLException: Incorrect string value: ???xACxEDx00x05sr...??? for column ???token??? at row 1

????????? DB ?????? Redis

?????? QPS ???????????????????????????????????? DB ?????????????????? Redis ??? MongoDB ????????????????????????????????? Token ??????????????????????????? Token ????????? ???????????????????????????????????????????????????????????????

/*
    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Bean
    public RedisTokenStore tokenStore() {
        return new RedisTokenStore(connectionFactory);
    }
 */

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;


    @Bean("jdbcTokenStore")
    public JdbcTokenStore getJdbcTokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

//        endpoints
//                .tokenStore(new RedisTokenStore(redisConnectionFactory))
//                .authenticationManager(authenticationManager);

           endpoints.authenticationManager(authenticationManager)
                     //?????? JwtAccessToken ?????????
                  //  .accessTokenConverter(jwtAccessTokenConverter())
                     //refresh_token ?????? UserDetailsService is required
                 //   .userDetailsService(userDetailsService)
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                    .tokenStore(getJdbcTokenStore());
    }

 GitHub ??????





以上是关于Spring Cloud ?????????????????? OAuth2.0 ??????????????????的主要内容,如果未能解决你的问题,请参考以下文章

spring-cloud-config-server

Spring Cloud实战Spring Cloud GateWay服务网关

spring-cloud-config——Quick Start

Spring Cloud入门 - Spring Cloud保护机制

spring cloud 与 spring boot 和 spring cloud alibab 版本号对应

整合spring cloud云服务架构 - Spring Cloud简介