添加SpringCloud Feign支持,添加对mall-admin服务的调用

This commit is contained in:
macro
2019-10-18 17:03:48 +08:00
parent fe96c7aab0
commit 2af06bbdd6
13 changed files with 190 additions and 176 deletions

View File

@@ -26,21 +26,19 @@
<groupId>com.macro.mall</groupId>
<artifactId>mall-mbg</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -3,7 +3,9 @@ package com.macro.mall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class MallDemoApplication{

View File

@@ -1,56 +0,0 @@
package com.macro.mall.demo.bo;
import com.macro.mall.model.UmsAdmin;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Arrays;
import java.util.Collection;
/**
* SpringSecurity需要的用户详情
*/
public class AdminUserDetails implements UserDetails {
private UmsAdmin umsAdmin;
public AdminUserDetails(UmsAdmin umsAdmin) {
this.umsAdmin = umsAdmin;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
//返回当前用户的权限
return Arrays.asList(new SimpleGrantedAuthority("TEST"));
}
@Override
public String getPassword() {
return umsAdmin.getPassword();
}
@Override
public String getUsername() {
return umsAdmin.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}

View File

@@ -0,0 +1,32 @@
package com.macro.mall.demo.component;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
/**
* 用于Feign传递请求头的拦截器
* Created by macro on 2019/10/18.
*/
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
requestTemplate.header(name, values);
}
}
}
}
}

View File

@@ -0,0 +1,23 @@
package com.macro.mall.demo.config;
import com.macro.mall.demo.component.FeignRequestInterceptor;
import feign.Logger;
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by macro on 2019/9/5.
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
RequestInterceptor requestInterceptor() {
return new FeignRequestInterceptor();
}
}

View File

@@ -1,5 +1,6 @@
package com.macro.mall.demo.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@@ -11,6 +12,7 @@ import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}

View File

@@ -1,82 +0,0 @@
package com.macro.mall.demo.config;
import com.macro.mall.demo.bo.AdminUserDetails;
import com.macro.mall.mapper.UmsAdminMapper;
import com.macro.mall.model.UmsAdmin;
import com.macro.mall.model.UmsAdminExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.List;
/**
* SpringSecurity的配置
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UmsAdminMapper umsAdminMapper;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()//配置权限
// .antMatchers("/").access("hasRole('TEST')")//该路径需要TEST角色
.antMatchers("/").authenticated()//该路径需要登录认证
// .antMatchers("/brand/list").hasAuthority("TEST")//该路径需要TEST权限
.antMatchers("/**").permitAll()
.antMatchers("/actuator/**")// 允许SpringBoot Admin 访问监控信息
.permitAll()
.and()//启用基于http的认证
.httpBasic()
.realmName("/")
.and()//配置登录页面
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.and()//配置退出路径
.logout()
.logoutSuccessUrl("/")
// .and()//记住密码功能
// .rememberMe()
// .tokenValiditySeconds(60*60*24)
// .key("rememberMeKey")
.and()//关闭跨域伪造
.csrf()
.disable()
.headers()//去除X-Frame-Options
.frameOptions()
.disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
}
@Bean
public UserDetailsService userDetailsService() {
//获取登录用户信息
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UmsAdminExample example = new UmsAdminExample();
example.createCriteria().andUsernameEqualTo(username);
List<UmsAdmin> umsAdminList = umsAdminMapper.selectByExample(example);
if (umsAdminList != null && umsAdminList.size() > 0) {
return new AdminUserDetails(umsAdminList.get(0));
}
throw new UsernameNotFoundException("用户名或密码错误");
}
};
}
}

View File

@@ -6,10 +6,17 @@ import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* Swagger2API文档的配置
*/
@@ -21,17 +28,51 @@ public class Swagger2Config {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.macro.mall.demo"))
.apis(RequestHandlerSelectors.basePackage("com.macro.mall.demo.controller"))
.paths(PathSelectors.any())
.build();
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("SwaggerUI演示")
.description("Demo模块")
.title("mall-demo系统")
.description("SpringCloud版本中的一些示例")
.contact("macro")
.version("1.0")
.build();
}
private List<ApiKey> securitySchemes() {
//设置请求头信息
List<ApiKey> result = new ArrayList<>();
ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
result.add(apiKey);
return result;
}
private List<SecurityContext> securityContexts() {
//设置需要登录认证的路径
List<SecurityContext> result = new ArrayList<>();
result.add(getContextByPath("/feign/admin/brand.*"));
return result;
}
private SecurityContext getContextByPath(String pathRegex){
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex(pathRegex))
.build();
}
private List<SecurityReference> defaultAuth() {
List<SecurityReference> result = new ArrayList<>();
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
result.add(new SecurityReference("Authorization", authorizationScopes));
return result;
}
}

View File

@@ -0,0 +1,36 @@
package com.macro.mall.demo.controller;
/**
* Created by macro on 2019/10/18.
*/
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.demo.dto.UmsAdminLoginParam;
import com.macro.mall.demo.service.FeignAdminService;
import com.macro.mall.model.PmsBrand;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Feign调用mall-admin接口示例
*/
@Api(tags = "FeignAdminController", description = "Feign调用mall-admin接口示例")
@RestController
@RequestMapping("/feign/admin")
public class FeignAdminController {
@Autowired
private FeignAdminService adminService;
@PostMapping("/login")
public CommonResult login(@RequestBody UmsAdminLoginParam loginParam) {
return adminService.login(loginParam);
}
@GetMapping("/brand/listAll")
public CommonResult getBrandList(){
return adminService.getList();
}
}

View File

@@ -0,0 +1,19 @@
package com.macro.mall.demo.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.validator.constraints.NotEmpty;
/**
* 用户登录参数
* Created by macro on 2018/4/26.
*/
@Getter
@Setter
public class UmsAdminLoginParam {
@ApiModelProperty(value = "用户名", required = true)
private String username;
@ApiModelProperty(value = "密码", required = true)
private String password;
}

View File

@@ -0,0 +1,21 @@
package com.macro.mall.demo.service;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.demo.dto.UmsAdminLoginParam;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* Created by macro on 2019/10/18.
*/
@FeignClient("mall-admin")
public interface FeignAdminService {
@PostMapping("/admin/login")
CommonResult login(@RequestBody UmsAdminLoginParam loginParam);
@GetMapping("/brand/listAll")
CommonResult getList();
}

View File

@@ -7,12 +7,6 @@ spring:
url: jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root
thymeleaf:
mode: HTML5
encoding: utf-8
servlet:
content-type: text/html
cache: false #开发时关闭缓存,不然没法看到实时页面
mybatis:
mapper-locations:
- classpath:mapper/*.xml
@@ -21,11 +15,10 @@ logging:
level:
root: info #日志配置DEBUG,INFO,WARN,ERROR
com.macro.mall: debug
# file: demo_log.log #配置日志生成路径
# path: /var/logs #配置日志文件名称
com.macro.mall.demo.service.FeignAdminService: debug
host:
mall:
admin: http://localhost:8080
admin: http://mall-admin
eureka:
client:
register-with-eureka: true

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>localhost:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<root level="INFO">
<!--使用logstash时打开-->
<appender-ref ref="LOGSTASH" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>