diff --git a/application/pom.xml b/application/pom.xml
index 21a319491d..55009709d1 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -132,6 +132,18 @@
             org.springframework.boot
             spring-boot-starter-websocket
         
+        
+            org.springframework.cloud
+            spring-cloud-starter-oauth2
+        
+        
+            org.springframework.security
+            spring-security-oauth2-client
+        
+        
+            org.springframework.security
+            spring-security-oauth2-jose
+        
         
             io.jsonwebtoken
             jjwt
diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardOAuth2Configuration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardOAuth2Configuration.java
new file mode 100644
index 0000000000..45048fddf3
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardOAuth2Configuration.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright © 2016-2020 The Thingsboard Authors
+ *
+ * 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.thingsboard.server.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
+import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
+import org.springframework.security.oauth2.core.AuthorizationGrantType;
+import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
+
+import java.util.Collections;
+
+@ConditionalOnProperty(prefix = "security.oauth2", value = "enabled", havingValue = "true")
+@Configuration
+public class ThingsboardOAuth2Configuration {
+
+    @Value("${security.oauth2.registrationId}")
+    private String registrationId;
+    @Value("${security.oauth2.userNameAttributeName}")
+    private String userNameAttributeName;
+
+    @Value("${security.oauth2.client.clientId}")
+    private String clientId;
+    @Value("${security.oauth2.client.clientName}")
+    private String clientName;
+    @Value("${security.oauth2.client.clientSecret}")
+    private String clientSecret;
+    @Value("${security.oauth2.client.accessTokenUri}")
+    private String accessTokenUri;
+    @Value("${security.oauth2.client.authorizationUri}")
+    private String authorizationUri;
+    @Value("${security.oauth2.client.redirectUriTemplate}")
+    private String redirectUriTemplate;
+    @Value("${security.oauth2.client.scope}")
+    private String scope;
+    @Value("${security.oauth2.client.jwkSetUri}")
+    private String jwkSetUri;
+    @Value("${security.oauth2.client.authorizationGrantType}")
+    private String authorizationGrantType;
+    @Value("${security.oauth2.client.clientAuthenticationMethod}")
+    private String clientAuthenticationMethod;
+
+    @Value("${security.oauth2.resource.userInfoUri}")
+    private String userInfoUri;
+
+    @Bean
+    public ClientRegistrationRepository clientRegistrationRepository() {
+        ClientRegistration registration = ClientRegistration.withRegistrationId(registrationId)
+                .clientId(clientId)
+                .authorizationUri(authorizationUri)
+                .clientSecret(clientSecret)
+                .tokenUri(accessTokenUri)
+                .redirectUriTemplate(redirectUriTemplate)
+                .scope(scope.split(","))
+                .clientName(clientName)
+                .authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
+                .userInfoUri(userInfoUri)
+                .userNameAttributeName(userNameAttributeName)
+                .jwkSetUri(jwkSetUri)
+                .clientAuthenticationMethod(new ClientAuthenticationMethod(clientAuthenticationMethod))
+                .build();
+        return new InMemoryClientRegistrationRepository(Collections.singletonList(registration));
+    }
+}
\ No newline at end of file
diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
index 53876f4040..36490b5166 100644
--- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
@@ -18,6 +18,8 @@ package org.thingsboard.server.config;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Required;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.security.SecurityProperties;
 import org.springframework.context.annotation.Bean;
@@ -73,12 +75,25 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
     public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**";
 
     @Autowired private ThingsboardErrorResponseHandler restAccessDeniedHandler;
-    @Autowired private AuthenticationSuccessHandler successHandler;
+
+    @Autowired(required = false)
+    @Qualifier("oauth2AuthenticationSuccessHandler")
+    private AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler;
+
+    @Autowired
+    @Qualifier("defaultAuthenticationSuccessHandler")
+    private AuthenticationSuccessHandler successHandler;
+
     @Autowired private AuthenticationFailureHandler failureHandler;
     @Autowired private RestAuthenticationProvider restAuthenticationProvider;
     @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider;
     @Autowired private RefreshTokenAuthenticationProvider refreshTokenAuthenticationProvider;
 
+    @Value("${security.oauth2.enabled}")
+    private boolean oauth2Enabled;
+    @Value("${security.oauth2.client.loginProcessingUrl}")
+    private String loginProcessingUrl;
+
     @Autowired
     @Qualifier("jwtHeaderTokenExtractor")
     private TokenExtractor jwtHeaderTokenExtractor;
@@ -189,6 +204,11 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
                 .addFilterBefore(buildRefreshTokenProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
                 .addFilterBefore(buildWsJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
                 .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class);
+        if (oauth2Enabled) {
+            http.oauth2Login()
+                    .loginProcessingUrl(loginProcessingUrl)
+                    .successHandler(oauth2AuthenticationSuccessHandler);
+        }
     }
 
 
diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth/Oauth2AuthenticationSuccessHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth/Oauth2AuthenticationSuccessHandler.java
new file mode 100644
index 0000000000..e99e5896e1
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth/Oauth2AuthenticationSuccessHandler.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright © 2016-2020 The Thingsboard Authors
+ *
+ * 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.thingsboard.server.service.security.auth.oauth;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.security.authentication.InsufficientAuthenticationException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
+import org.springframework.stereotype.Component;
+import org.thingsboard.server.common.data.User;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.security.UserCredentials;
+import org.thingsboard.server.dao.user.UserService;
+import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
+import org.thingsboard.server.service.security.model.SecurityUser;
+import org.thingsboard.server.service.security.model.UserPrincipal;
+import org.thingsboard.server.service.security.model.token.JwtToken;
+import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
+import org.thingsboard.server.service.security.system.SystemSecurityService;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component(value="oauth2AuthenticationSuccessHandler")
+@ConditionalOnProperty(prefix = "security.oauth2", value = "enabled", havingValue = "true")
+public class Oauth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
+
+    private final ObjectMapper mapper;
+    private final JwtTokenFactory tokenFactory;
+    private final RefreshTokenRepository refreshTokenRepository;
+    private final SystemSecurityService systemSecurityService;
+    private final UserService userService;
+
+    @Autowired
+    public Oauth2AuthenticationSuccessHandler(final ObjectMapper mapper,
+                                              final JwtTokenFactory tokenFactory,
+                                              final RefreshTokenRepository refreshTokenRepository,
+                                              final UserService userService,
+                                              final SystemSecurityService systemSecurityService) {
+        this.mapper = mapper;
+        this.tokenFactory = tokenFactory;
+        this.refreshTokenRepository = refreshTokenRepository;
+        this.userService = userService;
+        this.systemSecurityService = systemSecurityService;
+    }
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
+        Object object = authentication.getPrincipal();
+
+        System.out.println(object);
+
+        // active user check
+
+        UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, "tenant@thingsboard.org");
+        SecurityUser securityUser =  (SecurityUser) authenticateByUsernameAndPassword(principal,"tenant@thingsboard.org", "tenant").getPrincipal();
+
+        JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
+        JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);
+
+        Map tokenMap = new HashMap();
+        tokenMap.put("token", accessToken.getToken());
+        tokenMap.put("refreshToken", refreshToken.getToken());
+
+//        response.setStatus(HttpStatus.OK.value());
+//        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+//        mapper.writeValue(response.getWriter(), tokenMap);
+
+        request.setAttribute("token", accessToken.getToken());
+        response.addHeader("token", accessToken.getToken());
+
+        getRedirectStrategy().sendRedirect(request, response, "http://localhost:4200/?accessToken=" + accessToken.getToken() + "&refreshToken=" + refreshToken.getToken());
+    }
+
+    private Authentication authenticateByUsernameAndPassword(UserPrincipal userPrincipal, String username, String password) {
+        User user = userService.findUserByEmail(TenantId.SYS_TENANT_ID, username);
+        if (user == null) {
+            throw new UsernameNotFoundException("User not found: " + username);
+        }
+
+        try {
+
+            UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, user.getId());
+            if (userCredentials == null) {
+                throw new UsernameNotFoundException("User credentials not found");
+            }
+
+            try {
+                systemSecurityService.validateUserCredentials(user.getTenantId(), userCredentials, username, password);
+            } catch (LockedException e) {
+                throw e;
+            }
+
+            if (user.getAuthority() == null)
+                throw new InsufficientAuthenticationException("User has no authority assigned");
+
+            SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), userPrincipal);
+            return new UsernamePasswordAuthenticationToken(securityUser, null, securityUser.getAuthorities());
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+}
\ No newline at end of file
diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java
index aa55818084..d26b02174e 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java
@@ -36,7 +36,7 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
-@Component
+@Component(value="defaultAuthenticationSuccessHandler")
 public class RestAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
     private final ObjectMapper mapper;
     private final JwtTokenFactory tokenFactory;
diff --git a/application/src/main/resources/logback.xml b/application/src/main/resources/logback.xml
index e25fb72ccb..9b14ff06f5 100644
--- a/application/src/main/resources/logback.xml
+++ b/application/src/main/resources/logback.xml
@@ -26,6 +26,7 @@
     
 
     
+    
     
 
 
diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml
index bf82c586c3..97e22fa2c6 100644
--- a/application/src/main/resources/thingsboard.yml
+++ b/application/src/main/resources/thingsboard.yml
@@ -97,6 +97,44 @@ security:
     allowClaimingByDefault: "${SECURITY_CLAIM_ALLOW_CLAIMING_BY_DEFAULT:true}"
     # Time allowed to claim the device in milliseconds
     duration: "${SECURITY_CLAIM_DURATION:60000}" # 1 minute, note this value must equal claimDevices.timeToLiveInMinutes value
+  basic:
+    enabled: false
+    #  oauth2:
+    #    enabled: true
+    #    registrationId: A
+    #    userNameAttributeName: email
+    #    client:
+    #      clientName: Thingsboard Dev Test Q
+    #      clientId: 5f5c0998-1d9b-4679-9610-6108fb91af2a
+    #      clientSecret: h_kXVb7Ee1LgDDinix_nkAh_owWX7YCO783NNteF9AIOqlTWu2L03YoFjv5KL8yRVyx4uYAE-r_N3tFbupE8Kw
+    #      accessTokenUri: https://federation-q.auth.schwarz/nidp/oauth/nam/token
+    #      authorizationUri: https://federation-q.auth.schwarz/nidp/oauth/nam/authz
+    #      scope: openid,profile,email,siam
+    #      redirectUriTemplate: http://localhost:8080/login/oauth2/code/
+    #      loginProcessingUrl: /login/oauth2/code/
+    #      jwkSetUri: https://federation-q.auth.schwarz/nidp/oauth/nam/keys
+    #      authorizationGrantType: authorization_code  # authorization_code, implicit, refresh_token, client_credentials
+    #      clientAuthenticationMethod: post # basic, post
+    #    resource:
+    #      userInfoUri: https://federation-q.auth.schwarz/nidp/oauth/nam/userinfo
+    oauth2:
+      enabled: true
+      registrationId: A
+      userNameAttributeName: email
+      client:
+        clientName: Test app
+        clientId: dVH9reqyqiXIG7M2wmamb0ySue8zaM4g
+        clientSecret: EYAfAGxwkwoeYnb2o2cDgaWZB5k97OStpZQPPvcMMD-SVH2BuughTGeBazXtF5I6
+        accessTokenUri: https://dev-r9m8ht0k.auth0.com/oauth/token
+        authorizationUri: https://dev-r9m8ht0k.auth0.com/authorize
+        scope: openid,profile,email
+        redirectUriTemplate: http://localhost:8080/login/oauth2/code/
+        loginProcessingUrl: /login/oauth2/code/
+        jwkSetUri: https://dev-r9m8ht0k.auth0.com/.well-known/jwks.json
+        authorizationGrantType: authorization_code  # authorization_code, implicit, refresh_token, client_credentials
+        clientAuthenticationMethod: post # basic, post
+      resource:
+        userInfoUri: https://dev-r9m8ht0k.auth0.com/userinfo
 
 # Dashboard parameters
 dashboard:
diff --git a/pom.xml b/pom.xml
index 494a43cb56..f263307538 100755
--- a/pom.xml
+++ b/pom.xml
@@ -458,6 +458,21 @@
                 spring-boot-starter-security
                 ${spring-boot.version}
             
+            
+                org.springframework.cloud
+                spring-cloud-starter-oauth2
+                ${spring-boot.version}
+            
+            
+                org.springframework.security
+                spring-security-oauth2-client
+                ${spring.version}
+            
+            
+                org.springframework.security
+                spring-security-oauth2-jose
+                ${spring.version}
+            
             
                 org.springframework.boot
                 spring-boot-starter-web
diff --git a/ui/src/app/login/login.tpl.html b/ui/src/app/login/login.tpl.html
index 6e9d7d8977..409f5cd4ad 100644
--- a/ui/src/app/login/login.tpl.html
+++ b/ui/src/app/login/login.tpl.html
@@ -47,6 +47,7 @@
                         
                     
                     {{ 'login.login' | translate }}
+                    OAUTH2 LOGIN