diff --git a/samples/sureness-spring-boot-starter-example/pom.xml b/samples/sureness-spring-boot-starter-example/pom.xml index 4ba8f8321bc0033c44e965b6290ed71c70ae54b4..039f8ca7ef66020c5d1eca29c8f0fe836394da8f 100644 --- a/samples/sureness-spring-boot-starter-example/pom.xml +++ b/samples/sureness-spring-boot-starter-example/pom.xml @@ -15,7 +15,7 @@ UTF-8 UTF-8 1.8 - 1.0.0-beta.1 + 1.0.0-beta.2 diff --git a/samples/sureness-spring-boot-starter-example/src/main/java/com/usthe/sureness/bootstrap/BootstrapApplication.java b/samples/sureness-spring-boot-starter-example/src/main/java/com/usthe/sureness/bootstrap/BootstrapApplication.java index 271b30bc60fe7e2e88491f4477f16ce401094acb..65a075d1a16ab6f190e75d88dc4e14fe360ed26c 100644 --- a/samples/sureness-spring-boot-starter-example/src/main/java/com/usthe/sureness/bootstrap/BootstrapApplication.java +++ b/samples/sureness-spring-boot-starter-example/src/main/java/com/usthe/sureness/bootstrap/BootstrapApplication.java @@ -8,7 +8,6 @@ import org.springframework.boot.web.servlet.ServletComponentScan; * @author wangtao */ @SpringBootApplication -@ServletComponentScan public class BootstrapApplication { public static void main(String[] args) { diff --git a/samples/sureness-spring-boot-starter-example/src/main/resources/application.yml b/samples/sureness-spring-boot-starter-example/src/main/resources/application.yml index 15f21dd48624bcb53331b5db27a47166afce9517..4f6403b0cdbe2cad3830282eb892d7f3cbb02e63 100644 --- a/samples/sureness-spring-boot-starter-example/src/main/resources/application.yml +++ b/samples/sureness-spring-boot-starter-example/src/main/resources/application.yml @@ -10,14 +10,16 @@ logging: root: info sureness: - enabled: true - authTypes: - - Jwt - - Basic - - Digest + container: servlet + auth-types: + - digest + - basic + - jwt support-types: - Servlet - Websocket + session-enabled: true + websocket-enabled: true jwt: secret-key: ?::4s9ssf2sf4sed45pf):RnLN7XNn4wARoQXizIv6MHUsIV+EFfiMw/x7R0ntu4aWr/CWuApcFajCyaFv0bwq2Eik0jdrKUtsA6bx3sDJeFV643R+YYzGMRIqcBIp6AKA98GM2RIqcBIp6-?::4390fsf4sdl6opf)4ZI:tdQMtcQQ14pkOAQdQ546 annotation: diff --git a/support/spring-boot-starter-sureness/pom.xml b/support/spring-boot-starter-sureness/pom.xml index f75f2e1d928f9dc41b04d90a51c9f9e7f5a01cc8..c5c5438d7fd77af83fb9e32297d3ef8d4f1be3df 100644 --- a/support/spring-boot-starter-sureness/pom.xml +++ b/support/spring-boot-starter-sureness/pom.xml @@ -53,7 +53,7 @@ 1.8 1.8 UTF-8 - 1.0.4-beta.2 + 1.0.5 2.4.5 diff --git a/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessAutoConfiguration.java b/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessAutoConfiguration.java index 54b0299a97d80785a0fdcef2def9db12bd5cb93e..f3c984148ee32d48d65bc88fd99b321364909bab 100644 --- a/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessAutoConfiguration.java +++ b/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessAutoConfiguration.java @@ -54,6 +54,7 @@ import org.springframework.context.annotation.Configuration; import javax.servlet.Filter; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -75,8 +76,6 @@ public class SurenessAutoConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(SurenessAutoConfiguration.class); - private static final int NUM_2 = 2; - private ApplicationContext applicationContext; private SurenessProperties surenessProperties; @@ -94,11 +93,8 @@ public class SurenessAutoConfiguration { @Bean @ConditionalOnMissingBean(PathTreeProvider.class) - PathTreeProvider pathTreeProvider(DefaultPathRoleMatcher pathRoleMatcher){ - PathTreeProvider pathTreeProvider = new DocumentPathTreeProvider(); - pathRoleMatcher.setPathTreeProvider(pathTreeProvider); - pathRoleMatcher.buildTree(); - return pathTreeProvider; + PathTreeProvider pathTreeProvider(){ + return new DocumentPathTreeProvider(); } @Bean @@ -107,76 +103,73 @@ public class SurenessAutoConfiguration { SubjectFactory subjectFactory() { SubjectFactory subjectFactory = new SurenessSubjectFactory(); List subjectCreates = new ArrayList<>(); - Set authTypes = surenessProperties.getAuthTypes(); - if (authTypes == null || authTypes.isEmpty()) { + AuthType[] authTypeArr = surenessProperties.getAuthTypes(); + Set authTypes = authTypeArr == null ? new HashSet<>() : new HashSet<>(Arrays.asList(authTypeArr)); + if (authTypes.isEmpty()) { // if is null, default config is basic auth, jwt auth LOGGER.info("[sureness-starter] - use default authTypes: Basic, Jwt"); authTypes = new HashSet<>(2); authTypes.add(AuthType.BASIC); authTypes.add(AuthType.JWT); - surenessProperties.setAuthTypes(authTypes); } - Set supportTypes = surenessProperties.getSupportTypes(); - if (supportTypes == null || supportTypes.isEmpty()) { - // if is null, default config is servlet, websocket + ContainerType containerType = surenessProperties.getContainer(); + if (containerType == null) { + // if is null, default config is servlet LOGGER.info("[sureness-starter] - use default supportTypes: Servlet, Websocket"); - supportTypes = new HashSet<>(2); - supportTypes.add(SupportType.Servlet); - supportTypes.add(SupportType.WebSocket); - surenessProperties.setSupportTypes(supportTypes); + containerType = ContainerType.Servlet; } - if (supportTypes.size() >= NUM_2 && !supportTypes.contains(SupportType.WebSocket)) { - LOGGER.error("[sureness-starter] - supportTypes: Servlet, JAX-RS or Spring-Reactor neither can exist at the same time"); - throw new SurenessInitException("[sureness-starter] - supportTypes: Servlet, JAX-RS or Spring-Reactor neither can exist at the same time"); - } - if (supportTypes.contains(SupportType.Servlet)) { - subjectCreates.add(new NoneSubjectServletCreator()); - if (supportTypes.contains(SupportType.WebSocket)) { - subjectCreates.add(new JwtSubjectWsServletCreator()); - } - if (authTypes.contains(AuthType.BASIC)){ - subjectCreates.add(new BasicSubjectServletCreator()); - } - if (authTypes.contains(AuthType.JWT)){ - subjectCreates.add(new JwtSubjectServletCreator()); - subjectCreates.add(new JwtSubjectWsServletCreator()); - } - if (authTypes.contains(AuthType.DIGEST)){ - subjectCreates.add(new DigestSubjectServletCreator()); - } - if (surenessProperties.isSessionEnabled()) { - subjectCreates.add(new SessionSubjectServletCreator()); - } - } else if (supportTypes.contains(SupportType.JAX_RS)){ - // other is JAX-RS - subjectCreates.add(new NoneSubjectJaxRsCreator()); - if (supportTypes.contains(SupportType.WebSocket)) { - subjectCreates.add(new JwtSubjectWsJaxRsCreator()); - } - if (authTypes.contains(AuthType.BASIC)){ - subjectCreates.add(new BasicSubjectJaxRsCreator()); - } - if (authTypes.contains(AuthType.JWT)){ - subjectCreates.add(new JwtSubjectJaxRsCreator()); - subjectCreates.add(new JwtSubjectWsJaxRsCreator()); - } - if (authTypes.contains(AuthType.DIGEST)){ - subjectCreates.add(new DigestSubjectJaxRsCreator()); - } - } else if (supportTypes.contains(SupportType.Spring_Reactor)) { - subjectCreates.add(new NoneSubjectSpringReactiveCreator()); - if (supportTypes.contains(SupportType.WebSocket)) { - subjectCreates.add(new JwtSubjectWsSpringReactiveCreator()); - } - if (authTypes.contains(AuthType.BASIC)) { - subjectCreates.add(new BasicSubjectSpringReactiveCreator()); - } - if (authTypes.contains(AuthType.JWT)) { - subjectCreates.add(new JwtSubjectSpringReactiveCreator()); - } - if (authTypes.contains(AuthType.DIGEST)) { - subjectCreates.add(new DigestSubjectSpringReactiveCreator()); - } + boolean enableWebsocket = surenessProperties.isWebsocketEnabled(); + switch (containerType) { + case Servlet: + subjectCreates.add(new NoneSubjectServletCreator()); + if (enableWebsocket) { + subjectCreates.add(new JwtSubjectWsServletCreator()); + } + if (authTypes.contains(AuthType.BASIC)){ + subjectCreates.add(new BasicSubjectServletCreator()); + } + if (authTypes.contains(AuthType.JWT)){ + subjectCreates.add(new JwtSubjectServletCreator()); + subjectCreates.add(new JwtSubjectWsServletCreator()); + } + if (authTypes.contains(AuthType.DIGEST)){ + subjectCreates.add(new DigestSubjectServletCreator()); + } + if (surenessProperties.isSessionEnabled()) { + subjectCreates.add(new SessionSubjectServletCreator()); + } + break; + case JAX_RS: + subjectCreates.add(new NoneSubjectJaxRsCreator()); + if (enableWebsocket) { + subjectCreates.add(new JwtSubjectWsJaxRsCreator()); + } + if (authTypes.contains(AuthType.BASIC)){ + subjectCreates.add(new BasicSubjectJaxRsCreator()); + } + if (authTypes.contains(AuthType.JWT)){ + subjectCreates.add(new JwtSubjectJaxRsCreator()); + subjectCreates.add(new JwtSubjectWsJaxRsCreator()); + } + if (authTypes.contains(AuthType.DIGEST)){ + subjectCreates.add(new DigestSubjectJaxRsCreator()); + } + break; + case Spring_Reactor: + subjectCreates.add(new NoneSubjectSpringReactiveCreator()); + if (enableWebsocket) { + subjectCreates.add(new JwtSubjectWsSpringReactiveCreator()); + } + if (authTypes.contains(AuthType.BASIC)) { + subjectCreates.add(new BasicSubjectSpringReactiveCreator()); + } + if (authTypes.contains(AuthType.JWT)) { + subjectCreates.add(new JwtSubjectSpringReactiveCreator()); + } + if (authTypes.contains(AuthType.DIGEST)) { + subjectCreates.add(new DigestSubjectSpringReactiveCreator()); + } + default: break; } subjectFactory.registerSubjectCreator(subjectCreates); LOGGER.info("[sureness-starter] - SurenessSubjectFactory init success"); @@ -209,14 +202,14 @@ public class SurenessAutoConfiguration { List processorList = new LinkedList<>(); NoneProcessor noneProcessor = new NoneProcessor(); processorList.add(noneProcessor); - Set authTypes = surenessProperties.getAuthTypes(); - if (authTypes == null || authTypes.isEmpty()) { + AuthType[] authTypeArr = surenessProperties.getAuthTypes(); + Set authTypes = authTypeArr == null ? new HashSet<>() : new HashSet<>(Arrays.asList(authTypeArr)); + if (authTypes.isEmpty()) { // if is null, default config is basic auth, jwt auth LOGGER.info("[sureness-starter] - use default authTypes: Basic, Jwt"); authTypes = new HashSet<>(2); authTypes.add(AuthType.BASIC); authTypes.add(AuthType.JWT); - surenessProperties.setAuthTypes(authTypes); } if (authTypes.contains(AuthType.JWT)) { JwtProcessor jwtProcessor = new JwtProcessor(); @@ -241,12 +234,15 @@ public class SurenessAutoConfiguration { @Bean @ConditionalOnMissingBean(TreePathRoleMatcher.class) - TreePathRoleMatcher pathRoleMatcher(PathTreeProvider pathTreeProvider, - DefaultPathRoleMatcher pathRoleMatcher) { - List providers = new ArrayList<>(); - providers.add(pathTreeProvider); - // add documentProvider default - providers.add(new DocumentPathTreeProvider()); + TreePathRoleMatcher pathRoleMatcher(List pathTreeProviders) { + DefaultPathRoleMatcher pathRoleMatcher = new DefaultPathRoleMatcher(); + if (pathTreeProviders == null) { + pathTreeProviders = new ArrayList<>(); + } + if (pathTreeProviders.isEmpty()) { + // add documentProvider default + pathTreeProviders.add(new DocumentPathTreeProvider()); + } AnnotationProperties annotationProperties = surenessProperties.getAnnotation(); if (annotationProperties != null && annotationProperties.isEnable()) { List scanPackages = annotationProperties.getScanPackages(); @@ -255,32 +251,21 @@ public class SurenessAutoConfiguration { } else { AnnotationPathTreeProvider annotationPathTreeProvider = new AnnotationPathTreeProvider(); annotationPathTreeProvider.setScanPackages(scanPackages); - providers.add(annotationPathTreeProvider); + pathTreeProviders.add(annotationPathTreeProvider); } } - pathRoleMatcher.setPathTreeProviderList(providers); + pathRoleMatcher.setPathTreeProviderList(pathTreeProviders); pathRoleMatcher.buildTree(); return pathRoleMatcher; } - @Bean - @ConditionalOnMissingBean(DefaultPathRoleMatcher.class) - public DefaultPathRoleMatcher defaultPathRoleMatcher(){ - return new DefaultPathRoleMatcher(); - } - @Bean @ConditionalOnWebApplication - @ConditionalOnMissingBean(value = FilterRegistrationBean.class) - @ConditionalOnExpression("'${sureness.support-types}'.contains('com.usthe.sureness.configuration.SupportType.Servlet')") - public FilterRegistrationBean filterRegistration( - SecurityManager securityManager - ) { + @ConditionalOnExpression("'${sureness.container}'.equalsIgnoreCase('servlet')") + public FilterRegistrationBean filterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); - registration.setFilter(new SurenessFilter(securityManager)); registration.addUrlPatterns("/*"); - registration.setFilter((Filter) - applicationContext.getBean("surenessFilter")); + registration.setFilter((Filter) applicationContext.getBean("surenessFilter")); registration.setName("surenessFilter"); registration.setOrder(1); return registration; @@ -288,6 +273,7 @@ public class SurenessAutoConfiguration { @Bean @ConditionalOnMissingBean(name = "surenessFilter") + @ConditionalOnExpression("'${sureness.container}'.equalsIgnoreCase('servlet')") public Filter surenessFilter(SecurityManager securityManager){ return new SurenessFilter(securityManager); } diff --git a/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessFilter.java b/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessFilter.java index 5c096bd2f4b0c11717bd045e3a6ef06f206edfcf..1e1d9bb081fe6b3450b3ed3f806b81b6fa134b36 100644 --- a/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessFilter.java +++ b/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessFilter.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.PrintWriter; - /** * @author wangtao * @date 2021/7/8 @@ -72,7 +71,7 @@ public class SurenessFilter implements Filter { logger.debug("this request account info is illegal, {}", e1.getMessage()); responseWrite(ResponseEntity .status(HttpStatus.UNAUTHORIZED) - .body("Username or password is incorrect or expired"), servletResponse); + .body("Username or password is incorrect or token expired"), servletResponse); return; } catch (DisabledAccountException | ExcessiveAttemptsException e2 ) { logger.debug("the account is disabled, {}", e2.getMessage()); @@ -97,7 +96,7 @@ public class SurenessFilter implements Filter { servletResponse); return; } - + try { // if ok, doFilter and add subject in request filterChain.doFilter(servletRequest, servletResponse); diff --git a/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessProperties.java b/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessProperties.java index df6c014b0258d9c574398be729cc2feae9afd0fc..df61d79e7bcc3f8e6cd34c3683d54129d9a097c4 100644 --- a/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessProperties.java +++ b/support/spring-boot-starter-sureness/src/main/java/com/usthe/sureness/configuration/SurenessProperties.java @@ -4,7 +4,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.List; -import java.util.Set; /** * @author wangtao @@ -20,20 +19,25 @@ public class SurenessProperties { private boolean enabled = true; /** - * 可配置 支持 websocket, servlet, jax-rs或者其它容器协议 + * 可配置 支持 Servlet, JAX_RS, Spring_Reactor 容器协议 */ - private Set supportTypes; + private ContainerType container = ContainerType.Servlet; /** * 支持的认证方式 Jwt, basic auth, digest auth等其它认证方式 */ - private Set authTypes; + private AuthType[] authTypes = new AuthType[] {AuthType.BASIC, AuthType.JWT, AuthType.DIGEST}; /** - * 当 authType 为 jwt 时设置的属性 + * 当 authType 为 JWT 时设置的属性 */ private JwtProperties jwt; + /** + * 是否开启 websocket 的认证鉴权 + */ + private boolean websocketEnabled = true; + /** * 是否开启 session */ @@ -44,19 +48,11 @@ public class SurenessProperties { */ private AnnotationProperties annotation; - public Set getSupportTypes() { - return supportTypes; - } - - public void setSupportTypes(Set supportTypes) { - this.supportTypes = supportTypes; - } - - public Set getAuthTypes() { + public AuthType[] getAuthTypes() { return authTypes; } - public void setAuthTypes(Set authTypes) { + public void setAuthTypes(AuthType[] authTypes) { this.authTypes = authTypes; } @@ -92,6 +88,23 @@ public class SurenessProperties { this.annotation = annotation; } + public ContainerType getContainer() { + return container; + } + + public void setContainer(ContainerType container) { + this.container = container; + } + + public boolean isWebsocketEnabled() { + return websocketEnabled; + } + + public void setWebsocketEnabled(boolean websocketEnabled) { + this.websocketEnabled = websocketEnabled; + } + + public static enum AuthType { /** json web token auth **/ JWT, @@ -101,15 +114,13 @@ public class SurenessProperties { DIGEST } - public static enum SupportType { + public static enum ContainerType { /** http servlet **/ Servlet, /** jax-rs **/ JAX_RS, /** spring reactor stream **/ Spring_Reactor, - /** websocket **/ - WebSocket } public static class AnnotationProperties {