diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java index 4deacff3d..9b4bc08b6 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java @@ -6,6 +6,7 @@ import org.hswebframework.web.authorization.access.DataAccessHandler; import org.hswebframework.web.authorization.basic.aop.AopMethodAuthorizeDefinitionParser; import org.hswebframework.web.authorization.basic.embed.EmbedAuthenticationManager; import org.hswebframework.web.authorization.basic.handler.DefaultAuthorizingHandler; +import org.hswebframework.web.authorization.basic.handler.UserAllowPermissionHandler; import org.hswebframework.web.authorization.basic.handler.access.DefaultDataAccessController; import org.hswebframework.web.authorization.basic.web.*; import org.hswebframework.web.authorization.basic.web.session.UserTokenAutoExpiredListener; @@ -76,6 +77,12 @@ public class AuthorizingHandlerAutoConfiguration { return new EmbedAuthenticationManager(); } + @Bean + @ConditionalOnProperty("hsweb.authorize.allows") + public UserAllowPermissionHandler userAllowPermissionHandler() { + return new UserAllowPermissionHandler(); + } + @Bean public UserOnSignIn userOnSignIn(UserTokenManager userTokenManager) { return new UserOnSignIn(userTokenManager); diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/UserAllowPermissionHandler.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/UserAllowPermissionHandler.java new file mode 100644 index 000000000..920f7f8da --- /dev/null +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/UserAllowPermissionHandler.java @@ -0,0 +1,75 @@ +package org.hswebframework.web.authorization.basic.handler; + +import lombok.Getter; +import lombok.Setter; +import org.hswebframework.web.authorization.define.AuthorizingContext; +import org.hswebframework.web.authorization.listener.event.AuthorizingHandleBeforeEvent; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.event.EventListener; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.ClassUtils; +import org.springframework.util.PathMatcher; + +import java.util.*; + +/** + *
+ *     hsweb:
+ *        authorize:
+ *            allows:
+ *               users:
+ *                  admin: *
+ *                  guest: **.query*
+ *               roles:
+ *                  admin: *
+ *
+ * 
+ * + * @author zhouhao + * @since 3.0.1 + */ +@ConfigurationProperties("hsweb.authorize") +public class UserAllowPermissionHandler { + + @Getter + @Setter + private Map> allows = new HashMap<>(); + + private PathMatcher pathMatcher = new AntPathMatcher("."); + + @EventListener + public void handEvent(AuthorizingHandleBeforeEvent event) { + AuthorizingContext context = event.getContext(); + if (allows.isEmpty()) { + return; + } + // package.method + String path = ClassUtils.getUserClass(context.getParamContext() + .getTarget()) + .getName().concat(".") + .concat(context.getParamContext() + .getMethod().getName()); + + String userId = context.getAuthentication().getUser().getId(); + boolean allow; + allow = Optional.ofNullable(allows.get("users")) + .map(users -> users.get(userId)) + .filter(pattern -> "*".equals(pattern) || pathMatcher.match(pattern, path)) + .isPresent(); + if (allow) { + event.setAllow(true); + return; + } + allow = context.getAuthentication() + .getRoles() + .stream() + .map(role -> allows.getOrDefault("roles", Collections.emptyMap()).get(role.getId())) + .filter(Objects::nonNull) + .anyMatch(pattern -> "*".equals(pattern) || pathMatcher.match(pattern, path)); + if (allow) { + event.setAllow(true); + return; + } + } + +}