[
  {
    "path": ".gitignore",
    "content": "*.class\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.ear\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n.idea\n.DS_Store\n*.iml\n\n"
  },
  {
    "path": "README.md",
    "content": "\n* **master分支是当前文章的项目**\n* **master-jdbc分支 是在master基础上以mysql数据库的实现**\n* **master-jwt分支 是在oauth2 jwt的实现**\n\n* 二、[Spring Cloud OAuth2 token存数据库实现](https://www.jianshu.com/p/4ce5577bab74)\n* 三、[Spring Cloud Oauth2 JWT 实现](https://www.jianshu.com/p/402bda62a7c3)\n\n学习一下Spring Cloud OAuth2，我们分三个项目 eureka-server、service-auth、service-hi\n\n ![g9.png](https://upload-images.jianshu.io/upload_images/2151905-98b8ab75251c922d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n\n# 1. 创建eureka-server项目\n选择依赖 **spring-cloud-starter-netflix-eureka-server**\n## 1.1 启动类里添加注释\n``` java\n@SpringBootApplication\n@EnableEurekaServer\npublic class EurekaServerApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(EurekaServerApplication.class, args);\n    }\n}\n```\n## 1.2 application.yml\n``` xml\nspring:\n  application:\n    name: eureka-server\nserver:\n  port: 8761\neureka:\n  instance:\n    hostname: localhost\n  client:\n    service-url:\n      defaultZone: http://localhost:8761/eureka/\n    fetch-registry: false\n    register-with-eureka: false\n```\n配置完成可以访问 http://localhost:8761\n\n#2 创建service-auth项目\n## 2.1 用于获取授权token，项目上目录结构：\n![g4.png](https://upload-images.jianshu.io/upload_images/2151905-82f360b00e6ae1c2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n> 这里有个有趣的地方，如果包名config和customImpl和启动类不在同一个根包下，会扫不到包，此时必须在启动类上增加 ``` @ComponentScan(basePackages = \"包名\") ```\n\n##2.2 创建项目依赖 \n+ **spring-boot-starter-data-redis** 把token存到redis中\n+ **spring-cloud-starter-netflix-eureka-client** 做为EurekaClient\n+ **spring-cloud-starter-oauth2** 是对spring-cloud-starter-security、spring-security-oauth2、spring-security-jwt这3个依赖的整合\n+ **spring-boot-starter-actuator**\n\n完整pom.xml\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>com.uaa.service</groupId>\n    <artifactId>uaa-service</artifactId>\n    <version>0.0.1-SNAPSHOT</version>\n    <packaging>jar</packaging>\n\n    <name>uaa-service</name>\n    <description>Demo project for Spring Boot</description>\n\n    <parent>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-starter-parent</artifactId>\n        <version>2.0.4.RELEASE</version>\n        <relativePath/> <!-- lookup parent from repository -->\n    </parent>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n        <java.version>1.8</java.version>\n        <spring-cloud.version>Finchley.SR1</spring-cloud.version>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-actuator</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-data-redis</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.cloud</groupId>\n            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.cloud</groupId>\n            <artifactId>spring-cloud-starter-oauth2</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-test</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.springframework.cloud</groupId>\n                <artifactId>spring-cloud-dependencies</artifactId>\n                <version>${spring-cloud.version}</version>\n                <type>pom</type>\n                <scope>import</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n\n</project>\n```\n## 2.3 application.yml \n```xml\nspring:\n  application:\n    name: service-auth\n  redis:\n    host: 172.16.10.43\n    database: 0\nserver:\n  port: 9098\neureka:\n  client:\n    service-url:\n      defaultZone: http://localhost:8761/eureka/\n```\napplication.yml中配置redis、注册中心\n接下来分别继承 **AuthorizationServerConfigurerAdapter**和**WebSecurityConfigurerAdapter**\n+ AuthorizationServerConfigurerAdapter 类中3个不同的configure方法分别\n  + configure(ClientDetailsServiceConfigurer clients) 用来配置客户端详情服务（ClientDetailsService），客户端详情信息在这里进行初始化，你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息；\n  + configure(AuthorizationServerEndpointsConfigurer endpoints) 用来配置授权（authorization）以及令牌（token）的访问端点和令牌服务(token services)，还有token的存储方式(tokenStore)；\n  + configure(AuthorizationServerSecurityConfigurer security) 用来配置令牌端点(Token Endpoint)的安全约束；\n+ WebSecurityConfigurerAdapter \n  + configure(HttpSecurity http) httpSecurity中配置所有请求的安全验证\n  + 注入Bean UserDetailsService\n  + 注入Bean AuthenticationManager 用来做验证\n  + 注入Bean PasswordEncoder\n\n## 2.4  AuthorizationServerConfiguration继承AuthorizationServerConfigurerAdapter\n``` java\n@Configuration\n@EnableAuthorizationServer\npublic class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {\n    @Autowired\n    AuthenticationManager authenticationManager;\n\n    @Autowired\n    RedisConnectionFactory redisConnectionFactory;\n\n    @Override\n    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {\n        String finalSecret = \"{bcrypt}\" + new BCryptPasswordEncoder().encode(\"123456\");\n\n        // 配置两个客户端，一个用于password认证一个用于client认证\n        clients.inMemory().withClient(\"client_1\")\n                .resourceIds(Utils.RESOURCEIDS.ORDER)\n                .authorizedGrantTypes(\"client_credentials\", \"refresh_token\")\n                .scopes(\"select\")\n                .authorities(\"oauth2\")\n                .secret(finalSecret)\n                .and().withClient(\"client_2\")\n                .resourceIds(Utils.RESOURCEIDS.ORDER)\n                .authorizedGrantTypes(\"password\", \"refresh_token\")\n                .scopes(\"server\")\n                .authorities(\"oauth2\")\n                .secret(finalSecret);\n    }\n\n    @Override\n    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {\n        endpoints.tokenStore(new MyRedisTokenStore(redisConnectionFactory))\n                .authenticationManager(authenticationManager)\n                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);\n    }\n\n    @Override\n    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {\n        // 允许表单认证\n        security.allowFormAuthenticationForClients();\n    }\n}\n\n\n```\n##2.5 SecurityConfiguration 继承 WebSecurityConfigurerAdapter\n``` java\n@Configuration\n@EnableWebSecurity\npublic class SecurityConfiguration extends WebSecurityConfigurerAdapter {\n    @Bean\n    @Override\n    protected UserDetailsService userDetailsService() {\n        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();\n\n        String finalPassword = \"{bcrypt}\"+bCryptPasswordEncoder.encode(\"123456\");\n        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();\n        manager.createUser(User.withUsername(\"user_1\").password(finalPassword).authorities(\"USER\").build());\n        manager.createUser(User.withUsername(\"user_2\").password(finalPassword).authorities(\"USER\").build());\n\n        return manager;\n    }\n\n    @Bean\n    PasswordEncoder passwordEncoder() {\n        return PasswordEncoderFactories.createDelegatingPasswordEncoder();\n    }\n\n    @Bean\n    @Override\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        AuthenticationManager manager = super.authenticationManagerBean();\n        return manager;\n    }\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http.requestMatchers().anyRequest()\n                .and()\n                .authorizeRequests()\n                .antMatchers(\"/oauth/**\").permitAll();\n    }\n}\n\n```\n\n> 这里在内在中创建了两个用户user_1和user_2，后续会以存mysql数据的方式来完善。\n\n##2.6 暴露Remote Token Services 接口\n采用RemoteTokenServices这种方式对token进行验证，如果其他资源服务需要验证token,则需要远程调用授权服务暴露的验证token的api接口，验证token的API接口代码如下：\n\n``` java\n@RestController\n@RequestMapping(\"/users\")\npublic class UserController {\n\n    Logger logger = LoggerFactory.getLogger(UserController.class);\n\n    @RequestMapping(value = \"/current\", method = RequestMethod.GET)\n    public Principal getUser(Principal principal) {\n        logger.info(\">>>>>>>>>>>>>>>>>>>>>>>>\");\n        logger.info(principal.toString());\n        logger.info(\">>>>>>>>>>>>>>>>>>>>>>>>\");\n        return principal;\n    }\n}\n\n```\n \n\n##2.7 启动类\n``` java\n@SpringBootApplication\n@EnableResourceServer\n@EnableEurekaClient\npublic class ServiceAuthApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(ServiceAuthApplication.class, args);\n    }\n}\n```\n> 启动类上加上EnableResourceServer注解开启资源服务，因为程序需要对外暴露获取token的API和验证token的API所以该程序也是一个资源服务器。\n\n*到此，授权服务已经配置完成，可以访问，认证类型以password方式*\n\n![g2.png](https://upload-images.jianshu.io/upload_images/2151905-1fb916316cb390c5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n# 3. 创建资源服务器 service-hi\n创建项目的依赖 spring-cloud-starter-openfeign、spring-cloud-starter-oauth2、spring-cloud-starter-netflix-eureka-client、spring-boot-starter-web\n## 3.1 以下是完整pom.xml\n``` xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<groupId>com.service.hi</groupId>\n\t<artifactId>service-hi</artifactId>\n\t<version>0.0.1-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<name>service-hi</name>\n\t<description>Demo project for Spring Boot</description>\n\n\t<parent>\n\t\t<groupId>org.springframework.boot</groupId>\n\t\t<artifactId>spring-boot-starter-parent</artifactId>\n\t\t<version>2.0.4.RELEASE</version>\n\t\t<relativePath/> <!-- lookup parent from repository -->\n\t</parent>\n\n\t<properties>\n\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\t\t<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n\t\t<java.version>1.8</java.version>\n\t\t<spring-cloud.version>Finchley.SR1</spring-cloud.version>\n\t</properties>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-web</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t<artifactId>spring-cloud-starter-oauth2</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t<artifactId>spring-cloud-starter-openfeign</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-test</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<dependencyManagement>\n\t\t<dependencies>\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t\t<artifactId>spring-cloud-dependencies</artifactId>\n\t\t\t\t<version>${spring-cloud.version}</version>\n\t\t\t\t<type>pom</type>\n\t\t\t\t<scope>import</scope>\n\t\t\t</dependency>\n\t\t</dependencies>\n\t</dependencyManagement>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t\t<artifactId>spring-boot-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\n</project>\n```\n\n## 3.2 配置文件 application.yml\n``` xml\neureka:\n  client:\n    service-url:\n      defaultZone: http://localhost:8761/eureka/\nserver:\n  port: 8765\nspring:\n  application:\n    name: service-hi\nsecurity:\n  oauth2:\n    resource:\n      user-info-uri: http://localhost:9098/users/current\n    client:\n      id: client_2\n      client-secret: 123456\n      access-token-uri: http://localhost:9098/oauth/token\n      grant-type: client_credentials,password\n      scope: server\n```\n> security.oauth2.resource.user-info-uri用于获取当前token的用户信息，配置security.oauth2.client的相关信息以及clientId、client-secret等信息要和service-auth中的配置一一对应。\n\n## 3.3 配置Resource Server\n``` java\n@Configuration\n@EnableResourceServer\n@EnableGlobalMethodSecurity(prePostEnabled = true)\npublic class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {\n\n\n    @Override\n    public void configure(HttpSecurity http) throws Exception {\n        http.authorizeRequests()\n                .antMatchers(\"/order/**\").authenticated(); // 配置order访问控制，必须认证后才可以访问\n    }\n}\n```\n> 添加EnableResourceServer注解开启资源服务的功能，加注解EnableGlobalMethodSecurity开户方法级别的保护，ResourceServerConfigurerAdapter是配置类，configure(HttpSecurity http)中只配置了\"/order/**\"需要验证。\n\n## 3.4 配置OAuth2 Client\nOAuth2 client用来访问被OAuth2保护的资源，service-hi作为OAuth2 Client，配置如下：\n``` java\n@EnableOAuth2Client\n@EnableConfigurationProperties\n@Configuration\npublic class OAuth2ClientConfig {\n\n    @Bean\n    @ConfigurationProperties(prefix = \"security.oauth2.client\")\n    public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {\n        return new ClientCredentialsResourceDetails();\n    }\n\n    @Bean\n    public RequestInterceptor oauth2FeignRequestInterceptor() {\n        return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), clientCredentialsResourceDetails());\n    }\n\n    @Bean\n    public OAuth2RestTemplate clientCredentialsRestTemplate() {\n        return new OAuth2RestTemplate(clientCredentialsResourceDetails());\n    }\n}\n```\n> 注解EnableOAuth2Client开启了OAuth2 Client功能，注入一个OAuth2RestTemplate 类型的Bean用于向service-auth服务请求。\n## 3.5 写一个端点测试Controller TestEndPointController\n``` java\n@RestController\npublic class TestEndPointController {\n\n    Logger logger = LoggerFactory.getLogger(TestEndPointController.class);\n\n    @GetMapping(\"/product/{id}\")\n    public String getProduct(@PathVariable String id) {\n        return \"product id : \" + id;\n    }\n\n    @GetMapping(\"/order/{id}\")\n    public String getOrder(@PathVariable String id) {\n        return \"order id : \" + id;\n    }\n\n    @GetMapping(\"/getPrinciple\")\n    public OAuth2Authentication getPrinciple(OAuth2Authentication oAuth2Authentication, Principal principal, Authentication authentication) {\n        logger.info(oAuth2Authentication.getUserAuthentication().getAuthorities().toString());\n        logger.info(oAuth2Authentication.toString());\n        logger.info(\"principal.toString() \" + principal.toString());\n        logger.info(\"principal.getName() \" + principal.getName());\n        logger.info(\"authentication: \" + authentication.getAuthorities().toString());\n\n        return oAuth2Authentication;\n    }\n}\n```\n## 3.6 启动类\n``` java\n@SpringBootApplication\n@EnableEurekaClient\npublic class ServiceHiApplication {\n\n\tpublic static void main(String[] args) {\n\t\tSpringApplication.run(ServiceHiApplication.class, args);\n\t}\n}\n```\n到此资源服务的配置也完成，我们可以测试，依次启动 eureka-server、service-auth、service-hi\n访问http://localhost:8761\n![g7.png](https://upload-images.jianshu.io/upload_images/2151905-75e9f3ced3a578b8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/850)\n\n访问oauth/token获取token信息 get方式请求： \n\nhttp://localhost:9098/oauth/token?username=user_1&password=123456&grant_type=password&scope=server&client_id=client_2&client_secret=123456\n\n也可以使用postman用post方式访问。\n请求结果：\n``` json\n{\n    \"access_token\": \"e9a93dff-fd58-4af3-b458-01fbb6079416\",\n    \"token_type\": \"bearer\",\n    \"refresh_token\": \"f31290cf-f421-49ba-8112-95a1a2fe9f09\",\n    \"expires_in\": 40172,\n    \"scope\": \"server\"\n}\n```\n这时候如果访问service-hi的http://localhost:8765/order/1 不带token信息：\n``` json\n{\n    \"error\": \"unauthorized\",\n    \"error_description\": \"Full authentication is required to access this resource\"\n}\n```\n告诉你，没有权限访问该资源\n\n正确的访问姿势：\n可以是以url参数形式 http://localhost:8765/order/1?access_token=e9a93dff-fd58-4af3-b458-01fbb6079416\n也可以是headers 的authorization中 bearer token 形式\n![g8.png](https://upload-images.jianshu.io/upload_images/2151905-f24eb03adf19d26d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/850)\n\n不需要验证的资源product  http://localhost:8765/product/1\n```\nproduct id : 1\n```\ngetPrinciple打印出验证信息 http://localhost:8765/getPrinciple ：\n``` json\n{\n    \"authorities\": [\n        {\n            \"authority\": \"USER\"\n        }\n    ],\n    \"details\": {\n        \"remoteAddress\": \"0:0:0:0:0:0:0:1\",\n        \"sessionId\": \"8F2D30BA614CA41B6AA03D2A4650EA3E\",\n        \"tokenValue\": \"e9a93dff-fd58-4af3-b458-01fbb6079416\",\n        \"tokenType\": \"Bearer\",\n        \"decodedDetails\": null\n    },\n    \"authenticated\": true,\n    \"userAuthentication\": {\n        \"authorities\": [\n            {\n                \"authority\": \"USER\"\n            }\n        ],\n        \"details\": {\n            \"authorities\": [\n                {\n                    \"authority\": \"USER\"\n                }\n            ],\n            \"details\": {\n                \"remoteAddress\": \"127.0.0.1\",\n                \"sessionId\": null,\n                \"tokenValue\": \"e9a93dff-fd58-4af3-b458-01fbb6079416\",\n                \"tokenType\": \"Bearer\",\n                \"decodedDetails\": null\n            },\n            \"authenticated\": true,\n            \"userAuthentication\": {\n                \"authorities\": [\n                    {\n                        \"authority\": \"USER\"\n                    }\n                ],\n                \"details\": {\n                    \"grant_type\": \"password\",\n                    \"scope\": \"server\",\n                    \"client_secret\": \"123456\",\n                    \"client_id\": \"client_2\",\n                    \"username\": \"user_1\"\n                },\n                \"authenticated\": true,\n                \"principal\": {\n                    \"password\": null,\n                    \"username\": \"user_1\",\n                    \"authorities\": [\n                        {\n                            \"authority\": \"USER\"\n                        }\n                    ],\n                    \"accountNonExpired\": true,\n                    \"accountNonLocked\": true,\n                    \"credentialsNonExpired\": true,\n                    \"enabled\": true\n                },\n                \"credentials\": null,\n                \"name\": \"user_1\"\n            },\n            \"oauth2Request\": {\n                \"clientId\": \"client_2\",\n                \"scope\": [\n                    \"server\"\n                ],\n                \"requestParameters\": {\n                    \"grant_type\": \"password\",\n                    \"scope\": \"server\",\n                    \"client_id\": \"client_2\",\n                    \"username\": \"user_1\"\n                },\n                \"resourceIds\": [],\n                \"authorities\": [\n                    {\n                        \"authority\": \"oauth2\"\n                    }\n                ],\n                \"approved\": true,\n                \"refresh\": false,\n                \"redirectUri\": null,\n                \"responseTypes\": [],\n                \"extensions\": {},\n                \"grantType\": \"password\",\n                \"refreshTokenRequest\": null\n            },\n            \"principal\": {\n                \"password\": null,\n                \"username\": \"user_1\",\n                \"authorities\": [\n                    {\n                        \"authority\": \"USER\"\n                    }\n                ],\n                \"accountNonExpired\": true,\n                \"accountNonLocked\": true,\n                \"credentialsNonExpired\": true,\n                \"enabled\": true\n            },\n            \"credentials\": \"\",\n            \"clientOnly\": false,\n            \"name\": \"user_1\"\n        },\n        \"authenticated\": true,\n        \"principal\": \"user_1\",\n        \"credentials\": \"N/A\",\n        \"name\": \"user_1\"\n    },\n    \"clientOnly\": false,\n    \"principal\": \"user_1\",\n    \"credentials\": \"\",\n    \"oauth2Request\": {\n        \"clientId\": null,\n        \"scope\": [],\n        \"requestParameters\": {},\n        \"resourceIds\": [],\n        \"authorities\": [],\n        \"approved\": true,\n        \"refresh\": false,\n        \"redirectUri\": null,\n        \"responseTypes\": [],\n        \"extensions\": {},\n        \"grantType\": null,\n        \"refreshTokenRequest\": null\n    },\n    \"name\": \"user_1\"\n}\n```\n\n"
  },
  {
    "path": "eureka-server/.gitignore",
    "content": "/target/\n!.mvn/wrapper/maven-wrapper.jar\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n### IntelliJ IDEA ###\n.idea\n*.iws\n*.iml\n*.ipr\n\n### NetBeans ###\n/nbproject/private/\n/build/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/"
  },
  {
    "path": "eureka-server/.mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip\n"
  },
  {
    "path": "eureka-server/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Maven2 Start Up Batch script\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   M2_HOME - location of maven2's installed home dir\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"`uname`\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        export JAVA_HOME=\"`/usr/libexec/java_home`\"\n      else\n        export JAVA_HOME=\"/Library/Java/Home\"\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=`java-config --jre-home`\n  fi\nfi\n\nif [ -z \"$M2_HOME\" ] ; then\n  ## resolve links - $0 may be a link to maven's home\n  PRG=\"$0\"\n\n  # need this for relative symlinks\n  while [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n      PRG=\"$link\"\n    else\n      PRG=\"`dirname \"$PRG\"`/$link\"\n    fi\n  done\n\n  saveddir=`pwd`\n\n  M2_HOME=`dirname \"$PRG\"`/..\n\n  # make it fully qualified\n  M2_HOME=`cd \"$M2_HOME\" && pwd`\n\n  cd \"$saveddir\"\n  # echo Using m2 at $M2_HOME\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --unix \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --unix \"$CLASSPATH\"`\nfi\n\n# For Migwn, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=\"`(cd \"$M2_HOME\"; pwd)`\"\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"`(cd \"$JAVA_HOME\"; pwd)`\"\n  # TODO classpath?\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"`which javac`\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"`expr \\\"$javaExecutable\\\" : '\\([^ ]*\\)'`\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=`which readlink`\n    if [ ! `expr \"$readLink\" : '\\([^ ]*\\)'` = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n        javaExecutable=\"`cd \\\"$javaHome\\\" && pwd -P`/javac\"\n      else\n        javaExecutable=\"`readlink -f \\\"$javaExecutable\\\"`\"\n      fi\n      javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n      javaHome=`expr \"$javaHome\" : '\\(.*\\)/bin'`\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"`which java`\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\nCLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=`cd \"$wdir/..\"; pwd`\n    fi\n    # end of workaround\n  done\n  echo \"${basedir}\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    echo \"$(tr -s '\\n' ' ' < \"$1\")\"\n  fi\n}\n\nBASE_DIR=`find_maven_basedir \"$(pwd)\"`\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nexport MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}\necho $MAVEN_PROJECTBASEDIR\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --path --windows \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --path --windows \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --windows \"$CLASSPATH\"`\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=`cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\"`\nfi\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.home=${M2_HOME}\" \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "eureka-server/mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    http://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Maven2 Start Up Batch script\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM M2_HOME - location of maven2's installed home dir\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_pre.bat\" call \"%HOME%\\mavenrc_pre.bat\"\nif exist \"%HOME%\\mavenrc_pre.cmd\" call \"%HOME%\\mavenrc_pre.cmd\"\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\n\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_post.bat\" call \"%HOME%\\mavenrc_post.bat\"\nif exist \"%HOME%\\mavenrc_post.cmd\" call \"%HOME%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\" == \"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\" == \"on\" exit %ERROR_CODE%\n\nexit /B %ERROR_CODE%\n"
  },
  {
    "path": "eureka-server/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>com.eureka.server</groupId>\n    <artifactId>eureka-server</artifactId>\n    <version>0.0.1-SNAPSHOT</version>\n    <packaging>jar</packaging>\n\n    <name>eureka-server</name>\n    <description>Demo project for Spring Boot</description>\n\n    <parent>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-starter-parent</artifactId>\n        <version>2.0.4.RELEASE</version>\n        <relativePath/> <!-- lookup parent from repository -->\n    </parent>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n        <java.version>1.8</java.version>\n        <spring-cloud.version>Finchley.SR1</spring-cloud.version>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework.cloud</groupId>\n            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-test</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.springframework.cloud</groupId>\n                <artifactId>spring-cloud-dependencies</artifactId>\n                <version>${spring-cloud.version}</version>\n                <type>pom</type>\n                <scope>import</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n\n</project>\n"
  },
  {
    "path": "eureka-server/src/main/java/com/eureka/server/eurekaserver/EurekaServerApplication.java",
    "content": "package com.eureka.server.eurekaserver;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;\n\n@SpringBootApplication\n@EnableEurekaServer\npublic class EurekaServerApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(EurekaServerApplication.class, args);\n    }\n}\n"
  },
  {
    "path": "eureka-server/src/main/resources/application.yml",
    "content": "spring:\r\n  application:\r\n    name: eureka-server\r\nserver:\r\n  port: 8761\r\neureka:\r\n  instance:\r\n    hostname: localhost\r\n  client:\r\n    service-url:\r\n      defaultZone: http://localhost:8761/eureka/\r\n    fetch-registry: false\r\n    register-with-eureka: false\r\n"
  },
  {
    "path": "eureka-server/src/test/java/com/eureka/server/eurekaserver/EurekaServerApplicationTests.java",
    "content": "package com.eureka.server.eurekaserver;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit4.SpringRunner;\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\npublic class EurekaServerApplicationTests {\n\n    @Test\n    public void contextLoads() {\n    }\n\n}\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>com.test.security.oauth2.demo</groupId>\n    <artifactId>test-security-oauth2-demo</artifactId>\n    <version>1.0-SNAPSHOT</version>\n\n\n</project>\n"
  },
  {
    "path": "service-auth/.gitignore",
    "content": "/target/\n!.mvn/wrapper/maven-wrapper.jar\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n### IntelliJ IDEA ###\n.idea\n*.iws\n*.iml\n*.ipr\n\n### NetBeans ###\n/nbproject/private/\n/build/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/"
  },
  {
    "path": "service-auth/.mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip\n"
  },
  {
    "path": "service-auth/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Maven2 Start Up Batch script\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   M2_HOME - location of maven2's installed home dir\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"`uname`\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        export JAVA_HOME=\"`/usr/libexec/java_home`\"\n      else\n        export JAVA_HOME=\"/Library/Java/Home\"\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=`java-config --jre-home`\n  fi\nfi\n\nif [ -z \"$M2_HOME\" ] ; then\n  ## resolve links - $0 may be a link to maven's home\n  PRG=\"$0\"\n\n  # need this for relative symlinks\n  while [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n      PRG=\"$link\"\n    else\n      PRG=\"`dirname \"$PRG\"`/$link\"\n    fi\n  done\n\n  saveddir=`pwd`\n\n  M2_HOME=`dirname \"$PRG\"`/..\n\n  # make it fully qualified\n  M2_HOME=`cd \"$M2_HOME\" && pwd`\n\n  cd \"$saveddir\"\n  # echo Using m2 at $M2_HOME\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --unix \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --unix \"$CLASSPATH\"`\nfi\n\n# For Migwn, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=\"`(cd \"$M2_HOME\"; pwd)`\"\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"`(cd \"$JAVA_HOME\"; pwd)`\"\n  # TODO classpath?\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"`which javac`\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"`expr \\\"$javaExecutable\\\" : '\\([^ ]*\\)'`\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=`which readlink`\n    if [ ! `expr \"$readLink\" : '\\([^ ]*\\)'` = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n        javaExecutable=\"`cd \\\"$javaHome\\\" && pwd -P`/javac\"\n      else\n        javaExecutable=\"`readlink -f \\\"$javaExecutable\\\"`\"\n      fi\n      javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n      javaHome=`expr \"$javaHome\" : '\\(.*\\)/bin'`\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"`which java`\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\nCLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=`cd \"$wdir/..\"; pwd`\n    fi\n    # end of workaround\n  done\n  echo \"${basedir}\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    echo \"$(tr -s '\\n' ' ' < \"$1\")\"\n  fi\n}\n\nBASE_DIR=`find_maven_basedir \"$(pwd)\"`\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nexport MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}\necho $MAVEN_PROJECTBASEDIR\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --path --windows \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --path --windows \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --windows \"$CLASSPATH\"`\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=`cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\"`\nfi\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.home=${M2_HOME}\" \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "service-auth/mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    http://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Maven2 Start Up Batch script\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM M2_HOME - location of maven2's installed home dir\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_pre.bat\" call \"%HOME%\\mavenrc_pre.bat\"\nif exist \"%HOME%\\mavenrc_pre.cmd\" call \"%HOME%\\mavenrc_pre.cmd\"\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\n\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_post.bat\" call \"%HOME%\\mavenrc_post.bat\"\nif exist \"%HOME%\\mavenrc_post.cmd\" call \"%HOME%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\" == \"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\" == \"on\" exit %ERROR_CODE%\n\nexit /B %ERROR_CODE%\n"
  },
  {
    "path": "service-auth/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>com.service.auth</groupId>\n    <artifactId>service-auth</artifactId>\n    <version>0.0.1-SNAPSHOT</version>\n    <packaging>jar</packaging>\n\n    <name>service-auth</name>\n    <description>Demo project for Spring Boot</description>\n\n    <parent>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-starter-parent</artifactId>\n        <version>2.0.4.RELEASE</version>\n        <relativePath/> <!-- lookup parent from repository -->\n    </parent>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n        <java.version>1.8</java.version>\n        <spring-cloud.version>Finchley.SR1</spring-cloud.version>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-actuator</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-data-redis</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.cloud</groupId>\n            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.cloud</groupId>\n            <artifactId>spring-cloud-starter-oauth2</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>org.springframework.boot</groupId>\n            <artifactId>spring-boot-starter-test</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <dependencyManagement>\n        <dependencies>\n            <dependency>\n                <groupId>org.springframework.cloud</groupId>\n                <artifactId>spring-cloud-dependencies</artifactId>\n                <version>${spring-cloud.version}</version>\n                <type>pom</type>\n                <scope>import</scope>\n            </dependency>\n        </dependencies>\n    </dependencyManagement>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.springframework.boot</groupId>\n                <artifactId>spring-boot-maven-plugin</artifactId>\n            </plugin>\n        </plugins>\n    </build>\n\n\n</project>\n"
  },
  {
    "path": "service-auth/src/main/java/com/service/auth/serviceauth/ServiceAuthApplication.java",
    "content": "package com.service.auth.serviceauth;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.EnableAutoConfiguration;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.netflix.eureka.EnableEurekaClient;\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;\n\n@SpringBootApplication\n@EnableResourceServer\n@EnableEurekaClient\npublic class ServiceAuthApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(ServiceAuthApplication.class, args);\n    }\n}\n"
  },
  {
    "path": "service-auth/src/main/java/com/service/auth/serviceauth/config/AuthorizationServerConfiguration.java",
    "content": "package com.service.auth.serviceauth.config;\r\n\r\nimport com.service.auth.serviceauth.customImpl.MyRedisTokenStore;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.data.redis.connection.RedisConnectionFactory;\r\nimport org.springframework.http.HttpMethod;\r\nimport org.springframework.security.authentication.AuthenticationManager;\r\nimport org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\r\nimport org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;\r\nimport org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;\r\nimport org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;\r\nimport org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;\r\nimport org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;\r\n\r\n@Configuration\r\n@EnableAuthorizationServer\r\npublic class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {\r\n    @Autowired\r\n    AuthenticationManager authenticationManager;\r\n\r\n    @Autowired\r\n    RedisConnectionFactory redisConnectionFactory;\r\n\r\n    @Override\r\n    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {\r\n        String finalSecret = \"{bcrypt}\" + new BCryptPasswordEncoder().encode(\"123456\");\r\n\r\n        // 配置两个客户端，一个用于password认证一个用于client认证\r\n        clients.inMemory().withClient(\"client_1\")\r\n//                .resourceIds(Utils.RESOURCEIDS.ORDER)\r\n                .authorizedGrantTypes(\"client_credentials\", \"refresh_token\")\r\n                .scopes(\"select\")\r\n                .authorities(\"oauth2\")\r\n                .secret(finalSecret)\r\n                .and().withClient(\"client_2\")\r\n//                .resourceIds(Utils.RESOURCEIDS.ORDER)\r\n                .authorizedGrantTypes(\"password\", \"refresh_token\")\r\n                .scopes(\"server\")\r\n                .authorities(\"oauth2\")\r\n                .secret(finalSecret);\r\n    }\r\n\r\n    @Override\r\n    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {\r\n        endpoints.tokenStore(new MyRedisTokenStore(redisConnectionFactory))\r\n                .authenticationManager(authenticationManager)\r\n                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);\r\n    }\r\n\r\n    @Override\r\n    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {\r\n        // 允许表单认证\r\n        security.allowFormAuthenticationForClients().tokenKeyAccess(\"permitAll()\")\r\n                .checkTokenAccess(\"isAuthenticated()\");\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-auth/src/main/java/com/service/auth/serviceauth/config/SecurityConfiguration.java",
    "content": "package com.service.auth.serviceauth.config;\r\n\r\nimport org.springframework.context.annotation.Bean;\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.security.authentication.AuthenticationManager;\r\nimport org.springframework.security.config.annotation.web.builders.HttpSecurity;\r\nimport org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;\r\nimport org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\r\nimport org.springframework.security.core.userdetails.User;\r\nimport org.springframework.security.core.userdetails.UserDetailsService;\r\nimport org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;\r\nimport org.springframework.security.crypto.factory.PasswordEncoderFactories;\r\nimport org.springframework.security.crypto.password.PasswordEncoder;\r\nimport org.springframework.security.provisioning.InMemoryUserDetailsManager;\r\n\r\n@Configuration\r\n@EnableWebSecurity\r\npublic class SecurityConfiguration extends WebSecurityConfigurerAdapter {\r\n    @Bean\r\n    @Override\r\n    protected UserDetailsService userDetailsService() {\r\n        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();\r\n\r\n        String finalPassword = \"{bcrypt}\"+bCryptPasswordEncoder.encode(\"123456\");\r\n        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();\r\n        manager.createUser(User.withUsername(\"user_1\").password(finalPassword).authorities(\"USER\").build());\r\n        manager.createUser(User.withUsername(\"user_2\").password(finalPassword).authorities(\"USER\").build());\r\n\r\n        return manager;\r\n    }\r\n\r\n    @Bean\r\n    PasswordEncoder passwordEncoder() {\r\n        return PasswordEncoderFactories.createDelegatingPasswordEncoder();\r\n    }\r\n\r\n    @Bean\r\n    @Override\r\n    public AuthenticationManager authenticationManagerBean() throws Exception {\r\n        AuthenticationManager manager = super.authenticationManagerBean();\r\n        return manager;\r\n    }\r\n\r\n    @Override\r\n    protected void configure(HttpSecurity http) throws Exception {\r\n        http.requestMatchers().anyRequest()\r\n                .and()\r\n                .authorizeRequests()\r\n                .antMatchers(\"/oauth/**\").permitAll();\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-auth/src/main/java/com/service/auth/serviceauth/config/Utils.java",
    "content": "package com.service.auth.serviceauth.config;\r\n\r\npublic class Utils {\r\n    public static class RESOURCEIDS {\r\n        static final String ORDER = \"order\";\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-auth/src/main/java/com/service/auth/serviceauth/controller/UserController.java",
    "content": "package com.service.auth.serviceauth.controller;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.web.bind.annotation.RequestMapping;\r\nimport org.springframework.web.bind.annotation.RequestMethod;\r\nimport org.springframework.web.bind.annotation.RestController;\r\n\r\nimport java.security.Principal;\r\n\r\n@RestController\r\n@RequestMapping(\"/users\")\r\npublic class UserController {\r\n\r\n    Logger logger = LoggerFactory.getLogger(UserController.class);\r\n\r\n    @RequestMapping(value = \"/current\", method = RequestMethod.GET)\r\n    public Principal getUser(Principal principal) {\r\n        logger.info(\">>>>>>>>>>>>>>>>>>>>>>>>\");\r\n        logger.info(principal.toString());\r\n        logger.info(\">>>>>>>>>>>>>>>>>>>>>>>>\");\r\n        return principal;\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-auth/src/main/java/com/service/auth/serviceauth/customImpl/MyRedisTokenStore.java",
    "content": "package com.service.auth.serviceauth.customImpl;\r\n\r\nimport org.springframework.data.redis.connection.RedisConnection;\r\nimport org.springframework.data.redis.connection.RedisConnectionFactory;\r\nimport org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;\r\nimport org.springframework.security.oauth2.common.OAuth2AccessToken;\r\nimport org.springframework.security.oauth2.common.OAuth2RefreshToken;\r\nimport org.springframework.security.oauth2.provider.OAuth2Authentication;\r\nimport org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;\r\nimport org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;\r\nimport org.springframework.security.oauth2.provider.token.TokenStore;\r\nimport org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy;\r\nimport org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;\r\n\r\nimport java.util.*;\r\n\r\npublic class MyRedisTokenStore implements TokenStore {private static final String ACCESS = \"access:\";\r\n    private static final String AUTH_TO_ACCESS = \"auth_to_access:\";\r\n    private static final String AUTH = \"auth:\";\r\n    private static final String REFRESH_AUTH = \"refresh_auth:\";\r\n    private static final String ACCESS_TO_REFRESH = \"access_to_refresh:\";\r\n    private static final String REFRESH = \"refresh:\";\r\n    private static final String REFRESH_TO_ACCESS = \"refresh_to_access:\";\r\n    private static final String CLIENT_ID_TO_ACCESS = \"client_id_to_access:\";\r\n    private static final String UNAME_TO_ACCESS = \"uname_to_access:\";\r\n    private final RedisConnectionFactory connectionFactory;\r\n    private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();\r\n    private RedisTokenStoreSerializationStrategy serializationStrategy = new JdkSerializationStrategy();\r\n    private String prefix = \"\";\r\n\r\n    public MyRedisTokenStore(RedisConnectionFactory connectionFactory) {\r\n        this.connectionFactory = connectionFactory;\r\n    }\r\n\r\n    public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {\r\n        this.authenticationKeyGenerator = authenticationKeyGenerator;\r\n    }\r\n\r\n    public void setSerializationStrategy(RedisTokenStoreSerializationStrategy serializationStrategy) {\r\n        this.serializationStrategy = serializationStrategy;\r\n    }\r\n\r\n    public void setPrefix(String prefix) {\r\n        this.prefix = prefix;\r\n    }\r\n\r\n    private RedisConnection getConnection() {\r\n        return this.connectionFactory.getConnection();\r\n    }\r\n\r\n    private byte[] serialize(Object object) {\r\n        return this.serializationStrategy.serialize(object);\r\n    }\r\n\r\n    private byte[] serializeKey(String object) {\r\n        return this.serialize(this.prefix + object);\r\n    }\r\n\r\n    private OAuth2AccessToken deserializeAccessToken(byte[] bytes) {\r\n        return (OAuth2AccessToken)this.serializationStrategy.deserialize(bytes, OAuth2AccessToken.class);\r\n    }\r\n\r\n    private OAuth2Authentication deserializeAuthentication(byte[] bytes) {\r\n        return (OAuth2Authentication)this.serializationStrategy.deserialize(bytes, OAuth2Authentication.class);\r\n    }\r\n\r\n    private OAuth2RefreshToken deserializeRefreshToken(byte[] bytes) {\r\n        return (OAuth2RefreshToken)this.serializationStrategy.deserialize(bytes, OAuth2RefreshToken.class);\r\n    }\r\n\r\n    private byte[] serialize(String string) {\r\n        return this.serializationStrategy.serialize(string);\r\n    }\r\n\r\n    private String deserializeString(byte[] bytes) {\r\n        return this.serializationStrategy.deserializeString(bytes);\r\n    }\r\n\r\n    public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {\r\n        String key = this.authenticationKeyGenerator.extractKey(authentication);\r\n        byte[] serializedKey = this.serializeKey(\"auth_to_access:\" + key);\r\n        byte[] bytes = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n\r\n        try {\r\n            bytes = conn.get(serializedKey);\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);\r\n        if (accessToken != null) {\r\n            OAuth2Authentication storedAuthentication = this.readAuthentication(accessToken.getValue());\r\n            if (storedAuthentication == null || !key.equals(this.authenticationKeyGenerator.extractKey(storedAuthentication))) {\r\n                this.storeAccessToken(accessToken, authentication);\r\n            }\r\n        }\r\n\r\n        return accessToken;\r\n    }\r\n\r\n    public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {\r\n        return this.readAuthentication(token.getValue());\r\n    }\r\n\r\n    public OAuth2Authentication readAuthentication(String token) {\r\n        byte[] bytes = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n\r\n        try {\r\n            bytes = conn.get(this.serializeKey(\"auth:\" + token));\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        OAuth2Authentication var4 = this.deserializeAuthentication(bytes);\r\n        return var4;\r\n    }\r\n\r\n    public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {\r\n        return this.readAuthenticationForRefreshToken(token.getValue());\r\n    }\r\n\r\n    public OAuth2Authentication readAuthenticationForRefreshToken(String token) {\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        OAuth2Authentication var5;\r\n        try {\r\n            byte[] bytes = conn.get(this.serializeKey(\"refresh_auth:\" + token));\r\n            OAuth2Authentication auth = this.deserializeAuthentication(bytes);\r\n            var5 = auth;\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        return var5;\r\n    }\r\n\r\n    public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {\r\n        byte[] serializedAccessToken = this.serialize((Object)token);\r\n        byte[] serializedAuth = this.serialize((Object)authentication);\r\n        byte[] accessKey = this.serializeKey(\"access:\" + token.getValue());\r\n        byte[] authKey = this.serializeKey(\"auth:\" + token.getValue());\r\n        byte[] authToAccessKey = this.serializeKey(\"auth_to_access:\" + this.authenticationKeyGenerator.extractKey(authentication));\r\n        byte[] approvalKey = this.serializeKey(\"uname_to_access:\" + getApprovalKey(authentication));\r\n        byte[] clientId = this.serializeKey(\"client_id_to_access:\" + authentication.getOAuth2Request().getClientId());\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            conn.openPipeline();\r\n            conn.stringCommands().set(accessKey, serializedAccessToken);\r\n            conn.stringCommands().set(authKey, serializedAuth);\r\n            conn.stringCommands().set(authToAccessKey, serializedAccessToken);\r\n            if (!authentication.isClientOnly()) {\r\n                conn.rPush(approvalKey, new byte[][]{serializedAccessToken});\r\n            }\r\n\r\n            conn.rPush(clientId, new byte[][]{serializedAccessToken});\r\n            if (token.getExpiration() != null) {\r\n                int seconds = token.getExpiresIn();\r\n                conn.expire(accessKey, (long)seconds);\r\n                conn.expire(authKey, (long)seconds);\r\n                conn.expire(authToAccessKey, (long)seconds);\r\n                conn.expire(clientId, (long)seconds);\r\n                conn.expire(approvalKey, (long)seconds);\r\n            }\r\n\r\n            OAuth2RefreshToken refreshToken = token.getRefreshToken();\r\n            if (refreshToken != null && refreshToken.getValue() != null) {\r\n                byte[] refresh = this.serialize(token.getRefreshToken().getValue());\r\n                byte[] auth = this.serialize(token.getValue());\r\n                byte[] refreshToAccessKey = this.serializeKey(\"refresh_to_access:\" + token.getRefreshToken().getValue());\r\n                conn.stringCommands().set(refreshToAccessKey, auth);\r\n                byte[] accessToRefreshKey = this.serializeKey(\"access_to_refresh:\" + token.getValue());\r\n                conn.stringCommands().set(accessToRefreshKey, refresh);\r\n                if (refreshToken instanceof ExpiringOAuth2RefreshToken) {\r\n                    ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken)refreshToken;\r\n                    Date expiration = expiringRefreshToken.getExpiration();\r\n                    if (expiration != null) {\r\n                        int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L).intValue();\r\n                        conn.expire(refreshToAccessKey, (long)seconds);\r\n                        conn.expire(accessToRefreshKey, (long)seconds);\r\n                    }\r\n                }\r\n            }\r\n\r\n            conn.closePipeline();\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n    }\r\n\r\n    private static String getApprovalKey(OAuth2Authentication authentication) {\r\n        String userName = authentication.getUserAuthentication() == null ? \"\" : authentication.getUserAuthentication().getName();\r\n        return getApprovalKey(authentication.getOAuth2Request().getClientId(), userName);\r\n    }\r\n\r\n    private static String getApprovalKey(String clientId, String userName) {\r\n        return clientId + (userName == null ? \"\" : \":\" + userName);\r\n    }\r\n\r\n    public void removeAccessToken(OAuth2AccessToken accessToken) {\r\n        this.removeAccessToken(accessToken.getValue());\r\n    }\r\n\r\n    public OAuth2AccessToken readAccessToken(String tokenValue) {\r\n        byte[] key = this.serializeKey(\"access:\" + tokenValue);\r\n        byte[] bytes = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            bytes = conn.get(key);\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        OAuth2AccessToken var5 = this.deserializeAccessToken(bytes);\r\n        return var5;\r\n    }\r\n\r\n    public void removeAccessToken(String tokenValue) {\r\n        byte[] accessKey = this.serializeKey(\"access:\" + tokenValue);\r\n        byte[] authKey = this.serializeKey(\"auth:\" + tokenValue);\r\n        byte[] accessToRefreshKey = this.serializeKey(\"access_to_refresh:\" + tokenValue);\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            conn.openPipeline();\r\n            conn.get(accessKey);\r\n            conn.get(authKey);\r\n            conn.del(new byte[][]{accessKey});\r\n            conn.del(new byte[][]{accessToRefreshKey});\r\n            conn.del(new byte[][]{authKey});\r\n            List<Object> results = conn.closePipeline();\r\n            byte[] access = (byte[])((byte[])results.get(0));\r\n            byte[] auth = (byte[])((byte[])results.get(1));\r\n            OAuth2Authentication authentication = this.deserializeAuthentication(auth);\r\n            if (authentication != null) {\r\n                String key = this.authenticationKeyGenerator.extractKey(authentication);\r\n                byte[] authToAccessKey = this.serializeKey(\"auth_to_access:\" + key);\r\n                byte[] unameKey = this.serializeKey(\"uname_to_access:\" + getApprovalKey(authentication));\r\n                byte[] clientId = this.serializeKey(\"client_id_to_access:\" + authentication.getOAuth2Request().getClientId());\r\n                conn.openPipeline();\r\n                conn.del(new byte[][]{authToAccessKey});\r\n                conn.lRem(unameKey, 1L, access);\r\n                conn.lRem(clientId, 1L, access);\r\n                conn.del(new byte[][]{this.serialize(\"access:\" + key)});\r\n                conn.closePipeline();\r\n            }\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n    }\r\n\r\n    public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {\r\n        byte[] refreshKey = this.serializeKey(\"refresh:\" + refreshToken.getValue());\r\n        byte[] refreshAuthKey = this.serializeKey(\"refresh_auth:\" + refreshToken.getValue());\r\n        byte[] serializedRefreshToken = this.serialize((Object)refreshToken);\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            conn.openPipeline();\r\n            conn.stringCommands().set(refreshKey, serializedRefreshToken);\r\n            conn.stringCommands().set(refreshAuthKey, this.serialize((Object)authentication));\r\n            if (refreshToken instanceof ExpiringOAuth2RefreshToken) {\r\n                ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken)refreshToken;\r\n                Date expiration = expiringRefreshToken.getExpiration();\r\n                if (expiration != null) {\r\n                    int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L).intValue();\r\n                    conn.expire(refreshKey, (long)seconds);\r\n                    conn.expire(refreshAuthKey, (long)seconds);\r\n                }\r\n            }\r\n\r\n            conn.closePipeline();\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n    }\r\n\r\n    public OAuth2RefreshToken readRefreshToken(String tokenValue) {\r\n        byte[] key = this.serializeKey(\"refresh:\" + tokenValue);\r\n        byte[] bytes = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            bytes = conn.get(key);\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        OAuth2RefreshToken var5 = this.deserializeRefreshToken(bytes);\r\n        return var5;\r\n    }\r\n\r\n    public void removeRefreshToken(OAuth2RefreshToken refreshToken) {\r\n        this.removeRefreshToken(refreshToken.getValue());\r\n    }\r\n\r\n    public void removeRefreshToken(String tokenValue) {\r\n        byte[] refreshKey = this.serializeKey(\"refresh:\" + tokenValue);\r\n        byte[] refreshAuthKey = this.serializeKey(\"refresh_auth:\" + tokenValue);\r\n        byte[] refresh2AccessKey = this.serializeKey(\"refresh_to_access:\" + tokenValue);\r\n        byte[] access2RefreshKey = this.serializeKey(\"access_to_refresh:\" + tokenValue);\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            conn.openPipeline();\r\n            conn.del(new byte[][]{refreshKey});\r\n            conn.del(new byte[][]{refreshAuthKey});\r\n            conn.del(new byte[][]{refresh2AccessKey});\r\n            conn.del(new byte[][]{access2RefreshKey});\r\n            conn.closePipeline();\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n    }\r\n\r\n    public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {\r\n        this.removeAccessTokenUsingRefreshToken(refreshToken.getValue());\r\n    }\r\n\r\n    private void removeAccessTokenUsingRefreshToken(String refreshToken) {\r\n        byte[] key = this.serializeKey(\"refresh_to_access:\" + refreshToken);\r\n        List<Object> results = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            conn.openPipeline();\r\n            conn.get(key);\r\n            conn.del(new byte[][]{key});\r\n            results = conn.closePipeline();\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        if (results != null) {\r\n            byte[] bytes = (byte[])((byte[])results.get(0));\r\n            String accessToken = this.deserializeString(bytes);\r\n            if (accessToken != null) {\r\n                this.removeAccessToken(accessToken);\r\n            }\r\n\r\n        }\r\n    }\r\n\r\n    public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {\r\n        byte[] approvalKey = this.serializeKey(\"uname_to_access:\" + getApprovalKey(clientId, userName));\r\n        List<byte[]> byteList = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            byteList = conn.lRange(approvalKey, 0L, -1L);\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        if (byteList != null && byteList.size() != 0) {\r\n            List<OAuth2AccessToken> accessTokens = new ArrayList(byteList.size());\r\n            Iterator var7 = byteList.iterator();\r\n\r\n            while(var7.hasNext()) {\r\n                byte[] bytes = (byte[])var7.next();\r\n                OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);\r\n                accessTokens.add(accessToken);\r\n            }\r\n\r\n            return Collections.unmodifiableCollection(accessTokens);\r\n        } else {\r\n            return Collections.emptySet();\r\n        }\r\n    }\r\n\r\n    public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {\r\n        byte[] key = this.serializeKey(\"client_id_to_access:\" + clientId);\r\n        List<byte[]> byteList = null;\r\n        RedisConnection conn = this.getConnection();\r\n\r\n        try {\r\n            byteList = conn.lRange(key, 0L, -1L);\r\n        } finally {\r\n            conn.close();\r\n        }\r\n\r\n        if (byteList != null && byteList.size() != 0) {\r\n            List<OAuth2AccessToken> accessTokens = new ArrayList(byteList.size());\r\n            Iterator var6 = byteList.iterator();\r\n\r\n            while(var6.hasNext()) {\r\n                byte[] bytes = (byte[])var6.next();\r\n                OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);\r\n                accessTokens.add(accessToken);\r\n            }\r\n\r\n            return Collections.unmodifiableCollection(accessTokens);\r\n        } else {\r\n            return Collections.emptySet();\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-auth/src/main/resources/application.yml",
    "content": "spring:\n  application:\n    name: service-auth\n\n  redis:\n    host: 172.16.10.43\n    database: 1\n\n\nserver:\n  port: 9098\neureka:\n  client:\n    service-url:\n      defaultZone: http://localhost:8761/eureka/\n\n#logging.level.org.springframework.security: DEBUG\n\n"
  },
  {
    "path": "service-auth/src/test/java/com/service/auth/serviceauth/ServiceAuthApplicationTests.java",
    "content": "package com.service.auth.serviceauth;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit4.SpringRunner;\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\npublic class ServiceAuthApplicationTests {\n\n    @Test\n    public void contextLoads() {\n    }\n\n}\n"
  },
  {
    "path": "service-hi/.gitignore",
    "content": "/target/\n!.mvn/wrapper/maven-wrapper.jar\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBeans\n.sts4-cache\n\n### IntelliJ IDEA ###\n.idea\n*.iws\n*.iml\n*.ipr\n\n### NetBeans ###\n/nbproject/private/\n/build/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/"
  },
  {
    "path": "service-hi/.mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip\n"
  },
  {
    "path": "service-hi/mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Maven2 Start Up Batch script\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   M2_HOME - location of maven2's installed home dir\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"`uname`\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        export JAVA_HOME=\"`/usr/libexec/java_home`\"\n      else\n        export JAVA_HOME=\"/Library/Java/Home\"\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=`java-config --jre-home`\n  fi\nfi\n\nif [ -z \"$M2_HOME\" ] ; then\n  ## resolve links - $0 may be a link to maven's home\n  PRG=\"$0\"\n\n  # need this for relative symlinks\n  while [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n      PRG=\"$link\"\n    else\n      PRG=\"`dirname \"$PRG\"`/$link\"\n    fi\n  done\n\n  saveddir=`pwd`\n\n  M2_HOME=`dirname \"$PRG\"`/..\n\n  # make it fully qualified\n  M2_HOME=`cd \"$M2_HOME\" && pwd`\n\n  cd \"$saveddir\"\n  # echo Using m2 at $M2_HOME\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --unix \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --unix \"$CLASSPATH\"`\nfi\n\n# For Migwn, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=\"`(cd \"$M2_HOME\"; pwd)`\"\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"`(cd \"$JAVA_HOME\"; pwd)`\"\n  # TODO classpath?\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"`which javac`\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"`expr \\\"$javaExecutable\\\" : '\\([^ ]*\\)'`\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=`which readlink`\n    if [ ! `expr \"$readLink\" : '\\([^ ]*\\)'` = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n        javaExecutable=\"`cd \\\"$javaHome\\\" && pwd -P`/javac\"\n      else\n        javaExecutable=\"`readlink -f \\\"$javaExecutable\\\"`\"\n      fi\n      javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n      javaHome=`expr \"$javaHome\" : '\\(.*\\)/bin'`\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"`which java`\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\nCLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=`cd \"$wdir/..\"; pwd`\n    fi\n    # end of workaround\n  done\n  echo \"${basedir}\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    echo \"$(tr -s '\\n' ' ' < \"$1\")\"\n  fi\n}\n\nBASE_DIR=`find_maven_basedir \"$(pwd)\"`\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\nexport MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}\necho $MAVEN_PROJECTBASEDIR\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --path --windows \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --path --windows \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --windows \"$CLASSPATH\"`\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=`cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\"`\nfi\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.home=${M2_HOME}\" \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "service-hi/mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    http://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Maven2 Start Up Batch script\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM M2_HOME - location of maven2's installed home dir\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_pre.bat\" call \"%HOME%\\mavenrc_pre.bat\"\nif exist \"%HOME%\\mavenrc_pre.cmd\" call \"%HOME%\\mavenrc_pre.cmd\"\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\n\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\n%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_post.bat\" call \"%HOME%\\mavenrc_post.bat\"\nif exist \"%HOME%\\mavenrc_post.cmd\" call \"%HOME%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\" == \"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\" == \"on\" exit %ERROR_CODE%\n\nexit /B %ERROR_CODE%\n"
  },
  {
    "path": "service-hi/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n\t<modelVersion>4.0.0</modelVersion>\n\n\t<groupId>com.service.hi</groupId>\n\t<artifactId>service-hi</artifactId>\n\t<version>0.0.1-SNAPSHOT</version>\n\t<packaging>jar</packaging>\n\n\t<name>service-hi</name>\n\t<description>Demo project for Spring Boot</description>\n\n\t<parent>\n\t\t<groupId>org.springframework.boot</groupId>\n\t\t<artifactId>spring-boot-starter-parent</artifactId>\n\t\t<version>2.0.4.RELEASE</version>\n\t\t<relativePath/> <!-- lookup parent from repository -->\n\t</parent>\n\n\t<properties>\n\t\t<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n\t\t<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n\t\t<java.version>1.8</java.version>\n\t\t<spring-cloud.version>Finchley.SR1</spring-cloud.version>\n\t</properties>\n\n\t<dependencies>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-web</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t<artifactId>spring-cloud-starter-oauth2</artifactId>\n\t\t</dependency>\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t<artifactId>spring-cloud-starter-openfeign</artifactId>\n\t\t</dependency>\n\n\t\t<dependency>\n\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t<artifactId>spring-boot-starter-test</artifactId>\n\t\t\t<scope>test</scope>\n\t\t</dependency>\n\t</dependencies>\n\n\t<dependencyManagement>\n\t\t<dependencies>\n\t\t\t<dependency>\n\t\t\t\t<groupId>org.springframework.cloud</groupId>\n\t\t\t\t<artifactId>spring-cloud-dependencies</artifactId>\n\t\t\t\t<version>${spring-cloud.version}</version>\n\t\t\t\t<type>pom</type>\n\t\t\t\t<scope>import</scope>\n\t\t\t</dependency>\n\t\t</dependencies>\n\t</dependencyManagement>\n\n\t<build>\n\t\t<plugins>\n\t\t\t<plugin>\n\t\t\t\t<groupId>org.springframework.boot</groupId>\n\t\t\t\t<artifactId>spring-boot-maven-plugin</artifactId>\n\t\t\t</plugin>\n\t\t</plugins>\n\t</build>\n\n\n</project>\n"
  },
  {
    "path": "service-hi/src/main/java/com/service/hi/servicehi/ServiceHiApplication.java",
    "content": "package com.service.hi.servicehi;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.netflix.eureka.EnableEurekaClient;\nimport org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;\n\n@SpringBootApplication\n@EnableEurekaClient\npublic class ServiceHiApplication {\n\n\tpublic static void main(String[] args) {\n\t\tSpringApplication.run(ServiceHiApplication.class, args);\n\t}\n}\n"
  },
  {
    "path": "service-hi/src/main/java/com/service/hi/servicehi/config/OAuth2ClientConfig.java",
    "content": "package com.service.hi.servicehi.config;\r\n\r\nimport feign.RequestInterceptor;\r\nimport org.springframework.boot.context.properties.ConfigurationProperties;\r\nimport org.springframework.boot.context.properties.EnableConfigurationProperties;\r\nimport org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;\r\nimport org.springframework.context.annotation.Bean;\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;\r\nimport org.springframework.security.oauth2.client.OAuth2RestTemplate;\r\nimport org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;\r\nimport org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;\r\n\r\n\r\n@EnableOAuth2Client\r\n@EnableConfigurationProperties\r\n@Configuration\r\npublic class OAuth2ClientConfig {\r\n\r\n    @Bean\r\n    @ConfigurationProperties(prefix = \"security.oauth2.client\")\r\n    public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {\r\n        return new ClientCredentialsResourceDetails();\r\n    }\r\n\r\n    @Bean\r\n    public RequestInterceptor oauth2FeignRequestInterceptor() {\r\n        return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), clientCredentialsResourceDetails());\r\n    }\r\n\r\n    @Bean\r\n    public OAuth2RestTemplate clientCredentialsRestTemplate() {\r\n        return new OAuth2RestTemplate(clientCredentialsResourceDetails());\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-hi/src/main/java/com/service/hi/servicehi/config/ResourceServerConfiguration.java",
    "content": "package com.service.hi.servicehi.config;\r\n\r\nimport org.springframework.context.annotation.Configuration;\r\nimport org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;\r\nimport org.springframework.security.config.annotation.web.builders.HttpSecurity;\r\nimport org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;\r\nimport org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;\r\nimport org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;\r\n\r\n@Configuration\r\n@EnableResourceServer\r\n@EnableGlobalMethodSecurity(prePostEnabled = true)\r\npublic class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {\r\n\r\n\r\n    @Override\r\n    public void configure(HttpSecurity http) throws Exception {\r\n        http.authorizeRequests()\r\n                .antMatchers(\"/order/**\").authenticated(); // 配置order访问控制，必须认证后才可以访问\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-hi/src/main/java/com/service/hi/servicehi/controller/TestEndPointController.java",
    "content": "package com.service.hi.servicehi.controller;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.security.core.Authentication;\r\nimport org.springframework.security.oauth2.provider.OAuth2Authentication;\r\nimport org.springframework.web.bind.annotation.GetMapping;\r\nimport org.springframework.web.bind.annotation.PathVariable;\r\nimport org.springframework.web.bind.annotation.RestController;\r\n\r\nimport java.security.Principal;\r\n\r\n@RestController\r\npublic class TestEndPointController {\r\n\r\n    Logger logger = LoggerFactory.getLogger(TestEndPointController.class);\r\n\r\n    @GetMapping(\"/product/{id}\")\r\n    public String getProduct(@PathVariable String id) {\r\n//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\r\n        return \"product id : \" + id;\r\n    }\r\n\r\n    @GetMapping(\"/order/{id}\")\r\n    public String getOrder(@PathVariable String id) {\r\n//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\r\n        return \"order id : \" + id;\r\n    }\r\n\r\n    @GetMapping(\"/getPrinciple\")\r\n    public OAuth2Authentication getPrinciple(OAuth2Authentication oAuth2Authentication, Principal principal, Authentication authentication) {\r\n        logger.info(oAuth2Authentication.getUserAuthentication().getAuthorities().toString());\r\n        logger.info(oAuth2Authentication.toString());\r\n        logger.info(\"principal.toString() \" + principal.toString());\r\n        logger.info(\"principal.getName() \" + principal.getName());\r\n        logger.info(\"authentication: \" + authentication.getAuthorities().toString());\r\n\r\n        return oAuth2Authentication;\r\n    }\r\n}\r\n"
  },
  {
    "path": "service-hi/src/main/resources/application.yml",
    "content": "eureka:\r\n  client:\r\n    service-url:\r\n      defaultZone: http://localhost:8761/eureka/\r\nserver:\r\n  port: 8765\r\nspring:\r\n  application:\r\n    name: service-hi\r\n#  datasource:\r\n#      driver-class-name: com.mysql.jdbc.Driver\r\n#      url: jdbc:mysql://172.16.10.44:3306/spring-cloud-auth?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8\r\n#      username: dev\r\n#      password: NHdev2015\r\n#\r\n#  jpa:\r\n#    hibernate:\r\n#      ddl-auto: update\r\n#    show-sql: true\r\n\r\nsecurity:\r\n  oauth2:\r\n    resource:\r\n      user-info-uri: http://localhost:9098/users/current\r\n    client:\r\n      id: client_2\r\n      client-secret: 123456\r\n      access-token-uri: http://localhost:9098/oauth/token\r\n      grant-type: client_credentials,password\r\n      scope: server\r\n\r\n\r\n"
  },
  {
    "path": "service-hi/src/test/java/com/service/hi/servicehi/ServiceHiApplicationTests.java",
    "content": "package com.service.hi.servicehi;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit4.SpringRunner;\n\n@RunWith(SpringRunner.class)\n@SpringBootTest\npublic class ServiceHiApplicationTests {\n\n\t@Test\n\tpublic void contextLoads() {\n\t}\n\n}\n"
  }
]