feat: 初始化
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>febs-common</artifactId>
|
||||
<groupId>com.yida.data</groupId>
|
||||
<version>2.2-RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>febs-common-security-starter</artifactId>
|
||||
<name>FEBS-Common-Security-Starter</name>
|
||||
<description>FEBS-Common-Security-Starter安全模块</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yida.data</groupId>
|
||||
<artifactId>febs-common-core</artifactId>
|
||||
<version>${febs-cloud.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-oauth2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package cc.mrbird.febs.common.security.starter.annotation;
|
||||
|
||||
import cc.mrbird.febs.common.security.starter.configure.FebsCloudResourceServerConfigure;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author MrBird
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(FebsCloudResourceServerConfigure.class)
|
||||
public @interface EnableFebsCloudResourceServer {
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package cc.mrbird.febs.common.security.starter.configure;
|
||||
|
||||
import com.yida.data.common.core.entity.constant.EndpointConstant;
|
||||
import com.yida.data.common.core.entity.constant.StringConstant;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
|
||||
|
||||
import cc.mrbird.febs.common.security.starter.handler.FebsAccessDeniedHandler;
|
||||
import cc.mrbird.febs.common.security.starter.handler.FebsAuthExceptionEntryPoint;
|
||||
import cc.mrbird.febs.common.security.starter.properties.FebsCloudSecurityProperties;
|
||||
|
||||
/**
|
||||
* 资源配置
|
||||
*/
|
||||
@EnableResourceServer
|
||||
@EnableAutoConfiguration(exclude = UserDetailsServiceAutoConfiguration.class)
|
||||
public class FebsCloudResourceServerConfigure extends ResourceServerConfigurerAdapter {
|
||||
|
||||
private FebsCloudSecurityProperties properties;
|
||||
private FebsAccessDeniedHandler accessDeniedHandler;
|
||||
private FebsAuthExceptionEntryPoint exceptionEntryPoint;
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setProperties(FebsCloudSecurityProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setAccessDeniedHandler(FebsAccessDeniedHandler accessDeniedHandler) {
|
||||
this.accessDeniedHandler = accessDeniedHandler;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setExceptionEntryPoint(FebsAuthExceptionEntryPoint exceptionEntryPoint) {
|
||||
this.exceptionEntryPoint = exceptionEntryPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
if (properties == null) {
|
||||
permitAll(http);
|
||||
return;
|
||||
}
|
||||
String[] anonUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens(properties.getAnonUris(), StringConstant.COMMA);
|
||||
if (ArrayUtils.isEmpty(anonUrls)) {
|
||||
anonUrls = new String[]{};
|
||||
}
|
||||
if (ArrayUtils.contains(anonUrls, EndpointConstant.ALL)) {
|
||||
permitAll(http);
|
||||
return;
|
||||
}
|
||||
http.csrf().disable()
|
||||
.requestMatchers().antMatchers(properties.getAuthUri())
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers(anonUrls).permitAll()
|
||||
.antMatchers(properties.getAuthUri()).authenticated()
|
||||
.and()
|
||||
.httpBasic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(ResourceServerSecurityConfigurer resources) {
|
||||
if (exceptionEntryPoint != null) {
|
||||
resources.authenticationEntryPoint(exceptionEntryPoint);
|
||||
}
|
||||
if (accessDeniedHandler != null) {
|
||||
resources.accessDeniedHandler(accessDeniedHandler);
|
||||
}
|
||||
}
|
||||
|
||||
private void permitAll(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable();
|
||||
http.authorizeRequests().anyRequest().permitAll();
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package cc.mrbird.febs.common.security.starter.configure;
|
||||
|
||||
import com.yida.data.common.core.entity.constant.FebsConstant;
|
||||
import com.yida.data.common.core.utils.FebsUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import cc.mrbird.febs.common.security.starter.handler.FebsAccessDeniedHandler;
|
||||
import cc.mrbird.febs.common.security.starter.handler.FebsAuthExceptionEntryPoint;
|
||||
import cc.mrbird.febs.common.security.starter.properties.FebsCloudSecurityProperties;
|
||||
import feign.RequestInterceptor;
|
||||
|
||||
/**
|
||||
* @author MrBird
|
||||
*/
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||
@EnableConfigurationProperties(FebsCloudSecurityProperties.class)
|
||||
@ConditionalOnProperty(value = "febs.cloud.security.enable", havingValue = "true", matchIfMissing = true)
|
||||
public class FebsCloudSecurityAutoConfigure extends GlobalMethodSecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "accessDeniedHandler")
|
||||
public FebsAccessDeniedHandler accessDeniedHandler() {
|
||||
return new FebsAccessDeniedHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "authenticationEntryPoint")
|
||||
public FebsAuthExceptionEntryPoint authenticationEntryPoint() {
|
||||
return new FebsAuthExceptionEntryPoint();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = PasswordEncoder.class)
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FebsCloudSecurityInteceptorConfigure febsCloudSecurityInteceptorConfigure() {
|
||||
return new FebsCloudSecurityInteceptorConfigure();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean(DefaultTokenServices.class)
|
||||
public FebsUserInfoTokenServices febsUserInfoTokenServices(ResourceServerProperties properties) {
|
||||
return new FebsUserInfoTokenServices(properties.getUserInfoUri(), properties.getClientId());
|
||||
}
|
||||
|
||||
/**
|
||||
* feign过滤器
|
||||
*/
|
||||
@Bean
|
||||
public RequestInterceptor oauth2FeignRequestInterceptor() {
|
||||
return requestTemplate -> {
|
||||
String gatewayToken = new String(Base64Utils.encode(FebsConstant.GATEWAY_TOKEN_VALUE.getBytes()));
|
||||
|
||||
requestTemplate.header(FebsConstant.GATEWAY_TOKEN_HEADER, gatewayToken);
|
||||
if (FebsUtil.isLogin()) {
|
||||
String authorizationToken = FebsUtil.getCurrentTokenValue();
|
||||
if (StringUtils.isNotBlank(authorizationToken)) {
|
||||
requestTemplate.header(HttpHeaders.AUTHORIZATION, FebsConstant.OAUTH2_TOKEN_TYPE + authorizationToken);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
||||
return new OAuth2MethodSecurityExpressionHandler();
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package cc.mrbird.febs.common.security.starter.configure;
|
||||
|
||||
import cc.mrbird.febs.common.security.starter.interceptor.FebsServerProtectInterceptor;
|
||||
import cc.mrbird.febs.common.security.starter.properties.FebsCloudSecurityProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @author MrBird
|
||||
*/
|
||||
public class FebsCloudSecurityInteceptorConfigure implements WebMvcConfigurer {
|
||||
|
||||
private FebsCloudSecurityProperties properties;
|
||||
|
||||
@Autowired
|
||||
public void setProperties(FebsCloudSecurityProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerInterceptor febsServerProtectInterceptor() {
|
||||
FebsServerProtectInterceptor febsServerProtectInterceptor = new FebsServerProtectInterceptor();
|
||||
febsServerProtectInterceptor.setProperties(properties);
|
||||
return febsServerProtectInterceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("all")
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(febsServerProtectInterceptor());
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package cc.mrbird.febs.common.security.starter.configure;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.FixedAuthoritiesExtractor;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.FixedPrincipalExtractor;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestOperations;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Request;
|
||||
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 重写UserInfoTokenServices
|
||||
* {@link UserInfoTokenServices#loadAuthentication(String)}
|
||||
*
|
||||
* @author MrBird
|
||||
*/
|
||||
public class FebsUserInfoTokenServices implements ResourceServerTokenServices {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private final String userInfoEndpointUrl;
|
||||
private final String clientId;
|
||||
private OAuth2RestOperations restTemplate;
|
||||
private String tokenType = "Bearer";
|
||||
private AuthoritiesExtractor authoritiesExtractor = new FixedAuthoritiesExtractor();
|
||||
private PrincipalExtractor principalExtractor = new FixedPrincipalExtractor();
|
||||
|
||||
public FebsUserInfoTokenServices(String userInfoEndpointUrl, String clientId) {
|
||||
this.userInfoEndpointUrl = userInfoEndpointUrl;
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public void setTokenType(String tokenType) {
|
||||
this.tokenType = tokenType;
|
||||
}
|
||||
|
||||
public void setRestTemplate(OAuth2RestOperations restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
public void setAuthoritiesExtractor(AuthoritiesExtractor authoritiesExtractor) {
|
||||
Assert.notNull(authoritiesExtractor, "AuthoritiesExtractor must not be null");
|
||||
this.authoritiesExtractor = authoritiesExtractor;
|
||||
}
|
||||
|
||||
public void setPrincipalExtractor(PrincipalExtractor principalExtractor) {
|
||||
Assert.notNull(principalExtractor, "PrincipalExtractor must not be null");
|
||||
this.principalExtractor = principalExtractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException {
|
||||
Map<String, Object> map = this.getMap(this.userInfoEndpointUrl, accessToken);
|
||||
String error = "error";
|
||||
if (map.containsKey(error)) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("userinfo returned error: " + map.get(error));
|
||||
}
|
||||
|
||||
throw new InvalidTokenException(accessToken);
|
||||
} else {
|
||||
return this.extractAuthentication(map);
|
||||
}
|
||||
}
|
||||
|
||||
private OAuth2Authentication extractAuthentication(Map<String, Object> map) {
|
||||
Object principal = this.getPrincipal(map);
|
||||
List<GrantedAuthority> authorities = this.authoritiesExtractor.extractAuthorities(map);
|
||||
|
||||
String oauth2RequestString = JSONObject.toJSONString(map.get("oauth2Request"));
|
||||
JSONObject oauth2Request = JSONObject.parseObject(oauth2RequestString);
|
||||
TypeReference<Set<String>> setTypeReference = new TypeReference<Set<String>>() {
|
||||
};
|
||||
|
||||
Map<String, String> requestParameters = JSONObject.parseObject(oauth2Request.getString("requestParameters"), new TypeReference<Map<String, String>>() {
|
||||
});
|
||||
boolean approved = oauth2Request.getBooleanValue("approved");
|
||||
Set<String> scope = JSONObject.parseObject(oauth2Request.getString("scope"), setTypeReference);
|
||||
Set<String> resourceIds = JSONObject.parseObject(oauth2Request.getString("resourceIds"), setTypeReference);
|
||||
String redirectUri = oauth2Request.getString("redirectUri");
|
||||
Set<String> responseTypes = JSONObject.parseObject(oauth2Request.getString("responseTypes"), setTypeReference);
|
||||
Map<String, Serializable> extensions = JSONObject.parseObject(oauth2Request.getString("extensions"), new TypeReference<Map<String, Serializable>>() {
|
||||
});
|
||||
|
||||
OAuth2Request request = new OAuth2Request(requestParameters, this.clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions);
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(principal, "N/A", authorities);
|
||||
token.setDetails(map);
|
||||
return new OAuth2Authentication(request, token);
|
||||
}
|
||||
|
||||
protected Object getPrincipal(Map<String, Object> map) {
|
||||
Object principal = this.principalExtractor.extractPrincipal(map);
|
||||
return principal == null ? "unknown" : principal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessToken readAccessToken(String accessToken) {
|
||||
throw new UnsupportedOperationException("Not supported: read access token");
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private Map<String, Object> getMap(String path, String accessToken) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Getting user info from: " + path);
|
||||
}
|
||||
|
||||
try {
|
||||
OAuth2RestOperations restTemplate = this.restTemplate;
|
||||
if (restTemplate == null) {
|
||||
BaseOAuth2ProtectedResourceDetails resource = new BaseOAuth2ProtectedResourceDetails();
|
||||
resource.setClientId(this.clientId);
|
||||
restTemplate = new OAuth2RestTemplate(resource);
|
||||
}
|
||||
|
||||
OAuth2AccessToken existingToken = restTemplate.getOAuth2ClientContext().getAccessToken();
|
||||
if (existingToken == null || !accessToken.equals(existingToken.getValue())) {
|
||||
DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(accessToken);
|
||||
token.setTokenType(this.tokenType);
|
||||
restTemplate.getOAuth2ClientContext().setAccessToken(token);
|
||||
}
|
||||
|
||||
return (Map) restTemplate.getForEntity(path, Map.class, new Object[0]).getBody();
|
||||
} catch (Exception e) {
|
||||
this.logger.warn("Could not fetch user details: " + e.getClass() + ", " + e.getMessage());
|
||||
return Collections.singletonMap("error", "Could not fetch user details");
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package cc.mrbird.febs.common.security.starter.handler;
|
||||
|
||||
import com.yida.data.common.core.entity.FebsResponse;
|
||||
import com.yida.data.common.core.utils.FebsUtil;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 无权限处理
|
||||
*/
|
||||
public class FebsAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
|
||||
FebsResponse febsResponse = new FebsResponse();
|
||||
FebsUtil.makeJsonResponse(response, HttpServletResponse.SC_FORBIDDEN, febsResponse.message("没有权限访问该资源"));
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package cc.mrbird.febs.common.security.starter.handler;
|
||||
|
||||
import com.yida.data.common.core.entity.FebsResponse;
|
||||
import com.yida.data.common.core.utils.FebsUtil;
|
||||
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 认证失败处理
|
||||
*/
|
||||
@Slf4j
|
||||
public class FebsAuthExceptionEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
String requestUri = request.getRequestURI();
|
||||
int status = HttpServletResponse.SC_UNAUTHORIZED;
|
||||
String message = "访问令牌不合法";
|
||||
log.error("客户端访问{}请求失败: {}", requestUri, message, authException);
|
||||
FebsUtil.makeJsonResponse(response, status, new FebsResponse().message(message));
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package cc.mrbird.febs.common.security.starter.interceptor;
|
||||
|
||||
import com.yida.data.common.core.entity.FebsResponse;
|
||||
import com.yida.data.common.core.entity.constant.FebsConstant;
|
||||
import com.yida.data.common.core.utils.FebsUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import cc.mrbird.febs.common.security.starter.properties.FebsCloudSecurityProperties;
|
||||
|
||||
/**
|
||||
* 只能通过网关获取资源
|
||||
*/
|
||||
public class FebsServerProtectInterceptor implements HandlerInterceptor {
|
||||
|
||||
private FebsCloudSecurityProperties properties;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws IOException {
|
||||
if (!properties.getOnlyFetchByGateway()) {
|
||||
return true;
|
||||
}
|
||||
String token = request.getHeader(FebsConstant.GATEWAY_TOKEN_HEADER);
|
||||
String gatewayToken = new String(Base64Utils.encode(FebsConstant.GATEWAY_TOKEN_VALUE.getBytes()));
|
||||
if (StringUtils.equals(gatewayToken, token)) {
|
||||
return true;
|
||||
} else {
|
||||
FebsResponse febsResponse = new FebsResponse();
|
||||
FebsUtil.makeJsonResponse(response, HttpServletResponse.SC_FORBIDDEN, febsResponse.message("请通过网关获取资源"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setProperties(FebsCloudSecurityProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package cc.mrbird.febs.common.security.starter.properties;
|
||||
|
||||
import com.yida.data.common.core.entity.constant.EndpointConstant;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author MrBird
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "febs.cloud.security")
|
||||
public class FebsCloudSecurityProperties {
|
||||
|
||||
/**
|
||||
* 是否开启安全配置
|
||||
*/
|
||||
private Boolean enable;
|
||||
/**
|
||||
* 配置需要认证的uri,默认为所有/**
|
||||
*/
|
||||
private String authUri = EndpointConstant.ALL;
|
||||
/**
|
||||
* 免认证资源路径,支持通配符
|
||||
* 多个值时使用逗号分隔
|
||||
*/
|
||||
private String anonUris;
|
||||
/**
|
||||
* 是否只能通过网关获取资源
|
||||
*/
|
||||
private Boolean onlyFetchByGateway = Boolean.TRUE;
|
||||
|
||||
public Boolean getEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(Boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public String getAuthUri() {
|
||||
return authUri;
|
||||
}
|
||||
|
||||
public void setAuthUri(String authUri) {
|
||||
this.authUri = authUri;
|
||||
}
|
||||
|
||||
public String getAnonUris() {
|
||||
return anonUris;
|
||||
}
|
||||
|
||||
public void setAnonUris(String anonUris) {
|
||||
this.anonUris = anonUris;
|
||||
}
|
||||
|
||||
public Boolean getOnlyFetchByGateway() {
|
||||
return onlyFetchByGateway;
|
||||
}
|
||||
|
||||
public void setOnlyFetchByGateway(Boolean onlyFetchByGateway) {
|
||||
this.onlyFetchByGateway = onlyFetchByGateway;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FebsCloudSecurityProperties{" +
|
||||
"enable=" + enable +
|
||||
", authUri='" + authUri + '\'' +
|
||||
", anonUris='" + anonUris + '\'' +
|
||||
", onlyFetchByGateway=" + onlyFetchByGateway +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"groups": [
|
||||
{
|
||||
"name": "febs.doc",
|
||||
"type": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"name": "febs.doc.base-package",
|
||||
"type": "java.lang.String",
|
||||
"description": "接口扫描路径,如Controller路径",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.description",
|
||||
"type": "java.lang.String",
|
||||
"description": "文档描述",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.description-color",
|
||||
"type": "java.lang.String",
|
||||
"description": "文档描述颜色",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties",
|
||||
"defaultValue": "#42b983"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.description-font-size",
|
||||
"type": "java.lang.String",
|
||||
"description": "文档描述字体大小",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties",
|
||||
"defaultValue": "14"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.email",
|
||||
"type": "java.lang.String",
|
||||
"description": "联系方式:邮箱",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.enable",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "是否开启doc功能",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.license",
|
||||
"type": "java.lang.String",
|
||||
"description": "协议",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.license-url",
|
||||
"type": "java.lang.String",
|
||||
"description": "协议地址",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.name",
|
||||
"type": "java.lang.String",
|
||||
"description": "联系方式:姓名",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.terms-of-service-url",
|
||||
"type": "java.lang.String",
|
||||
"description": "服务url",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.title",
|
||||
"type": "java.lang.String",
|
||||
"description": "文档标题",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.url",
|
||||
"type": "java.lang.String",
|
||||
"description": "联系方式:个人网站url",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
},
|
||||
{
|
||||
"name": "febs.doc.version",
|
||||
"type": "java.lang.String",
|
||||
"description": "版本",
|
||||
"sourceType": "cc.mrbird.febs.common.doc.starter.properties.FebsDocProperties"
|
||||
}
|
||||
],
|
||||
"hints": []
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
cc.mrbird.febs.common.security.starter.configure.FebsCloudSecurityAutoConfigure
|
||||
Reference in New Issue
Block a user