Commit 9b18c408b2e2104d55df8d0c36ec9b68b2870641

Authored by VoBa
Committed by GitHub
1 parent f29c9c94

Added activate user config. Fixed https issue (#2737)

* Added activate user config. Fixed https issue

* Update OAuth2User.java

Co-authored-by: Igor Kulikov <ikulikov82@gmail.com>
... ... @@ -204,11 +204,11 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
204 204 http.oauth2Login()
205 205 .loginPage("/oauth2Login")
206 206 .loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl())
207   - .successHandler(oauth2AuthenticationSuccessHandler);
  207 + .successHandler(oauth2AuthenticationSuccessHandler)
  208 + .failureHandler(failureHandler);
208 209 }
209 210 }
210 211
211   -
212 212 @Bean
213 213 @ConditionalOnMissingBean(CorsFilter.class)
214 214 public CorsFilter corsFilter(@Autowired MvcCorsProperties mvcCorsProperties) {
... ...
... ... @@ -52,6 +52,7 @@ import org.thingsboard.server.service.security.model.UserPrincipal;
52 52 import org.thingsboard.server.service.security.model.token.JwtToken;
53 53 import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
54 54 import org.thingsboard.server.service.security.system.SystemSecurityService;
  55 +import org.thingsboard.server.utils.MiscUtils;
55 56 import ua_parser.Client;
56 57
57 58 import javax.servlet.http.HttpServletRequest;
... ... @@ -170,7 +171,7 @@ public class AuthController extends BaseController {
170 171 try {
171 172 String email = resetPasswordByEmailRequest.get("email").asText();
172 173 UserCredentials userCredentials = userService.requestPasswordReset(TenantId.SYS_TENANT_ID, email);
173   - String baseUrl = constructBaseUrl(request);
  174 + String baseUrl = MiscUtils.constructBaseUrl(request);
174 175 String resetUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl,
175 176 userCredentials.getResetToken());
176 177
... ... @@ -218,7 +219,7 @@ public class AuthController extends BaseController {
218 219 User user = userService.findUserById(TenantId.SYS_TENANT_ID, credentials.getUserId());
219 220 UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
220 221 SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal);
221   - String baseUrl = constructBaseUrl(request);
  222 + String baseUrl = MiscUtils.constructBaseUrl(request);
222 223 String loginUrl = String.format("%s/login", baseUrl);
223 224 String email = user.getEmail();
224 225
... ... @@ -265,7 +266,7 @@ public class AuthController extends BaseController {
265 266 User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId());
266 267 UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
267 268 SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), principal);
268   - String baseUrl = constructBaseUrl(request);
  269 + String baseUrl = MiscUtils.constructBaseUrl(request);
269 270 String loginUrl = String.format("%s/login", baseUrl);
270 271 String email = user.getEmail();
271 272 mailService.sendPasswordWasResetEmail(loginUrl, email);
... ...
... ... @@ -521,39 +521,6 @@ public abstract class BaseController {
521 521 return ruleNode;
522 522 }
523 523
524   -
525   - protected String constructBaseUrl(HttpServletRequest request) {
526   - String scheme = request.getScheme();
527   -
528   - String forwardedProto = request.getHeader("x-forwarded-proto");
529   - if (forwardedProto != null) {
530   - scheme = forwardedProto;
531   - }
532   -
533   - int serverPort = request.getServerPort();
534   - if (request.getHeader("x-forwarded-port") != null) {
535   - try {
536   - serverPort = request.getIntHeader("x-forwarded-port");
537   - } catch (NumberFormatException e) {
538   - }
539   - } else if (forwardedProto != null) {
540   - switch (forwardedProto) {
541   - case "http":
542   - serverPort = 80;
543   - break;
544   - case "https":
545   - serverPort = 443;
546   - break;
547   - }
548   - }
549   -
550   - String baseUrl = String.format("%s://%s:%d",
551   - scheme,
552   - request.getServerName(),
553   - serverPort);
554   - return baseUrl;
555   - }
556   -
557 524 protected <I extends EntityId> I emptyId(EntityType entityType) {
558 525 return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
559 526 }
... ...
... ... @@ -52,6 +52,7 @@ import org.thingsboard.server.service.security.model.token.JwtToken;
52 52 import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
53 53 import org.thingsboard.server.service.security.permission.Operation;
54 54 import org.thingsboard.server.service.security.permission.Resource;
  55 +import org.thingsboard.server.utils.MiscUtils;
55 56
56 57 import javax.servlet.http.HttpServletRequest;
57 58
... ... @@ -148,7 +149,7 @@ public class UserController extends BaseController {
148 149 if (sendEmail) {
149 150 SecurityUser authUser = getCurrentUser();
150 151 UserCredentials userCredentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), savedUser.getId());
151   - String baseUrl = constructBaseUrl(request);
  152 + String baseUrl = MiscUtils.constructBaseUrl(request);
152 153 String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl,
153 154 userCredentials.getActivateToken());
154 155 String email = savedUser.getEmail();
... ... @@ -188,7 +189,7 @@ public class UserController extends BaseController {
188 189
189 190 UserCredentials userCredentials = userService.findUserCredentialsByUserId(getCurrentUser().getTenantId(), user.getId());
190 191 if (!userCredentials.isEnabled()) {
191   - String baseUrl = constructBaseUrl(request);
  192 + String baseUrl = MiscUtils.constructBaseUrl(request);
192 193 String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl,
193 194 userCredentials.getActivateToken());
194 195 mailService.sendActivationEmail(activateUrl, email);
... ... @@ -213,7 +214,7 @@ public class UserController extends BaseController {
213 214 SecurityUser authUser = getCurrentUser();
214 215 UserCredentials userCredentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), user.getId());
215 216 if (!userCredentials.isEnabled()) {
216   - String baseUrl = constructBaseUrl(request);
  217 + String baseUrl = MiscUtils.constructBaseUrl(request);
217 218 String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl,
218 219 userCredentials.getActivateToken());
219 220 return activateUrl;
... ...
... ... @@ -63,7 +63,7 @@ public abstract class AbstractOAuth2ClientMapper {
63 63
64 64 private final Lock userCreationLock = new ReentrantLock();
65 65
66   - protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, boolean allowUserCreation) {
  66 + protected SecurityUser getOrCreateSecurityUserFromOAuth2User(OAuth2User oauth2User, boolean allowUserCreation, boolean activateUser) {
67 67 UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, oauth2User.getEmail());
68 68
69 69 User user = userService.findUserByEmail(TenantId.SYS_TENANT_ID, oauth2User.getEmail());
... ... @@ -93,8 +93,10 @@ public abstract class AbstractOAuth2ClientMapper {
93 93 user.setFirstName(oauth2User.getFirstName());
94 94 user.setLastName(oauth2User.getLastName());
95 95 user = userService.saveUser(user);
96   - UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId());
97   - userService.activateUserCredentials(user.getTenantId(), userCredentials.getActivateToken(), passwordEncoder.encode(""));
  96 + if (activateUser) {
  97 + UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getTenantId(), user.getId());
  98 + userService.activateUserCredentials(user.getTenantId(), userCredentials.getActivateToken(), passwordEncoder.encode(""));
  99 + }
98 100 }
99 101 } catch (Exception e) {
100 102 log.error("Can't get or create security user from oauth2 user", e);
... ...
... ... @@ -56,7 +56,8 @@ public class BasicOAuth2ClientMapper extends AbstractOAuth2ClientMapper implemen
56 56 String customerName = sub.replace(config.getBasic().getCustomerNamePattern());
57 57 oauth2User.setCustomerName(customerName);
58 58 }
59   - return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.getBasic().isAllowUserCreation());
  59 +
  60 + return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.isAllowUserCreation(), config.isActivateUser());
60 61 }
61 62
62 63 private String getTenantName(Map<String, Object> attributes, OAuth2ClientMapperConfig config) {
... ...
... ... @@ -38,7 +38,7 @@ public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper impleme
38 38 @Override
39 39 public SecurityUser getOrCreateUserByClientPrincipal(OAuth2AuthenticationToken token, OAuth2ClientMapperConfig config) {
40 40 OAuth2User oauth2User = getOAuth2User(token, config.getCustom());
41   - return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.getBasic().isAllowUserCreation());
  41 + return getOrCreateSecurityUserFromOAuth2User(oauth2User, config.isAllowUserCreation(), config.isActivateUser());
42 42 }
43 43
44 44 private synchronized OAuth2User getOAuth2User(OAuth2AuthenticationToken token, OAuth2ClientMapperConfig.CustomOAuth2ClientMapperConfig custom) {
... ...
... ... @@ -27,6 +27,7 @@ import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
27 27 import org.thingsboard.server.service.security.model.SecurityUser;
28 28 import org.thingsboard.server.service.security.model.token.JwtToken;
29 29 import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
  30 +import org.thingsboard.server.utils.MiscUtils;
30 31
31 32 import javax.servlet.http.HttpServletRequest;
32 33 import javax.servlet.http.HttpServletResponse;
... ... @@ -65,6 +66,7 @@ public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS
65 66 JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
66 67 JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);
67 68
68   - getRedirectStrategy().sendRedirect(request, response, "/?accessToken=" + accessToken.getToken() + "&refreshToken=" + refreshToken.getToken());
  69 + String baseUrl = MiscUtils.constructBaseUrl(request);
  70 + getRedirectStrategy().sendRedirect(request, response, baseUrl + "/?accessToken=" + accessToken.getToken() + "&refreshToken=" + refreshToken.getToken());
69 71 }
70 72 }
\ No newline at end of file
... ...
... ... @@ -18,8 +18,8 @@ package org.thingsboard.server.utils;
18 18 import com.google.common.hash.HashFunction;
19 19 import com.google.common.hash.Hashing;
20 20
  21 +import javax.servlet.http.HttpServletRequest;
21 22 import java.nio.charset.Charset;
22   -import java.util.Random;
23 23
24 24
25 25 /**
... ... @@ -47,4 +47,36 @@ public class MiscUtils {
47 47 throw new IllegalArgumentException("Can't find hash function with name " + name);
48 48 }
49 49 }
  50 +
  51 + public static String constructBaseUrl(HttpServletRequest request) {
  52 + String scheme = request.getScheme();
  53 +
  54 + String forwardedProto = request.getHeader("x-forwarded-proto");
  55 + if (forwardedProto != null) {
  56 + scheme = forwardedProto;
  57 + }
  58 +
  59 + int serverPort = request.getServerPort();
  60 + if (request.getHeader("x-forwarded-port") != null) {
  61 + try {
  62 + serverPort = request.getIntHeader("x-forwarded-port");
  63 + } catch (NumberFormatException e) {
  64 + }
  65 + } else if (forwardedProto != null) {
  66 + switch (forwardedProto) {
  67 + case "http":
  68 + serverPort = 80;
  69 + break;
  70 + case "https":
  71 + serverPort = 443;
  72 + break;
  73 + }
  74 + }
  75 +
  76 + String baseUrl = String.format("%s://%s:%d",
  77 + scheme,
  78 + request.getServerName(),
  79 + serverPort);
  80 + return baseUrl;
  81 + }
50 82 }
... ...
... ... @@ -127,11 +127,13 @@ security:
127 127 userInfoUri: "${SECURITY_OAUTH2_DEFAULT_USER_INFO_URI:}"
128 128 userNameAttributeName: "${SECURITY_OAUTH2_DEFAULT_USER_NAME_ATTRIBUTE_NAME:email}"
129 129 mapperConfig:
  130 + # Allows to create user if it not exists
  131 + allowUserCreation: "${SECURITY_OAUTH2_DEFAULT_MAPPER_ALLOW_USER_CREATION:true}"
  132 + # Allows user to setup ThingsBoard internal password and login over default Login window
  133 + activateUser: "${SECURITY_OAUTH2_DEFAULT_MAPPER_ACTIVATE_USER:false}"
130 134 # Mapper type of converter from external user into internal - 'basic' or 'custom'
131 135 type: "${SECURITY_OAUTH2_DEFAULT_MAPPER_TYPE:basic}"
132 136 basic:
133   - # Allows to create user if it not exists
134   - allowUserCreation: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_ALLOW_USER_CREATION:true}"
135 137 # Key from attributes of external user object to use as email
136 138 emailAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_EMAIL_ATTRIBUTE_KEY:email}"
137 139 firstNameAttributeKey: "${SECURITY_OAUTH2_DEFAULT_MAPPER_BASIC_FIRST_NAME_ATTRIBUTE_KEY:}"
... ...
... ... @@ -20,13 +20,14 @@ import lombok.Data;
20 20 @Data
21 21 public class OAuth2ClientMapperConfig {
22 22
  23 + private boolean allowUserCreation;
  24 + private boolean activateUser;
23 25 private String type;
24 26 private BasicOAuth2ClientMapperConfig basic;
25 27 private CustomOAuth2ClientMapperConfig custom;
26 28
27 29 @Data
28 30 public static class BasicOAuth2ClientMapperConfig {
29   - private boolean allowUserCreation;
30 31 private String emailAttributeKey;
31 32 private String firstNameAttributeKey;
32 33 private String lastNameAttributeKey;
... ...