parent
50b0ca2a01
commit
cf7b290bbb
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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> authFilter() { |
||||||
|
PathMatcher.doScan(requestMappingHandlerMapping, authenticationProperties); |
||||||
|
|
||||||
|
FilterRegistrationBean<AuthFilter> 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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
@ -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<String> excludePatterns; |
||||||
|
|
||||||
|
public List<String> getExcludePatterns() { |
||||||
|
return excludePatterns; |
||||||
|
} |
||||||
|
|
||||||
|
public void setExcludePatterns(List<String> excludePatterns) { |
||||||
|
this.excludePatterns = excludePatterns; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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<Set<String>> PATHS = new AtomicReference<>(); |
||||||
|
private static final AntPathMatcher MATCHER = new AntPathMatcher(); |
||||||
|
|
||||||
|
private static Set<String> getExcludePatterns() { |
||||||
|
Set<String> 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<String> target, Collection<String> 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<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods(); |
||||||
|
|
||||||
|
Set<String> patterns = new HashSet<>(); |
||||||
|
add(patterns, getExcludePatterns()); |
||||||
|
add(patterns, properties.getExcludePatterns()); |
||||||
|
|
||||||
|
for (Map.Entry<RequestMappingInfo, HandlerMethod> 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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.unionmed.framework.authentication; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ianChen |
||||||
|
* @date 2023/2/22 16:40 |
||||||
|
*/ |
||||||
|
public class TokenHelper { |
||||||
|
|
||||||
|
private static final ThreadLocal<BasicAuth> 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(); |
||||||
|
} |
||||||
|
} |
@ -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 { |
||||||
|
} |
Loading…
Reference in new issue