Spring Cloud 之 Oauth2

1. Create a server Eureka

  a. Create SpringBoot project, dependent on selected Eureka Server

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        ...

    </dependencies>

 

  b. Modify configuration application.yml

spring:
  application:
    name: eureka-server

server:
  port: 8081

eureka:
  instance:
    hostname: localhost
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    fetch-registry: false
    register-with-eureka: false

 

  c. Start the class to add annotations @EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }

}

 

 

2. Create Oauth2 server

  a. Create SpringBoot project, dependent on selected Eureka Discovery, Web, Spring Data Redis, Cloud Oauth2

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

        .....

    </dependencies>

 

  b. Modify configuration application.yml

spring:
  application:
    name: oauth-client
  redis:
    host: localhost
    database: 0

server:
  port: 8082

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8081/eureka/

 

  c.创建 AuthorizationServerConfiguration 继承 AuthorizationServerConfigurerAdapter

@Configuration 
@EnableAuthorizationServer 
public  class AuthorizationServerConfiguration the extends AuthorizationServerConfigurerAdapter { 

    @Resource 
    the AuthenticationManager the authenticationManager; 

    @Resource 
    RedisConnectionFactory redisConnectionFactory; 

    @Override 
    public  void Configure (ClientDetailsServiceConfigurer Clients) throws Exception { 
        String finalSecret = "{} bcrypt" + new new . BCryptPasswordEncoder () encode ( "123456 " ); 

        // disposed two clients, a password for authentication for authentication client_credentials
        clients.inMemory().withClient("client_1")
                .authorizedGrantTypes("client_credentials", "refresh_token")
                .scopes("server")
                .authorities("oauth2")
                .secret(finalSecret)
                .and().withClient("client_2")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("select")
                .authorities("oauth2")
                .secret(finalSecret);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory))
                .authenticationManager(authenticationManager)
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        // 允许表单认证
        security.allowFormAuthenticationForClients();
    }

}

 

  d. create SecurityConfiguration inherited WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        //模拟用户-角色,可换为从DB查询
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String finalPassword = "{bcrypt}" + bCryptPasswordEncoder.encode("123456");

        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user").password(finalPassword).authorities("ROLE_USER").build());
        manager.createUser(User.withUsername("vip").password(finalPassword).authorities("ROLE_VIP").build());
        manager.createUser(User.withUsername("admin").password(finalPassword).authorities("ROLE_ADMIN").build());

        return manager;
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers().anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").permitAll();
    }

}

 

  e. External interfaces provide access to user information

@RestController
@RequestMapping("/users")
public class UserController {

    Logger logger = LoggerFactory.getLogger(UserController.class);

    @RequestMapping(value = "/current", method = RequestMethod.GET)
    public Principal getUser(Principal principal) {
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>");
        logger.info(principal.toString());
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>");
        return principal;
    }
}

 

  f. Start classes with the @EnableResourceServer comment open Resource Service

@SpringBootApplication
@EnableResourceServer
@EnableEurekaClient
public class OauthClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(OauthClientApplication.class, args);
    }

}

 

 

3. Create a resource server

  a. Create SpringBoot project, dependent on selected Eureka Discovery, Web, Cloud Oauth2 and Feign

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        .....

    </dependencies>

 

  b. Modify configuration application.yml

Eureka: 
  Client: 
    Service - url: 
      defaultzone: HTTP: // localhost: 8081 / Eureka / 
Server: 
  Port: 8083 
the Spring: 
  the Application: 
    name: Service - Client 
Security: 
  oauth2: 
    # user information url 
    Resource: 
      the User -info-uri: HTTP: // localhost: 8082 / the Users / Current
     # client information with oauth-client configurations consistent 
    client: 
      the above mentioned id: client_1 
      client -secret: 123456 
      Access Addr-uri: HTTP: // localhost: 8082 / oauth / token 
      Grant -type: client_credentials,password
      scope: server

 

  c. Create ResourceServerConfiguration inherited ResourceServerConfigurerAdapter

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/order/**").hasAnyRole("ADMIN", "VIP")
                .antMatchers("/product/**").authenticated();
    }

}

 

  d. create OAuth2ClientConfig, add annotations @ EnableOAuth2Client open OAuth2 Client function

@EnableOAuth2Client
@EnableConfigurationProperties
@Configuration
public class OAuth2ClientConfig {

    @Bean
    @ConfigurationProperties(prefix = "security.oauth2.client")
    public ClientCredentialsResourceDetails clientCredentialsResourceDetails() {
        return new ClientCredentialsResourceDetails();
    }

    @Bean
    public RequestInterceptor oauth2FeignRequestInterceptor() {
        return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(), clientCredentialsResourceDetails());
    }

    @Bean
    public OAuth2RestTemplate clientCredentialsRestTemplate() {
        return new OAuth2RestTemplate(clientCredentialsResourceDetails());
    }

}

 

  e. Create Controller test

@RestController
public class CommonController {

    Logger logger = LoggerFactory.getLogger(CommonController.class);

    @GetMapping("/product/{id}")
    public String getProduct(@PathVariable String id) {
        return "product id : " + id;
    }

    @GetMapping("/order/{id}")
    public String getOrder(@PathVariable String id) {
        return "order id : " + id;
    }

    @GetMapping("/getPrinciple")
    public OAuth2Authentication getPrinciple(OAuth2Authentication oAuth2Authentication, Principal principal, Authentication authentication) {
        logger.info(oAuth2Authentication.getUserAuthentication().getAuthorities().toString());
        logger.info(oAuth2Authentication.toString());
        logger.info("principal.toString() " + principal.toString());
        logger.info("principal.getName() " + principal.getName());
        logger.info("authentication: " + authentication.getAuthorities().toString());

        return oAuth2Authentication;
    }

}

 

  f. Start classes are added @EnableEurekaClient notes indicate Eureka client

@SpringBootApplication
@EnableEurekaClient
public class ServiceHiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceHiApplication.class, args);
    }
}

 

 

4. Test:

  a. Eureka in turn starts the server, Oauth2 server, server resources (Redis also need to start)

  b.打开浏览器访问 http://localhost:8082/oauth/token?username=user&password=123456&grant_type=password&scope=select&client_id=client_2&client_secret=123456 获取 access_token

  . c, respectively, without a token visit http: // localhost: 8083 / order / 1 and with a token visit  http: // localhost: 8083 / order / 1 access_token = d3631d4b-f710-468b-aa3f-26d72a23064a?

  . d respectively without a token visit  http: // localhost: 8083 / product / 1  and with a token visit  http: // localhost: 8083 / product / 1 access_token = d3631d4b-f710-468b-aa3f-26d72a23064a?

 

 

5. Reference documents: https: //www.jianshu.com/p/3427549a148a

Guess you like

Origin www.cnblogs.com/vettel0329/p/11783284.html