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