Commit b2ef91def2d9813ccdf7e9a3233c9f7cf1bbc1ae
1 parent
d1cb0d70
fix: security修改权限【thingsKit刷新token需要】
Showing
7 changed files
with
81 additions
and
36 deletions
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | package org.thingsboard.server.service.security.auth.jwt; |
17 | 17 | |
18 | 18 | import lombok.RequiredArgsConstructor; |
19 | +import org.springframework.beans.factory.annotation.Autowired; | |
19 | 20 | import org.springframework.security.authentication.AuthenticationProvider; |
20 | 21 | import org.springframework.security.authentication.BadCredentialsException; |
21 | 22 | import org.springframework.security.authentication.CredentialsExpiredException; |
... | ... | @@ -33,6 +34,10 @@ import org.thingsboard.server.common.data.id.EntityId; |
33 | 34 | import org.thingsboard.server.common.data.id.TenantId; |
34 | 35 | import org.thingsboard.server.common.data.id.UserId; |
35 | 36 | import org.thingsboard.server.common.data.security.Authority; |
37 | +import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | |
38 | +import org.thingsboard.server.common.data.yunteng.dto.UserDTO; | |
39 | +import org.thingsboard.server.common.data.yunteng.dto.UserDetailsDTO; | |
40 | +import org.thingsboard.server.dao.yunteng.service.YtUserService; | |
36 | 41 | import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken; |
37 | 42 | import org.thingsboard.server.service.security.auth.TokenOutdatingService; |
38 | 43 | import org.thingsboard.server.service.security.model.SecurityUser; |
... | ... | @@ -43,6 +48,7 @@ import org.thingsboard.server.common.data.security.UserCredentials; |
43 | 48 | import org.thingsboard.server.dao.customer.CustomerService; |
44 | 49 | import org.thingsboard.server.dao.user.UserService; |
45 | 50 | |
51 | +import java.util.List; | |
46 | 52 | import java.util.UUID; |
47 | 53 | |
48 | 54 | @Component |
... | ... | @@ -52,6 +58,7 @@ public class RefreshTokenAuthenticationProvider implements AuthenticationProvide |
52 | 58 | private final UserService userService; |
53 | 59 | private final CustomerService customerService; |
54 | 60 | private final TokenOutdatingService tokenOutdatingService; |
61 | + private final YtUserService ytUserService; | |
55 | 62 | |
56 | 63 | @Override |
57 | 64 | public Authentication authenticate(Authentication authentication) throws AuthenticationException { |
... | ... | @@ -77,27 +84,53 @@ public class RefreshTokenAuthenticationProvider implements AuthenticationProvide |
77 | 84 | private SecurityUser authenticateByUserId(UserId userId) { |
78 | 85 | TenantId systemId = new TenantId(EntityId.NULL_UUID); |
79 | 86 | User user = userService.findUserById(systemId, userId); |
87 | + SecurityUser securityUser; | |
80 | 88 | if (user == null) { |
81 | - throw new UsernameNotFoundException("User not found by refresh token"); | |
82 | - } | |
83 | - | |
84 | - UserCredentials userCredentials = userService.findUserCredentialsByUserId(systemId, user.getId()); | |
85 | - if (userCredentials == null) { | |
86 | - throw new UsernameNotFoundException("User credentials not found"); | |
87 | - } | |
88 | - | |
89 | - if (!userCredentials.isEnabled()) { | |
90 | - throw new DisabledException("User is not active"); | |
89 | + //system platform user | |
90 | + securityUser = authenticateByPlatFormUserId(userId); | |
91 | + if(null == securityUser){ | |
92 | + throw new UsernameNotFoundException("User not found by refresh token"); | |
93 | + } | |
94 | + }else{ | |
95 | + UserCredentials userCredentials = userService.findUserCredentialsByUserId(systemId, user.getId()); | |
96 | + if (userCredentials == null) { | |
97 | + throw new UsernameNotFoundException("User credentials not found"); | |
98 | + } | |
99 | + | |
100 | + if (!userCredentials.isEnabled()) { | |
101 | + throw new DisabledException("User is not active"); | |
102 | + } | |
103 | + | |
104 | + if (user.getAuthority() == null) throw new InsufficientAuthenticationException("User has no authority assigned"); | |
105 | + | |
106 | + UserPrincipal userPrincipal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()); | |
107 | + String userName = user.getEmail().indexOf("@") != -1 ?user.getEmail().split("@")[0]:user.getEmail(); | |
108 | + List<UserDetailsDTO> userDetailsDTOS = ytUserService.findUserDetailsByUsername(userName, | |
109 | + user.getTenantId().getId().toString()); | |
110 | + user.setUserDetailsDTO(null != userDetailsDTOS && userDetailsDTOS.size()>0 ? userDetailsDTOS.get(0):null); | |
111 | + securityUser = new SecurityUser(user, userCredentials.isEnabled(), userPrincipal); | |
91 | 112 | } |
92 | - | |
93 | - if (user.getAuthority() == null) throw new InsufficientAuthenticationException("User has no authority assigned"); | |
94 | - | |
95 | - UserPrincipal userPrincipal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()); | |
96 | - SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), userPrincipal); | |
97 | - | |
98 | 113 | return securityUser; |
99 | 114 | } |
100 | 115 | |
116 | + private SecurityUser authenticateByPlatFormUserId(UserId userId){ | |
117 | + UserDTO userDTO =ytUserService.findUserInfoById(userId.getId().toString()); | |
118 | + if(null != userDTO){ | |
119 | + String email = userDTO.getUsername() + FastIotConstants.DEFAULT_EMAIL_SUFFIX_FOR_TB; | |
120 | + UserPrincipal userPrincipal = new UserPrincipal(UserPrincipal.Type.USER_NAME, email); | |
121 | + User user = new User(); | |
122 | + user.setAuthority(Authority.PLATFORM_USER); | |
123 | + user.setTenantId(new TenantId(EntityId.NULL_UUID)); | |
124 | + user.setId(userId); | |
125 | + user.setEmail(email); | |
126 | + List<UserDetailsDTO> userDetailsDTOS = ytUserService.findUserDetailsByUsername(userDTO.getUsername(), | |
127 | + user.getTenantId().getId().toString()); | |
128 | + user.setUserDetailsDTO(null != userDetailsDTOS && userDetailsDTOS.size()>0 ? userDetailsDTOS.get(0):null); | |
129 | + SecurityUser securityUser = new SecurityUser(user, true, userPrincipal); | |
130 | + return securityUser; | |
131 | + } | |
132 | + return null; | |
133 | + } | |
101 | 134 | private SecurityUser authenticateByPublicId(String publicId) { |
102 | 135 | TenantId systemId = new TenantId(EntityId.NULL_UUID); |
103 | 136 | CustomerId customerId; | ... | ... |
... | ... | @@ -279,7 +279,7 @@ public class RestAuthenticationProvider implements AuthenticationProvider { |
279 | 279 | @Autowired private PasswordEncoder passwordEncoder; |
280 | 280 | |
281 | 281 | private Optional<UserDetailsDTO> ytUserDetailsByUserName(String username, String password) { |
282 | - List<UserDetailsDTO> users = ytUserService.findUserDetailsByUsername(username); | |
282 | + List<UserDetailsDTO> users = ytUserService.findUserDetailsByUsername(username,null); | |
283 | 283 | |
284 | 284 | if (users.isEmpty()) { |
285 | 285 | throw new UsernameNotFoundException("User not found: " + username); | ... | ... |
... | ... | @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.security.model.JwtToken; |
28 | 28 | import org.thingsboard.server.config.JwtSettings; |
29 | 29 | import org.thingsboard.server.dao.customer.CustomerService; |
30 | 30 | import org.thingsboard.server.dao.user.UserService; |
31 | +import org.thingsboard.server.dao.yunteng.service.YtUserService; | |
31 | 32 | import org.thingsboard.server.service.security.auth.jwt.JwtAuthenticationProvider; |
32 | 33 | import org.thingsboard.server.service.security.auth.jwt.RefreshTokenAuthenticationProvider; |
33 | 34 | import org.thingsboard.server.service.security.exception.JwtExpiredTokenException; |
... | ... | @@ -60,6 +61,7 @@ public class TokenOutdatingTest { |
60 | 61 | private ConcurrentMapCacheManager cacheManager; |
61 | 62 | private JwtTokenFactory tokenFactory; |
62 | 63 | private JwtSettings jwtSettings; |
64 | + private YtUserService ytUserService; | |
63 | 65 | |
64 | 66 | private UserId userId; |
65 | 67 | |
... | ... | @@ -91,7 +93,8 @@ public class TokenOutdatingTest { |
91 | 93 | when(userService.findUserCredentialsByUserId(any(), eq(userId))).thenReturn(userCredentials); |
92 | 94 | |
93 | 95 | accessTokenAuthenticationProvider = new JwtAuthenticationProvider(tokenFactory, tokenOutdatingService); |
94 | - refreshTokenAuthenticationProvider = new RefreshTokenAuthenticationProvider(tokenFactory, userService, mock(CustomerService.class), tokenOutdatingService); | |
96 | + refreshTokenAuthenticationProvider = new RefreshTokenAuthenticationProvider(tokenFactory, userService, mock(CustomerService.class), tokenOutdatingService, | |
97 | + ytUserService); | |
95 | 98 | } |
96 | 99 | |
97 | 100 | @Test | ... | ... |
... | ... | @@ -80,9 +80,9 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
80 | 80 | private final ApplicationEventPublisher eventPublisher; |
81 | 81 | |
82 | 82 | @Override |
83 | - public List<UserDetailsDTO> findUserDetailsByUsername(String username) { | |
83 | + public List<UserDetailsDTO> findUserDetailsByUsername(String username,String tenantId) { | |
84 | 84 | // 多个租户可能存在多个username相同的情况 |
85 | - return baseMapper.findUserDetailsByUserName(username); | |
85 | + return baseMapper.findUserDetailsByUserName(username,tenantId); | |
86 | 86 | } |
87 | 87 | |
88 | 88 | @Override | ... | ... |
... | ... | @@ -17,30 +17,34 @@ import java.util.Set; |
17 | 17 | @Mapper |
18 | 18 | public interface UserMapper extends BaseMapper<User> { |
19 | 19 | |
20 | - List<UserDetailsDTO> findUserDetailsByUserName(String username); | |
20 | + List<UserDetailsDTO> findUserDetailsByUserName( | |
21 | + @Param("username") String username, @Param("tenantId") String tenantId); | |
21 | 22 | |
22 | - List<UserDetailsDTO> findUserDetailsByPhoneNumber(String phoneNumber); | |
23 | + List<UserDetailsDTO> findUserDetailsByPhoneNumber(String phoneNumber); | |
23 | 24 | |
24 | - IPage<UserDTO> getUserPage(IPage<?> page, @Param("queryMap") Map<String, Object> queryMap); | |
25 | + IPage<UserDTO> getUserPage(IPage<?> page, @Param("queryMap") Map<String, Object> queryMap); | |
25 | 26 | |
26 | - IPage<UserDTO> getTenantAdminPage(IPage<?> page, @Param("tenantId") String tenantId); | |
27 | + IPage<UserDTO> getTenantAdminPage(IPage<?> page, @Param("tenantId") String tenantId); | |
27 | 28 | |
28 | - Set<String> getAllIdsByTenantId(@Param("tenantIds") Collection<String> tenantIds); | |
29 | + Set<String> getAllIdsByTenantId(@Param("tenantIds") Collection<String> tenantIds); | |
29 | 30 | |
30 | - void setPassword2NullAndInsertActiveToken( | |
31 | - @Param("userId") String userId, @Param("activeToken") String activeToken); | |
31 | + void setPassword2NullAndInsertActiveToken( | |
32 | + @Param("userId") String userId, @Param("activeToken") String activeToken); | |
32 | 33 | |
33 | - UserDTO findUserInfo(UserDTO userDTO); | |
34 | + UserDTO findUserInfo(UserDTO userDTO); | |
34 | 35 | |
35 | - List<UserDTO> findUserInfoByPhoneNumber(UserDTO userDTO); | |
36 | + List<UserDTO> findUserInfoByPhoneNumber(UserDTO userDTO); | |
36 | 37 | |
37 | - String findUserCustomerIdById(@Param("userId") String userId); | |
38 | + String findUserCustomerIdById(@Param("userId") String userId); | |
38 | 39 | |
39 | - List<UserDTO> getUserCountByRoleType(@Param("roleType") RoleEnum roleType); | |
40 | + List<UserDTO> getUserCountByRoleType(@Param("roleType") RoleEnum roleType); | |
40 | 41 | |
41 | - List<UserDTO> getMyCustomers(@Param("tenantId") String tenantId, @Param("customerId") String customerId, @Param("userIds") Collection<String> userIds); | |
42 | + List<UserDTO> getMyCustomers( | |
43 | + @Param("tenantId") String tenantId, | |
44 | + @Param("customerId") String customerId, | |
45 | + @Param("userIds") Collection<String> userIds); | |
42 | 46 | |
43 | - List<UserDTO> findUsersAsyncByTs(@Param("startTs") String startTs,@Param("endTs") String endTs); | |
47 | + List<UserDTO> findUsersAsyncByTs(@Param("startTs") String startTs, @Param("endTs") String endTs); | |
44 | 48 | |
45 | - String findCustomerIdByUserId(@Param("id") String id); | |
49 | + String findCustomerIdByUserId(@Param("id") String id); | |
46 | 50 | } | ... | ... |
... | ... | @@ -18,7 +18,7 @@ import java.util.Set; |
18 | 18 | import java.util.concurrent.CompletableFuture; |
19 | 19 | |
20 | 20 | public interface YtUserService { |
21 | - List<UserDetailsDTO> findUserDetailsByUsername(String username); | |
21 | + List<UserDetailsDTO> findUserDetailsByUsername(String username,String tenantId); | |
22 | 22 | |
23 | 23 | UserDTO saveAccount( |
24 | 24 | UserDTO userDTO, boolean sendEmail, boolean sendMsg, boolean isTenantAdmin, String tenantId); | ... | ... |
... | ... | @@ -79,7 +79,12 @@ |
79 | 79 | LEFT JOIN sys_role sr ON sur.role_id = sr.id |
80 | 80 | WHERE sur.user_id = (SELECT id FROM sys_user WHERE username = #{username}) |
81 | 81 | ) rr ON su.id = rr.user_id |
82 | - WHERE su.username = #{username}; | |
82 | + <where> | |
83 | + su.username = #{username} | |
84 | + <if test="tenantId !=null and tenantId !=''"> | |
85 | + AND su.tenant_id = #{tenantId} | |
86 | + </if> | |
87 | + </where> | |
83 | 88 | </select> |
84 | 89 | |
85 | 90 | <select id="getUserPage" resultMap="userDTOMap"> | ... | ... |