Introduce OAuth failure handling
This commit is contained in:
parent
9b18c408b2
commit
d9bfd82926
@ -79,11 +79,18 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
|
|||||||
@Qualifier("oauth2AuthenticationSuccessHandler")
|
@Qualifier("oauth2AuthenticationSuccessHandler")
|
||||||
private AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler;
|
private AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
@Qualifier("oauth2AuthenticationFailureHandler")
|
||||||
|
private AuthenticationFailureHandler oauth2AuthenticationFailureHandler;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("defaultAuthenticationSuccessHandler")
|
@Qualifier("defaultAuthenticationSuccessHandler")
|
||||||
private AuthenticationSuccessHandler successHandler;
|
private AuthenticationSuccessHandler successHandler;
|
||||||
|
|
||||||
@Autowired private AuthenticationFailureHandler failureHandler;
|
@Autowired
|
||||||
|
@Qualifier("defaultAuthenticationFailureHandler")
|
||||||
|
private AuthenticationFailureHandler failureHandler;
|
||||||
|
|
||||||
@Autowired private RestAuthenticationProvider restAuthenticationProvider;
|
@Autowired private RestAuthenticationProvider restAuthenticationProvider;
|
||||||
@Autowired private JwtAuthenticationProvider jwtAuthenticationProvider;
|
@Autowired private JwtAuthenticationProvider jwtAuthenticationProvider;
|
||||||
@Autowired private RefreshTokenAuthenticationProvider refreshTokenAuthenticationProvider;
|
@Autowired private RefreshTokenAuthenticationProvider refreshTokenAuthenticationProvider;
|
||||||
@ -205,7 +212,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
|
|||||||
.loginPage("/oauth2Login")
|
.loginPage("/oauth2Login")
|
||||||
.loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl())
|
.loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl())
|
||||||
.successHandler(oauth2AuthenticationSuccessHandler)
|
.successHandler(oauth2AuthenticationSuccessHandler)
|
||||||
.failureHandler(failureHandler);
|
.failureHandler(oauth2AuthenticationFailureHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* 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.oauth2;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.thingsboard.server.utils.MiscUtils;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
@Component(value = "oauth2AuthenticationFailureHandler")
|
||||||
|
@ConditionalOnProperty(prefix = "security.oauth2", value = "enabled", havingValue = "true")
|
||||||
|
public class Oauth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAuthenticationFailure(HttpServletRequest request,
|
||||||
|
HttpServletResponse response, AuthenticationException exception)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
String baseUrl = MiscUtils.constructBaseUrl(request);
|
||||||
|
getRedirectStrategy().sendRedirect(request, response, baseUrl + "/login?loginError=" +
|
||||||
|
URLEncoder.encode(exception.getMessage(), StandardCharsets.UTF_8.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@Component
|
@Component(value = "defaultAuthenticationFailureHandler")
|
||||||
public class RestAwareAuthenticationFailureHandler implements AuthenticationFailureHandler {
|
public class RestAwareAuthenticationFailureHandler implements AuthenticationFailureHandler {
|
||||||
|
|
||||||
private final ThingsboardErrorResponseHandler errorResponseHandler;
|
private final ThingsboardErrorResponseHandler errorResponseHandler;
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export default angular.module('thingsboard.api.user', [thingsboardApiLogin,
|
|||||||
.name;
|
.name;
|
||||||
|
|
||||||
/*@ngInject*/
|
/*@ngInject*/
|
||||||
function UserService($http, $q, $rootScope, adminService, dashboardService, timeService, loginService, toast, store, jwtHelper, $translate, $state, $location) {
|
function UserService($http, $q, $rootScope, adminService, dashboardService, timeService, loginService, toast, store, jwtHelper, $translate, $state, $location, $mdDialog) {
|
||||||
var currentUser = null,
|
var currentUser = null,
|
||||||
currentUserDetails = null,
|
currentUserDetails = null,
|
||||||
lastPublicDashboardId = null,
|
lastPublicDashboardId = null,
|
||||||
@ -406,6 +406,10 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, time
|
|||||||
}, function fail() {
|
}, function fail() {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
});
|
});
|
||||||
|
} else if (locationSearch.loginError) {
|
||||||
|
showLoginErrorDialog(locationSearch.loginError);
|
||||||
|
$location.search('loginError', null);
|
||||||
|
deferred.reject();
|
||||||
} else {
|
} else {
|
||||||
procceedJwtTokenValidate();
|
procceedJwtTokenValidate();
|
||||||
}
|
}
|
||||||
@ -415,6 +419,17 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, time
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showLoginErrorDialog(loginError) {
|
||||||
|
$translate(['login.error',
|
||||||
|
'action.close']).then(function (translations) {
|
||||||
|
var alert = $mdDialog.alert()
|
||||||
|
.title(translations['login.error'])
|
||||||
|
.htmlContent(loginError)
|
||||||
|
.ok(translations['action.close']);
|
||||||
|
$mdDialog.show(alert);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function loadIsUserTokenAccessEnabled() {
|
function loadIsUserTokenAccessEnabled() {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
if (currentUser.authority === 'SYS_ADMIN' || currentUser.authority === 'TENANT_ADMIN') {
|
if (currentUser.authority === 'SYS_ADMIN' || currentUser.authority === 'TENANT_ADMIN') {
|
||||||
|
|||||||
@ -1334,7 +1334,8 @@
|
|||||||
"password-link-sent-message": "Password reset link was successfully sent!",
|
"password-link-sent-message": "Password reset link was successfully sent!",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"login-with": "Login with {{name}}",
|
"login-with": "Login with {{name}}",
|
||||||
"or": "or"
|
"or": "or",
|
||||||
|
"error": "Login error"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"top": "Top",
|
"top": "Top",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user