Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jia_RG
2018-10-10 12:14:30 +08:00
169 changed files with 706 additions and 402 deletions

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -1,11 +1,19 @@
package org.hswebframework.web.authorization.define;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
/**
* 权限控制上下文
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class AuthorizingContext {
private AuthorizeDefinition definition;

View File

@@ -1,18 +0,0 @@
package org.hswebframework.web.authorization.listener;
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
/**
* 授权监听器,用于监听授权过程,以及自定义授权逻辑
* 已弃用,请使用{@link org.springframework.context.ApplicationListener}
*
* @author zhouhao
* @see AuthorizationEvent
* @since 3.0
*/
@Deprecated
public interface AuthorizationListener<E extends AuthorizationEvent> {
void on(E event);
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package org.hswebframework.web.authorization.listener;
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import java.util.*;
/**
* {@link org.springframework.context.ApplicationEventPublisher}
* @author zhouhao
*/
@Deprecated
public class AuthorizationListenerDispatcher {
@Autowired
private ApplicationEventPublisher eventPublisher;
private Map<Class<? extends AuthorizationEvent>, List<AuthorizationListener>> listenerStore = new HashMap<>();
public <E extends AuthorizationEvent> void addListener(Class<E> eventClass, AuthorizationListener<E> listener) {
listenerStore.computeIfAbsent(eventClass, (k) -> new LinkedList<>())
.add(listener);
}
@SuppressWarnings("unchecked")
public <E extends AuthorizationEvent> int doEvent(Class<E> eventType, E event) {
eventPublisher.publishEvent(event);
// List<AuthorizationListener<E>> store = (List) listenerStore.get(eventType);
// if (null != store) {
// store.forEach(listener -> listener.on(event));
// return store.size();
// }
return 1;
}
@SuppressWarnings("unchecked")
public <E extends AuthorizationEvent> int doEvent(E event) {
eventPublisher.publishEvent(event);
return 1;
//return doEvent((Class<E>) event.getClass(), event);
}
}

View File

@@ -48,17 +48,18 @@ where name like ? or full_name like
where u_id in(?,?,?) and (name like ? or full_name like)
```
## 授权登录接口
http接口: `POST /authorize/login`, 登录接口支持2种`content-type`,`application/json`(Json RequestBody方式)和`application/x-www-form-urlencoded`(表单方式),
请在调用等时候指定对应等`content-type`.必要参数: `username``password`.
⚠️注意: 此接口只实现了简单的登录逻辑,不过会通过发布各种事件来实现自定义的逻辑处理.
1. `AuthorizationDecodeEvent` 在接收到登录请求之后触发,如果在登录前对用户名密码进行里加密,可以通过监听此事件实现对用户名密码的解密操作
2. `AuthorizationBeforeEvent``AuthorizationDecodeEvent`事件完成后触发,可通过监听此事件并获取请求参数,实现验证码功能
3. `AuthorizationSuccessEvent` 在授权成功后触发.注意: 权限控制模块也是通过监听此事件来完成授权
4. `AuthorizationFailedEvent` 授权失败时触发.当发生过程中异常时触发此事件
什么? 还不知道如何监听事件? [快看这里](https://github.com/hs-web/hsweb-framework/wiki/事件驱动)
# 会话状态
此模块默认使用sessionId绑定用户信息。还可以使用 [jwt](../hsweb-authorization-jwt) 方式
# 跨域设置
修改application.yml
```yaml
hsweb:
cors:
enabled: on
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
```

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -6,12 +6,14 @@ 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;
import org.hswebframework.web.authorization.token.UserTokenManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -75,6 +77,11 @@ public class AuthorizingHandlerAutoConfiguration {
return new EmbedAuthenticationManager();
}
@Bean
public UserAllowPermissionHandler userAllowPermissionHandler() {
return new UserAllowPermissionHandler();
}
@Bean
public UserOnSignIn userOnSignIn(UserTokenManager userTokenManager) {
return new UserOnSignIn(userTokenManager);
@@ -119,4 +126,16 @@ public class AuthorizingHandlerAutoConfiguration {
return bean;
}
}
@Configuration
@ConditionalOnProperty(prefix = "hsweb.authorize", name = "basic-authorization", havingValue = "true")
@ConditionalOnClass(UserTokenForTypeParser.class)
public static class BasicAuthorizationConfiguration {
@Bean
public BasicAuthorizationTokenParser basicAuthorizationTokenParser(AuthenticationManager authenticationManager,
UserTokenManager tokenManager) {
return new BasicAuthorizationTokenParser(authenticationManager, tokenManager);
}
}
}

View File

@@ -1,18 +1,20 @@
package org.hswebframework.web.authorization.starter;
package org.hswebframework.web.authorization.basic.configuration;
import org.apache.commons.codec.binary.Base64;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.AuthenticationManager;
import org.hswebframework.web.authorization.basic.web.AuthorizedToken;
import org.hswebframework.web.authorization.basic.web.ParsedToken;
import org.hswebframework.web.authorization.basic.web.UserTokenForTypeParser;
import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
import org.hswebframework.web.authorization.token.UserToken;
import org.hswebframework.web.authorization.token.UserTokenManager;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.service.authorization.UserService;
import javax.servlet.http.HttpServletRequest;
public class BasicAuthorizationTokenParser implements UserTokenForTypeParser {
private UserService userService;
private AuthenticationManager authenticationManager;
private UserTokenManager userTokenManager;
@@ -21,8 +23,8 @@ public class BasicAuthorizationTokenParser implements UserTokenForTypeParser {
return "basic";
}
public BasicAuthorizationTokenParser(UserService userService, UserTokenManager userTokenManager) {
this.userService = userService;
public BasicAuthorizationTokenParser(AuthenticationManager authenticationManager, UserTokenManager userTokenManager) {
this.authenticationManager = authenticationManager;
this.userTokenManager = userTokenManager;
}
@@ -56,12 +58,12 @@ public class BasicAuthorizationTokenParser implements UserTokenForTypeParser {
}
if (usernameAndPassword.contains(":")) {
String[] arr = usernameAndPassword.split("[:]");
UserEntity user = userService.selectByUserNameAndPassword(arr[0], arr[1]);
if (user != null) {
Authentication authentication = authenticationManager.authenticate(new PlainTextUsernamePasswordAuthenticationRequest(arr[0], arr[1]));
if (authentication != null) {
return new AuthorizedToken() {
@Override
public String getUserId() {
return user.getId();
return authentication.getUser().getId();
}
@Override
@@ -77,7 +79,7 @@ public class BasicAuthorizationTokenParser implements UserTokenForTypeParser {
@Override
public long getMaxInactiveInterval() {
//60分钟有效期
return 60*60*1000L;
return 60 * 60 * 1000L;
}
};
}

View File

@@ -11,6 +11,8 @@ import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfi
import org.hswebframework.web.validate.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
@@ -22,6 +24,7 @@ import java.util.Map;
* @since 3.0.0-RC
*/
@ConfigurationProperties(prefix = "hsweb")
@Order(Ordered.HIGHEST_PRECEDENCE)
public class EmbedAuthenticationManager implements AuthenticationManager {
private Map<String, Authentication> authentications = new HashMap<>();

View File

@@ -58,6 +58,8 @@ public class EmbedAuthenticationProperties {
private List<PermissionInfo> permissions = new ArrayList<>();
private Map<String, List<String>> permissionsSimple = new HashMap<>();
@Getter
@Setter
public static class PermissionInfo {
@@ -77,7 +79,9 @@ public class EmbedAuthenticationProperties {
user.setType(type);
authentication.setUser(user);
authentication.setRoles((List) roles);
List<Permission> permissionList = permissions.stream()
List<Permission> permissionList = new ArrayList<>();
permissionList.addAll(permissions.stream()
.map(info -> {
SimplePermission permission = new SimplePermission();
permission.setId(info.getId());
@@ -88,7 +92,16 @@ public class EmbedAuthenticationProperties {
.build()).collect(Collectors.toSet()));
return permission;
}).collect(Collectors.toList());
})
.collect(Collectors.toList()));
permissionList.addAll(permissionsSimple.entrySet().stream()
.map(entry -> {
SimplePermission permission = new SimplePermission();
permission.setId(entry.getKey());
permission.setActions(new HashSet<>(entry.getValue()));
return permission;
}).collect(Collectors.toList()));
authentication.setPermissions(permissionList);
return authentication;

View File

@@ -0,0 +1,78 @@
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.define.HandleType;
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.*;
/**
* <pre>
* hsweb:
* authorize:
* allows:
* users:
* admin: *
* guest: **.query*
* roles:
* admin: *
*
* </pre>
*
* @author zhouhao
* @since 3.0.1
*/
@ConfigurationProperties("hsweb.authorize")
public class UserAllowPermissionHandler {
@Getter
@Setter
private Map<String, Map<String, String>> allows = new HashMap<>();
private PathMatcher pathMatcher = new AntPathMatcher(".");
@EventListener
public void handEvent(AuthorizingHandleBeforeEvent event) {
if (allows.isEmpty() || event.getHandleType() == HandleType.DATA) {
return;
}
AuthorizingContext context = event.getContext();
// class full name.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;
}
}
}

View File

@@ -32,6 +32,7 @@ import org.hswebframework.web.logging.AccessLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@@ -77,9 +78,8 @@ public class AuthorizationController {
public ResponseMessage<Map<String, Object>> authorize(@ApiParam(example = "{\"username\":\"admin\",\"password\":\"admin\"}")
@RequestBody Map<String, String> parameter) {
return doLogin(Objects.requireNonNull(parameter.get("username"), "用户名不能为空")
, Objects.requireNonNull(parameter.get("password"), "密码不能为空")
, parameter);
return doLogin(parameter.get("username"), parameter.get("password"), parameter);
}
@PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@@ -93,6 +93,9 @@ public class AuthorizationController {
@SneakyThrows
protected ResponseMessage<Map<String, Object>> doLogin(String username, String password, Map<String, ?> parameter) {
Assert.hasLength(username, "用户名不能为空");
Assert.hasLength(password, "密码不能为空");
AuthorizationFailedEvent.Reason reason = AuthorizationFailedEvent.Reason.OTHER;
Function<String, Object> parameterGetter = parameter::get;
try {

View File

@@ -1,6 +1,5 @@
package org.hswebframework.web.authorization.basic.web;
import org.hswebframework.web.authorization.listener.AuthorizationListener;
import org.hswebframework.web.authorization.listener.event.AuthorizationSuccessEvent;
import org.hswebframework.web.authorization.token.UserToken;
import org.hswebframework.web.authorization.token.UserTokenHolder;

View File

@@ -1,5 +1,6 @@
package org.hswebframework.web.authorization.starter;
package org.hswebframework.web.authorization;
import org.hswebframework.web.authorization.basic.configuration.EnableAopAuthorize;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.test.context.web.WebAppConfiguration;
@@ -9,6 +10,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
*/
@SpringBootApplication
@WebAppConfiguration
@EnableAopAuthorize
public class TestApplication {
}

View File

@@ -2,6 +2,7 @@ package org.hswebframework.web.authorization.basic.embed
import org.hswebframework.web.authorization.Authentication
import org.hswebframework.web.authorization.AuthenticationManager
import org.hswebframework.web.authorization.TestApplication
import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
@@ -30,6 +31,7 @@ class EmbedAuthenticationManagerTest extends Specification {
authentication.getUser() != null
authentication.getUser().getName() == "超级管理员"
authentication.hasPermission("user-manager", "query")
authentication.hasPermission("test", "query")
authentication.getPermission("user-manager") != null
authentication.hasRole("user")
authentication.getPermission("user-manager")

View File

@@ -0,0 +1,24 @@
package org.hswebframework.web.authorization.basic.handler;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.controller.message.ResponseMessage;
/**
* @author zhouhao
* @since 3.0.1
*/
public class TestController {
public ResponseMessage<String> query() {
return ResponseMessage.ok();
}
public ResponseMessage<String> update() {
return ResponseMessage.ok();
}
public ResponseMessage<String> delete() {
return ResponseMessage.ok();
}
}

View File

@@ -0,0 +1,61 @@
package org.hswebframework.web.authorization.basic.handler
import org.hswebframework.web.authorization.Authentication
import org.hswebframework.web.authorization.AuthenticationManager
import org.hswebframework.web.authorization.TestApplication
import org.hswebframework.web.authorization.basic.define.EmptyAuthorizeDefinition
import org.hswebframework.web.authorization.define.AuthorizeDefinition
import org.hswebframework.web.authorization.define.AuthorizingContext
import org.hswebframework.web.authorization.define.HandleType
import org.hswebframework.web.authorization.listener.event.AuthorizingHandleBeforeEvent
import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest
import org.hswebframework.web.boost.aop.context.MethodInterceptorContext
import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.web.WebAppConfiguration
import spock.lang.Specification
/**
* @author zhouhao
* @since 3.0.1
*/
@WebAppConfiguration
@ContextConfiguration
@SpringBootTest(classes = [TestApplication.class], properties = ["classpath:application.yml"])
class UserAllowPermissionHandlerTest extends Specification {
@Autowired
UserAllowPermissionHandler handler;
@Autowired
private AuthenticationManager manager;
def createMethodInterceptorContext(TestController controller, String name) {
return new MethodInterceptorHolder(
"test"
, TestController.class.getMethod(name)
, controller
, new HashMap<String, Object>())
.createParamContext()
}
def "Test"() {
setup:
def authentication = manager.authenticate(new PlainTextUsernamePasswordAuthenticationRequest("admin", "admin"));
def definition = EmptyAuthorizeDefinition.instance;
def controller = new TestController();
def context = createMethodInterceptorContext(controller, "query");
def authorizingContext = new AuthorizingContext(
authentication: authentication
, definition: definition
, paramContext: context);
def event = new AuthorizingHandleBeforeEvent(authorizingContext, HandleType.RBAC);
handler.handEvent(event);
expect:
authentication != null
event.isAllow()
}
}

View File

@@ -1,19 +0,0 @@
package org.hswebframework.web.authorization.basic.embed;
import org.hswebframework.web.authorization.basic.configuration.AopAuthorizeAutoConfiguration;
import org.hswebframework.web.authorization.basic.configuration.AuthorizingHandlerAutoConfiguration;
import org.hswebframework.web.authorization.basic.configuration.EnableAopAuthorize;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.test.context.web.WebAppConfiguration;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@SpringBootApplication
@WebAppConfiguration
@EnableAopAuthorize
public class TestApplication {
}

View File

@@ -15,6 +15,10 @@ hsweb:
app:
name: hsweb-oauth2 客户端示例
version: 3.0.0
authorize:
allows:
users:
admin: "**.TestController.*"
users:
admin:
name: 超级管理员
@@ -25,6 +29,8 @@ hsweb:
name: 管理员
- id: user
name: 用户
permissions-simple:
test: query,get
permissions:
- id: user-manager
actions: query,get,update,delete

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-authorization-oauth2</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-authorization-oauth2</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-authorization-oauth2</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<!--<relativePath>../../pom.xml</relativePath>-->
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-boost</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-boost</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-boost</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons-dao</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons-dao</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -84,9 +84,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons-service</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-commons-service</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons-service</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -61,9 +61,8 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-concurrent</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -1,27 +1,22 @@
package org.hswebframework.web.async;
import lombok.SneakyThrows;
import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
import org.hswebframework.web.tests.SimpleWebApplicationTests;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.support.TransactionTemplate;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.Executors;
import static org.junit.Assert.*;
/**
*
* @author zhouhao
*/
public class TransactionSupportAsyncJobServiceTest extends SimpleWebApplicationTests {
@@ -42,11 +37,20 @@ public class TransactionSupportAsyncJobServiceTest extends SimpleWebApplicationT
}
}
@Before
@SneakyThrows
public void init() {
sqlExecutor.exec("create table test(id varchar(32))");
}
@After
@SneakyThrows
public void cleanup() {
sqlExecutor.exec("drop table test");
}
@Test
public void test() throws Exception {
sqlExecutor.exec("create table test(id varchar(32))");
try {
BatchAsyncJobContainer jobContainer = asyncJobService.batch();
jobContainer.submit(() -> {
@@ -66,9 +70,6 @@ public class TransactionSupportAsyncJobServiceTest extends SimpleWebApplicationT
@Test
public void testSimple() throws Exception {
sqlExecutor.exec("create table test(id varchar(32))");
try {
BatchAsyncJobContainer jobContainer = asyncJobService.batch();
jobContainer.submit(() -> {
@@ -85,6 +86,6 @@ public class TransactionSupportAsyncJobServiceTest extends SimpleWebApplicationT
} catch (Exception ignore) {
ignore.printStackTrace();
}
Assert.assertTrue(sqlExecutor.list("select * from test").size()>0);
Assert.assertTrue(sqlExecutor.list("select * from test").size() > 0);
}
}

View File

@@ -22,7 +22,7 @@
<parent>
<artifactId>hsweb-concurrent</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -22,7 +22,7 @@
<parent>
<artifactId>hsweb-concurrent-counter</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-concurrent-counter</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -22,7 +22,7 @@
<parent>
<artifactId>hsweb-concurrent</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-concurrent-lock</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-concurrent-lock</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-concurrent-lock</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -22,7 +22,7 @@
<parent>
<artifactId>hsweb-concurrent</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -22,7 +22,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-datasource</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-datasource</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -3,9 +3,12 @@ package org.hswebframework.web.datasource.jta;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.datasource.config.DynamicDataSourceConfig;
import javax.sql.XADataSource;
import java.sql.SQLException;
import java.util.Properties;
@@ -15,27 +18,34 @@ import java.util.Properties;
@EqualsAndHashCode(callSuper = true)
@Slf4j
@Data
public class AtomikosDataSourceConfig extends DynamicDataSourceConfig{
private static final long serialVersionUID = 5588085000663972571L;
private int minPoolSize = 5;
private int maxPoolSize = 200;
private int borrowConnectionTimeout = 60;
private int reapTimeout = 0;
private int maxIdleTime = 60;
private int maintenanceInterval = 60;
private int defaultIsolationLevel = -1;
private String xaDataSourceClassName = null;
private int loginTimeout = 0;
private String testQuery = null;
private int maxLifetime = 0;
private Properties xaProperties = null;
public class AtomikosDataSourceConfig extends DynamicDataSourceConfig {
private static final long serialVersionUID = 5588085000663972571L;
private int minPoolSize = 5;
private int maxPoolSize = 200;
private int borrowConnectionTimeout = 60;
private int reapTimeout = 0;
private int maxIdleTime = 60;
private int maintenanceInterval = 60;
private int defaultIsolationLevel = -1;
private String xaDataSourceClassName = null;
private int loginTimeout = 0;
private String testQuery = null;
private int maxLifetime = 0;
private Properties xaProperties = null;
//初始化超时时间
private int initTimeout = 10;
private int initTimeout = 10;
@SneakyThrows
public void putProperties(AtomikosDataSourceBean atomikosDataSourceBean) {
if (null != xaProperties) {
xaProperties.entrySet().forEach(entry -> entry.setValue(String.valueOf(entry.getValue())));
}
//fix #87
XADataSource dataSource = (XADataSource) Class.forName(getXaDataSourceClassName()).newInstance();
FastBeanCopier.copy(xaProperties, dataSource);
atomikosDataSourceBean.setXaDataSource(dataSource);
atomikosDataSourceBean.setXaDataSourceClassName(getXaDataSourceClassName());
atomikosDataSourceBean.setBorrowConnectionTimeout(getBorrowConnectionTimeout());
if (loginTimeout != 0) {

View File

@@ -9,6 +9,10 @@ spring:
url : jdbc:h2:mem:core;DB_CLOSE_ON_EXIT=FALSE
username : sa
password :
maxActive: 1000
initialSize: 5
minIdle: 5
maxWait: 50000
max-pool-size: 20
borrow-connection-timeout: 1000
connectionfactory:
@@ -31,6 +35,11 @@ hsweb:
url: jdbc:h2:mem:test;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
filters: stat
maxActive: 1000
initialSize: 5
minIdle: 5
maxWait: 50000
max-pool-size: 20
borrow-connection-timeout: 1000
test_ds2:

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-datasource</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-logging</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-logging</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-message</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-message</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -18,8 +18,6 @@ import static org.hswebframework.web.message.builder.StaticMessageSubjectBuilder
import static org.hswebframework.web.message.builder.StaticMessageSubjectBuilder.topic;
/**
* TODO 完成注释
*
* @author zhouhao
*/
@RunWith(SpringRunner.class)
@@ -50,7 +48,7 @@ public class JmsMessagerTest {
for (int i = 0; i < 100; i++) {
Thread.sleep(1000);
Thread.sleep(100);
messager.publish(text("hello jms"))
.to(queue("test"))
.send();
@@ -67,7 +65,7 @@ public class JmsMessagerTest {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
Thread.sleep(100);
messager.publish(text("hello jms"))
.to(topic("test"))
.send();

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-message</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-message</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -0,0 +1,30 @@
# 应用基本信息配置
```yaml
hsweb:
app:
name: my-application
comment: 我的应用
version: 1.0.0
auto-init: true # 启动服务时进行初始化(执行classpath*:/hsweb-starter.js)
```
# 跨域设置
修改application.yml
```yaml
hsweb:
cors:
enable: true
allowed-headers: "*"
allowed-methods: "*"
allowed-origins: "*"
allow-credentials: true
max-age: 14400
```
# json序列化配置
```yaml
fastjson:
features: WriteNullListAsEmpty,WriteNullNumberAsZero,WriteNullBooleanAsFalse
```

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-starter</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -18,13 +18,19 @@
package org.hswebframework.web.starter;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author zhouhao
*/
@ConfigurationProperties(prefix = "hsweb.app")
@Getter
@Setter
public class AppProperties {
private boolean autoInit = true;
private String name;
private String comment;
private String website;
@@ -38,36 +44,4 @@ public class AppProperties {
systemVersion.setVersion(version);
return systemVersion;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}

View File

@@ -18,6 +18,7 @@
package org.hswebframework.web.starter;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
import org.hswebframework.ezorm.rdb.meta.RDBDatabaseMetaData;
import org.hswebframework.ezorm.rdb.meta.parser.H2TableMetaParser;
@@ -63,6 +64,7 @@ import java.util.stream.Stream;
@Configuration
@EnableConfigurationProperties(AppProperties.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class SystemInitializeAutoConfiguration implements CommandLineRunner, BeanPostProcessor {
@Autowired
@@ -107,9 +109,14 @@ public class SystemInitializeAutoConfiguration implements CommandLineRunner, Bea
@Override
public void run(String... args) throws Exception {
if (!appProperties.isAutoInit()) {
log.debug("app auto init is disabled");
return;
}
DatabaseType type = DataSourceHolder.currentDatabaseType();
SystemVersion version = appProperties.build();
if(version.getName()==null){
if (version.getName() == null) {
version.setName("unknown");
}
Connection connection = null;

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -1,9 +1,9 @@
## 权限功能模块
1. 提供用户,角色管理,登录授权等功能
1. 提供用户,角色管理等基础功能
2. 提供统一的多维度,可拓展的权限分配
权限设置不再像以往那样和角色,用户直接关联.在hsweb里,权限设置是通用的.
权限设置不再像以往那样和角色,用户直接关联.在此模块里,权限设置是通用的.
你可以为用户,角色,自己定义的维度比如:机构,部门,岗位等维度进行权限分配.
而且不仅仅支持基本等RBAC权限控制,还可以自定义控制到数据行和列.
@@ -19,21 +19,6 @@
</dependency>
```
## 授权登录接口
http接口: `POST /authorize/login`, 登录接口支持2种`content-type`,`application/json`(Json RequestBody方式)和`application/x-www-form-urlencoded`(表单方式),
请在调用等时候指定对应等`content-type`.必要参数: `username``password`.
⚠️注意: 此接口只实现了简单的登录逻辑,不过会通过发布各种事件来实现自定义的逻辑处理.
1. `AuthorizationDecodeEvent` 在接收到登录请求之后触发,如果在登录前对用户名密码进行里加密,可以通过监听此事件实现对用户名密码的解密操作
2. `AuthorizationBeforeEvent``AuthorizationDecodeEvent`事件完成后触发,可通过监听此事件并获取请求参数,实现验证码功能
3. `AuthorizationSuccessEvent` 在授权成功后触发.注意: 权限控制模块也是通过监听此事件来完成授权
4. `AuthorizationFailedEvent` 授权失败时触发.当发生过程中异常时触发此事件
什么? 还不知道如何监听事件? [快看这里](https://github.com/hs-web/hsweb-framework/wiki/事件驱动)
## 权限设置
TODO
## 结构
![uml](./uml.png "uml.png")

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -1,5 +1,7 @@
package org.hswebframework.web.service.authorization.simple;
import lombok.Getter;
import lombok.Setter;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.AuthenticationInitializeService;
import org.hswebframework.web.authorization.AuthenticationManager;
@@ -25,6 +27,11 @@ public class SimpleAuthenticationManager implements AuthenticationManager {
private AuthenticationInitializeService authenticationInitializeService;
@Setter
@Getter
private AuthenticationManager parent;
@Autowired
private UserService userService;
@@ -38,6 +45,11 @@ public class SimpleAuthenticationManager implements AuthenticationManager {
this.authenticationInitializeService = authenticationInitializeService;
}
public SimpleAuthenticationManager(AuthenticationInitializeService authenticationInitializeService, AuthenticationManager parent) {
this.authenticationInitializeService = authenticationInitializeService;
this.parent = parent;
}
@Autowired
public void setAuthenticationInitializeService(AuthenticationInitializeService authenticationInitializeService) {
this.authenticationInitializeService = authenticationInitializeService;
@@ -45,6 +57,16 @@ public class SimpleAuthenticationManager implements AuthenticationManager {
@Override
public Authentication authenticate(AuthenticationRequest request) {
if (null != parent) {
try {
Authentication authentication = parent.authenticate(request);
if (null != authentication) {
return authentication;
}
} catch (Exception ignore) {
// ignore errors
}
}
if (request instanceof PlainTextUsernamePasswordAuthenticationRequest) {
String username = ((PlainTextUsernamePasswordAuthenticationRequest) request).getUsername();
String password = ((PlainTextUsernamePasswordAuthenticationRequest) request).getPassword();

View File

@@ -25,6 +25,7 @@ import org.springframework.cache.annotation.Caching;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@@ -78,7 +79,7 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
@Override
@Transactional(readOnly = true)
public UserEntity selectByUsername(String username) {
if (null == username) {
if (!StringUtils.hasLength(username)) {
return null;
}
return createQuery().where("username", username).single();
@@ -87,8 +88,8 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
@Override
@Transactional(readOnly = true)
public UserEntity selectByUserNameAndPassword(String plainUsername, String plainPassword) {
Objects.requireNonNull(plainUsername);
Objects.requireNonNull(plainPassword);
Assert.hasLength(plainUsername, "用户名不能为空");
Assert.hasLength(plainPassword, "密码不能为空");
return Optional.ofNullable(selectByUsername(plainUsername))
.filter(user -> encodePassword(plainPassword, user.getSalt()).equals(user.getPassword()))

View File

@@ -22,7 +22,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -20,16 +20,18 @@ package org.hswebframework.web.authorization.starter;
import org.hswebframework.web.authorization.AuthenticationInitializeService;
import org.hswebframework.web.authorization.AuthenticationManager;
import org.hswebframework.web.authorization.basic.embed.EmbedAuthenticationManager;
import org.hswebframework.web.authorization.simple.DefaultAuthorizationAutoConfiguration;
import org.hswebframework.web.service.authorization.simple.SimpleAuthenticationManager;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
/**
* @author zhouhao
@@ -41,12 +43,33 @@ import org.springframework.context.annotation.Import;
@AutoConfigureBefore(value = {
DefaultAuthorizationAutoConfiguration.class
}, name = "org.hswebframework.web.authorization.basic.configuration.AuthorizingHandlerAutoConfiguration")
@Import(BasicAuthorizationConfiguration.class)
public class AuthorizationAutoConfiguration {
@Bean
public AuthenticationManager authenticationManager(AuthenticationInitializeService authenticationInitializeService) {
return new SimpleAuthenticationManager(authenticationInitializeService);
@ConditionalOnMissingClass("org.hswebframework.web.authorization.basic.embed.EmbedAuthenticationManager")
@Configuration
public static class NoEmbedAuthenticationManagerAutoConfiguration {
@Bean
@Primary
public AuthenticationManager authenticationManager(AuthenticationInitializeService authenticationInitializeService) {
return new SimpleAuthenticationManager(authenticationInitializeService);
}
}
@ConditionalOnClass(EmbedAuthenticationManager.class)
@Configuration
public static class EmbedAuthenticationManagerAutoConfiguration {
@Bean
public EmbedAuthenticationManager embedAuthenticationManager() {
return new EmbedAuthenticationManager();
}
@Bean
@Primary
public AuthenticationManager authenticationManager(EmbedAuthenticationManager embedAuthenticationManager,
AuthenticationInitializeService authenticationInitializeService) {
return new SimpleAuthenticationManager(authenticationInitializeService, embedAuthenticationManager);
}
}
@Bean

View File

@@ -1,25 +0,0 @@
package org.hswebframework.web.authorization.starter;
import org.hswebframework.web.authorization.basic.web.UserTokenForTypeParser;
import org.hswebframework.web.authorization.token.UserTokenManager;
import org.hswebframework.web.service.authorization.UserService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhouhao
* @since 3.0
*/
@Configuration
@ConditionalOnProperty(prefix = "hsweb.authorize", name = "basic-authorization", havingValue = "true")
@ConditionalOnClass(UserTokenForTypeParser.class)
public class BasicAuthorizationConfiguration {
@Bean
public BasicAuthorizationTokenParser basicAuthorizationTokenParser(UserService userService, UserTokenManager tokenManager) {
return new BasicAuthorizationTokenParser(userService, tokenManager);
}
}

View File

@@ -0,0 +1,73 @@
package org.hswebframework.web.authorization.starter
import com.alibaba.fastjson.JSON
import org.hswebframework.web.entity.authorization.UserEntity
import org.hswebframework.web.service.authorization.UserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.context.annotation.Configuration
import org.springframework.http.MediaType
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.web.WebAppConfiguration
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import spock.lang.Shared
import spock.lang.Specification
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
@WebAppConfiguration
@ContextConfiguration
@SpringBootTest(classes = [TestApplication.class], properties = ["classpath:application.yml"])
@Configuration
class FixBug89Test extends Specification {
@Autowired
private ConfigurableApplicationContext context;
@Shared
private MockMvc mockMvc;
@Autowired
private UserService userService;
void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
UserEntity userEntity = userService.createEntity();
userEntity.setName("test");
userEntity.setUsername("fix-bug#89");
userEntity.setPassword("fix-bug#89");
if (userService.selectByUsername("fix-bug#89") == null) {
userService.insert(userEntity);
}
}
def doLogin(username, password) {
def response = mockMvc.perform(post("/authorize/login")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"username":"${username}","password":"${password}"}"""))
// .andExpect(status().is(200))
.andReturn()
.getResponse()
.getContentAsString()
return JSON.parseObject(response).get("status");
}
def "测试用户名为空时登录依旧能登录成功问题"() {
given:
def user = userService.selectByUserNameAndPassword("fix-bug#89", "fix-bug#89");
expect:
user != null
doLogin(username, password) == code
where:
username | password | code
"fix-bug#89" | "fix-bug#89" | 200
"fix-bug#89" | "" | 400
"" | "fix-bug#89" | 400
"" | "" | 400
}
}

View File

@@ -0,0 +1,24 @@
package org.hswebframework.web.authorization.starter;
import org.hswebframework.web.authorization.basic.web.AuthorizationController;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.web.WebAppConfiguration;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@SpringBootApplication
@WebAppConfiguration
@Configuration
public class TestApplication {
@Bean
public AuthorizationController authorizationController() {
return new AuthorizationController();
}
}

View File

@@ -19,6 +19,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders
import spock.lang.Shared
import spock.lang.Specification
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -62,10 +63,11 @@ class UserSettingControllerTest extends Specification {
]
permissions.forEach({ permission ->
//
mockMvc.perform(post("/permission")
mockMvc.perform(patch("/permission")
.contentType(MediaType.APPLICATION_JSON)
.content(JSON.toJSONString(permission)))
.andExpect(status().is(201))
.andDo({ result -> println result.response.contentAsString })
.andExpect(status().is(200))
})
}
@@ -84,6 +86,7 @@ class UserSettingControllerTest extends Specification {
}
"""
))
.andDo({ result -> println result.response.contentAsString })
.andExpect(status().is(201))
.andReturn()
.getResponse()
@@ -127,7 +130,8 @@ class UserSettingControllerTest extends Specification {
]
]
])
)).andExpect(status().is(201))
)).andDo({ result -> println result.response.contentAsString })
// .andExpect(status().is(201))
expect:
userId != null
def autz = initializeService.initUserAuthorization(userId)

View File

@@ -12,8 +12,8 @@ hsweb:
name: 权限管理测试
version: 3.0.0
authorize:
sync: true
auto-parse: true
sync: false
auto-parse: false
logging:
level:
org.springframework: WARN

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-system-config</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-system-config</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-config</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-system-config</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-system</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-dashboard</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-dashboard</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-dashboard</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-dashboard</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0.0</version>
<version>3.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Some files were not shown because too many files have changed in this diff Show More