diff --git a/framework-core/pom.xml b/framework-core/pom.xml index c8e67c4..e8557e9 100644 --- a/framework-core/pom.xml +++ b/framework-core/pom.xml @@ -5,7 +5,7 @@ com.unionmed unionmed-framework - 0.0.2 + 0.0.4 4.0.0 @@ -46,6 +46,11 @@ runtime true + @@ -165,6 +170,24 @@ ${project.name}-${project.parent.version} + + + diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/AuthAccessed.java b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthAccessed.java new file mode 100644 index 0000000..ae28a6e --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthAccessed.java @@ -0,0 +1,36 @@ +package com.unionmed.framework.authentication; + +/** + * @author ianChen + * @date 2023/2/22 16:42 + */ +public class AuthAccessed { + + private boolean success; + private Object info; + private BasicAuth basicAuth; + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public Object getInfo() { + return info; + } + + public void setInfo(Object info) { + this.info = info; + } + + public BasicAuth getBasicAuth() { + return basicAuth; + } + + public void setBasicAuth(BasicAuth basicAuth) { + this.basicAuth = basicAuth; + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/AuthFilter.java b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthFilter.java new file mode 100644 index 0000000..7b8ea4b --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthFilter.java @@ -0,0 +1,43 @@ +package com.unionmed.framework.authentication; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.unionmed.framework.bean.BeanFactory; +import com.unionmed.framework.http.HttpHeaders; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * @author ianChen + * @date 2023/2/22 10:11 + */ +public class AuthFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + try { + AuthenticationPrinciple principle = BeanFactory.getBean(AuthenticationPrinciple.class); + AuthAccessed authAccessed = principle.isAccessAllowed(request, response); + if (PathMatcher.match(request.getRequestURI()) || (authAccessed != null && authAccessed.isSuccess())) { + if (authAccessed != null) { + TokenHelper.set(authAccessed.getBasicAuth()); + } + filterChain.doFilter(request, response); + return; + } + + response.setContentType(HttpHeaders.APPLICATION_JSON_UTF8); + PrintWriter pw = response.getWriter(); + pw.print(new ObjectMapper().writeValueAsString(authAccessed.getInfo())); + pw.flush(); + pw.close(); + } finally { + TokenHelper.clear(); + } + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationAutoConfiguration.java b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationAutoConfiguration.java new file mode 100644 index 0000000..575ba0a --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationAutoConfiguration.java @@ -0,0 +1,45 @@ +package com.unionmed.framework.authentication; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.servlet.DispatcherType; + +/** + * @author ianChen + * @date 2023/2/22 14:37 + */ +@Configuration +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@ConditionalOnBean({AuthenticationPrinciple.class}) +@EnableConfigurationProperties({AuthenticationProperties.class}) +public class AuthenticationAutoConfiguration { + + @Autowired + private RequestMappingHandlerMapping requestMappingHandlerMapping; + @Autowired + private AuthenticationProperties authenticationProperties; + + public static final String REGISTRATION_BEAN_NAME = "filterAuthenticationFilterRegistrationBean"; + public static final String FILTER_NAME = "authenticationFilter"; + + @Bean(name = REGISTRATION_BEAN_NAME) + @ConditionalOnMissingBean(name = REGISTRATION_BEAN_NAME) + protected FilterRegistrationBean authFilter() { + PathMatcher.doScan(requestMappingHandlerMapping, authenticationProperties); + + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR); + registration.setFilter(new AuthFilter()); + registration.setName(FILTER_NAME); + registration.setOrder(1); + return registration; + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationPrinciple.java b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationPrinciple.java new file mode 100644 index 0000000..bc7c824 --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationPrinciple.java @@ -0,0 +1,13 @@ +package com.unionmed.framework.authentication; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author ianChen + * @date 2023/2/22 14:36 + */ +public interface AuthenticationPrinciple { + + AuthAccessed isAccessAllowed(HttpServletRequest request, HttpServletResponse response); +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationProperties.java b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationProperties.java new file mode 100644 index 0000000..388dd5d --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/AuthenticationProperties.java @@ -0,0 +1,25 @@ +package com.unionmed.framework.authentication; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +/** + * @author ianChen + * @date 2023/2/24 9:43 + */ +@ConfigurationProperties( + prefix = "unionmed.authentication" +) +public class AuthenticationProperties { + + private List excludePatterns; + + public List getExcludePatterns() { + return excludePatterns; + } + + public void setExcludePatterns(List excludePatterns) { + this.excludePatterns = excludePatterns; + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/BasicAuth.java b/framework-core/src/main/java/com/unionmed/framework/authentication/BasicAuth.java new file mode 100644 index 0000000..3074460 --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/BasicAuth.java @@ -0,0 +1,63 @@ +package com.unionmed.framework.authentication; + +/** + * @author ianChen + * @date 2023/2/23 9:42 + */ +public class BasicAuth { + + private String token; + private String choscode; + private String id; + private String name; + private int gender; + private String idcard; + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getChoscode() { + return choscode; + } + + public void setChoscode(String choscode) { + this.choscode = choscode; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getGender() { + return gender; + } + + public void setGender(int gender) { + this.gender = gender; + } + + public String getIdcard() { + return idcard; + } + + public void setIdcard(String idcard) { + this.idcard = idcard; + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/PathMatcher.java b/framework-core/src/main/java/com/unionmed/framework/authentication/PathMatcher.java new file mode 100644 index 0000000..456b15b --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/PathMatcher.java @@ -0,0 +1,80 @@ +package com.unionmed.framework.authentication; + +import com.unionmed.framework.authentication.annotation.AuthGuest; +import com.unionmed.framework.util.ObjectUtils; +import org.springframework.util.AntPathMatcher; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author ianChen + * @date 2023/2/23 10:03 + */ +public class PathMatcher { + + private static final AtomicReference> PATHS = new AtomicReference<>(); + private static final AntPathMatcher MATCHER = new AntPathMatcher(); + + private static Set getExcludePatterns() { + Set paths = new HashSet<>(); + paths.add("/swagger-resources/**"); + paths.add("/webjars/**"); + paths.add("/v2/**"); + paths.add("/csrf"); + paths.add("/swagger-ui.html/**"); + paths.add("/doc.html"); + + return paths; + } + + private static void add(Set target, Collection source) { + if (ObjectUtils.isEmpty(source)) return; + + for (String s : source) { + if (ObjectUtils.notEmpty(s)) + target.add(s); + } + } + + static void doScan(RequestMappingHandlerMapping requestMappingHandlerMapping, AuthenticationProperties properties) { + Map map = requestMappingHandlerMapping.getHandlerMethods(); + + Set patterns = new HashSet<>(); + add(patterns, getExcludePatterns()); + add(patterns, properties.getExcludePatterns()); + + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().getBeanType().getName().startsWith("com.unionmed")) { + AuthGuest ag = entry.getValue().getMethod().getAnnotation(AuthGuest.class); + if (ag == null) { + ag = entry.getValue().getBeanType().getAnnotation(AuthGuest.class); + } + if (ag != null) { + patterns.addAll(entry.getKey().getPatternsCondition().getPatterns()); + } + } + } + + PATHS.set(patterns); + } + + public static boolean match(String path) { + if (ObjectUtils.notEmpty(PATHS.get())) { + if (PATHS.get().contains(path)) return true; + + for (String pattern : PATHS.get()) { + if (MATCHER.match(pattern, path)) + return true; + } + } + + return false; + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/TokenHelper.java b/framework-core/src/main/java/com/unionmed/framework/authentication/TokenHelper.java new file mode 100644 index 0000000..8d65d79 --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/TokenHelper.java @@ -0,0 +1,35 @@ +package com.unionmed.framework.authentication; + +/** + * @author ianChen + * @date 2023/2/22 16:40 + */ +public class TokenHelper { + + private static final ThreadLocal AUTH_CACHE = new ThreadLocal<>(); + private static final BasicAuth EMPTY_AUTH = new BasicAuth(); + + static void set(BasicAuth ba) { + AUTH_CACHE.set(ba); + } + + public static BasicAuth get() { + return AUTH_CACHE.get() == null ? EMPTY_AUTH : AUTH_CACHE.get(); + } + + public static String getToken() { + return get().getToken(); + } + + public static String getId() { + return get().getId(); + } + + public static String getIdcard() { + return get().getIdcard(); + } + + static final void clear() { + AUTH_CACHE.remove(); + } +} diff --git a/framework-core/src/main/java/com/unionmed/framework/authentication/annotation/AuthGuest.java b/framework-core/src/main/java/com/unionmed/framework/authentication/annotation/AuthGuest.java new file mode 100644 index 0000000..ce06243 --- /dev/null +++ b/framework-core/src/main/java/com/unionmed/framework/authentication/annotation/AuthGuest.java @@ -0,0 +1,16 @@ +package com.unionmed.framework.authentication.annotation; + +import org.springframework.web.bind.annotation.Mapping; + +import java.lang.annotation.*; + +/** + * @author ianChen + * @date 2023/2/22 17:10 + */ +@Mapping +@Documented +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuthGuest { +} diff --git a/framework-orm/pom.xml b/framework-orm/pom.xml index 8477125..3b15ddb 100644 --- a/framework-orm/pom.xml +++ b/framework-orm/pom.xml @@ -5,7 +5,7 @@ unionmed-framework com.unionmed - 0.0.2 + 0.0.4 4.0.0 diff --git a/framework-test/pom.xml b/framework-test/pom.xml index e299fa4..b1570f3 100644 --- a/framework-test/pom.xml +++ b/framework-test/pom.xml @@ -5,7 +5,7 @@ com.unionmed unionmed-framework - 0.0.2 + 0.0.4 4.0.0 diff --git a/pom.xml b/pom.xml index a58b10c..cf4936a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 com.unionmed unionmed-framework - 0.0.2 + 0.0.4 pom unionmed-framework