mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-08-02 13:48:15 +02:00
More Provider refactoring & cleanup
This commit is contained in:
parent
06a5ba892c
commit
8954990afb
@ -20,7 +20,7 @@ public class CleanUrlInterceptor implements HandlerInterceptor {
|
|||||||
"endpoints",
|
"endpoints",
|
||||||
"logout",
|
"logout",
|
||||||
"error",
|
"error",
|
||||||
"erroroauth",
|
"errorOAuth",
|
||||||
"file",
|
"file",
|
||||||
"messageType",
|
"messageType",
|
||||||
"infoMessage");
|
"infoMessage");
|
||||||
|
@ -69,7 +69,7 @@ public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationF
|
|||||||
}
|
}
|
||||||
if (exception instanceof BadCredentialsException
|
if (exception instanceof BadCredentialsException
|
||||||
|| exception instanceof UsernameNotFoundException) {
|
|| exception instanceof UsernameNotFoundException) {
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?error=badcredentials");
|
getRedirectStrategy().sendRedirect(request, response, "/login?error=badCredentials");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (exception instanceof InternalAuthenticationServiceException
|
if (exception instanceof InternalAuthenticationServiceException
|
||||||
|
@ -27,57 +27,42 @@ import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrin
|
|||||||
import stirling.software.SPDF.model.ApplicationProperties;
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
|
||||||
import stirling.software.SPDF.model.provider.Provider;
|
|
||||||
import stirling.software.SPDF.utils.UrlUtils;
|
import stirling.software.SPDF.utils.UrlUtils;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
||||||
|
|
||||||
|
public static final String LOGOUT_PATH = "/login?logout=true";
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLogoutSuccess(
|
public void onLogoutSuccess(
|
||||||
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
if (!response.isCommitted()) {
|
if (!response.isCommitted()) {
|
||||||
// Handle user logout due to disabled account
|
|
||||||
if (request.getParameter("userIsDisabled") != null) {
|
|
||||||
response.sendRedirect(
|
|
||||||
request.getContextPath() + "/login?erroroauth=userIsDisabled");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Handle OAuth2 authentication error
|
|
||||||
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
|
|
||||||
response.sendRedirect(
|
|
||||||
request.getContextPath() + "/login?erroroauth=userAlreadyExistsWeb");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
// Handle SAML2 logout redirection
|
|
||||||
if (authentication instanceof Saml2Authentication) {
|
if (authentication instanceof Saml2Authentication) {
|
||||||
|
// Handle SAML2 logout redirection
|
||||||
getRedirect_saml2(request, response, authentication);
|
getRedirect_saml2(request, response, authentication);
|
||||||
}
|
} else if (authentication instanceof OAuth2AuthenticationToken) {
|
||||||
// Handle OAuth2 logout redirection
|
// Handle OAuth2 logout redirection
|
||||||
else if (authentication instanceof OAuth2AuthenticationToken) {
|
|
||||||
getRedirect_oauth2(request, response, authentication);
|
getRedirect_oauth2(request, response, authentication);
|
||||||
}
|
}
|
||||||
// Handle Username/Password logout
|
// Handle Username/Password logout
|
||||||
else if (authentication instanceof UsernamePasswordAuthenticationToken) {
|
else if (authentication instanceof UsernamePasswordAuthenticationToken) {
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
||||||
}
|
} else {
|
||||||
// Handle unknown authentication types
|
// Handle unknown authentication types
|
||||||
else {
|
|
||||||
log.error(
|
log.error(
|
||||||
"authentication class unknown: {}",
|
"Authentication class unknown: {}",
|
||||||
authentication.getClass().getSimpleName());
|
authentication.getClass().getSimpleName());
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Redirect to login page after logout
|
// Redirect to login page after logout
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,7 +123,7 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
samlClient.redirectToIdentityProvider(response, null, nameIdValue);
|
samlClient.redirectToIdentityProvider(response, null, nameIdValue);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(nameIdValue, e);
|
log.error(nameIdValue, e);
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
|
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,87 +131,81 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
private void getRedirect_oauth2(
|
private void getRedirect_oauth2(
|
||||||
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
String param = "logout=true";
|
String registrationId;
|
||||||
String registrationId = null;
|
|
||||||
String issuer = null;
|
|
||||||
String clientId = null;
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
String path = checkForErrors(request);
|
||||||
|
|
||||||
if (authentication instanceof OAuth2AuthenticationToken oauthToken) {
|
if (authentication instanceof OAuth2AuthenticationToken oauthToken) {
|
||||||
registrationId = oauthToken.getAuthorizedClientRegistrationId();
|
registrationId = oauthToken.getAuthorizedClientRegistrationId();
|
||||||
|
|
||||||
try {
|
|
||||||
// Get OAuth2 provider details from configuration
|
|
||||||
Provider provider = oauth.getClient().get(registrationId);
|
|
||||||
} catch (UnsupportedProviderException e) {
|
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
|
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
issuer = oauth.getIssuer();
|
String redirectUrl = UrlUtils.getOrigin(request) + "/login?" + path;
|
||||||
clientId = oauth.getClientId();
|
|
||||||
String errorMessage = "";
|
|
||||||
|
|
||||||
// Handle different error scenarios during logout
|
|
||||||
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
|
|
||||||
param = "erroroauth=oauth2AuthenticationErrorWeb";
|
|
||||||
} else if ((errorMessage = request.getParameter("error")) != null) {
|
|
||||||
param = "error=" + sanitizeInput(errorMessage);
|
|
||||||
} else if ((errorMessage = request.getParameter("erroroauth")) != null) {
|
|
||||||
param = "erroroauth=" + sanitizeInput(errorMessage);
|
|
||||||
} else if (request.getParameter("oauth2AutoCreateDisabled") != null) {
|
|
||||||
param = "error=oauth2AutoCreateDisabled";
|
|
||||||
} else if (request.getParameter("oauth2_admin_blocked_user") != null) {
|
|
||||||
param = "erroroauth=oauth2_admin_blocked_user";
|
|
||||||
} else if (request.getParameter("userIsDisabled") != null) {
|
|
||||||
param = "erroroauth=userIsDisabled";
|
|
||||||
} else if (request.getParameter("badcredentials") != null) {
|
|
||||||
param = "error=badcredentials";
|
|
||||||
}
|
|
||||||
|
|
||||||
String redirect_url = UrlUtils.getOrigin(request) + "/login?" + param;
|
|
||||||
|
|
||||||
// Redirect based on OAuth2 provider
|
// Redirect based on OAuth2 provider
|
||||||
switch (registrationId.toLowerCase()) {
|
switch (registrationId.toLowerCase()) {
|
||||||
case "keycloak" -> {
|
case "keycloak" -> {
|
||||||
// Add Keycloak specific logout URL if needed
|
|
||||||
String logoutUrl =
|
String logoutUrl =
|
||||||
issuer
|
oauth.getIssuer()
|
||||||
+ "/protocol/openid-connect/logout"
|
+ "/protocol/openid-connect/logout"
|
||||||
+ "?client_id="
|
+ "?client_id="
|
||||||
+ clientId
|
+ oauth.getClientId()
|
||||||
+ "&post_logout_redirect_uri="
|
+ "&post_logout_redirect_uri="
|
||||||
+ response.encodeRedirectURL(redirect_url);
|
+ response.encodeRedirectURL(redirectUrl);
|
||||||
log.info("Redirecting to Keycloak logout URL: " + logoutUrl);
|
log.info("Redirecting to Keycloak logout URL: {}", logoutUrl);
|
||||||
response.sendRedirect(logoutUrl);
|
response.sendRedirect(logoutUrl);
|
||||||
}
|
}
|
||||||
case "github" -> {
|
case "github", "google" -> {
|
||||||
// Add GitHub specific logout URL if needed
|
log.info(
|
||||||
// todo: why does the redirect go to github? shouldn't it come to Stirling PDF?
|
"No redirect URL for {} available. Redirecting to default logout URL: {}",
|
||||||
String githubLogoutUrl = "https://github.com/logout";
|
registrationId,
|
||||||
log.info("Redirecting to GitHub logout URL: " + redirect_url);
|
redirectUrl);
|
||||||
response.sendRedirect(redirect_url);
|
response.sendRedirect(redirectUrl);
|
||||||
}
|
|
||||||
case "google" -> {
|
|
||||||
// Add Google specific logout URL if needed
|
|
||||||
// String googleLogoutUrl =
|
|
||||||
// "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue="
|
|
||||||
// + response.encodeRedirectURL(redirect_url);
|
|
||||||
log.info("Google does not have a specific logout URL");
|
|
||||||
// log.info("Redirecting to Google logout URL: " + googleLogoutUrl);
|
|
||||||
// response.sendRedirect(googleLogoutUrl);
|
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
String defaultRedirectUrl = request.getContextPath() + "/login?" + param;
|
log.info("Redirecting to default logout URL: {}", redirectUrl);
|
||||||
log.info("Redirecting to default logout URL: {}", defaultRedirectUrl);
|
response.sendRedirect(redirectUrl);
|
||||||
response.sendRedirect(defaultRedirectUrl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitize input to avoid potential security vulnerabilities
|
/**
|
||||||
|
* Handles different error scenarios during logout. Will return a <code>String</code> containing
|
||||||
|
* the error request parameter.
|
||||||
|
*
|
||||||
|
* @param request the user's <code>HttpServletRequest</code> request.
|
||||||
|
* @return a <code>String</code> containing the error request parameter.
|
||||||
|
*/
|
||||||
|
private String checkForErrors(HttpServletRequest request) {
|
||||||
|
String errorMessage;
|
||||||
|
String path = "logout=true";
|
||||||
|
|
||||||
|
if (request.getParameter("oAuth2AuthenticationErrorWeb") != null) {
|
||||||
|
path = "errorOAuth=userAlreadyExistsWeb";
|
||||||
|
} else if ((errorMessage = request.getParameter("errorOAuth")) != null) {
|
||||||
|
path = "errorOAuth=" + sanitizeInput(errorMessage);
|
||||||
|
} else if (request.getParameter("oAuth2AutoCreateDisabled") != null) {
|
||||||
|
path = "errorOAuth=oAuth2AutoCreateDisabled";
|
||||||
|
} else if (request.getParameter("oAuth2AdminBlockedUser") != null) {
|
||||||
|
path = "errorOAuth=oAuth2AdminBlockedUser";
|
||||||
|
} else if (request.getParameter("userIsDisabled") != null) {
|
||||||
|
path = "errorOAuth=userIsDisabled";
|
||||||
|
} else if ((errorMessage = request.getParameter("error")) != null) {
|
||||||
|
path = "errorOAuth=" + sanitizeInput(errorMessage);
|
||||||
|
} else if (request.getParameter("badCredentials") != null) {
|
||||||
|
path = "errorOAuth=badCredentials";
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitize input to avoid potential security vulnerabilities. Will return a sanitised <code>
|
||||||
|
* String</code>.
|
||||||
|
*
|
||||||
|
* @return a sanitised <code>String</code>
|
||||||
|
*/
|
||||||
private String sanitizeInput(String input) {
|
private String sanitizeInput(String input) {
|
||||||
return input.replaceAll("[^a-zA-Z0-9 ]", "");
|
return input.replaceAll("[^a-zA-Z0-9 ]", "");
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ public class SecurityConfiguration {
|
|||||||
.permitAll());
|
.permitAll());
|
||||||
}
|
}
|
||||||
// Handle OAUTH2 Logins
|
// Handle OAUTH2 Logins
|
||||||
if (applicationProperties.getSecurity().isOauth2Activ()) {
|
if (applicationProperties.getSecurity().isOauth2Active()) {
|
||||||
http.oauth2Login(
|
http.oauth2Login(
|
||||||
oauth2 ->
|
oauth2 ->
|
||||||
oauth2.loginPage("/oauth2")
|
oauth2.loginPage("/oauth2")
|
||||||
@ -258,7 +258,7 @@ public class SecurityConfiguration {
|
|||||||
.permitAll());
|
.permitAll());
|
||||||
}
|
}
|
||||||
// Handle SAML
|
// Handle SAML
|
||||||
if (applicationProperties.getSecurity().isSaml2Activ()) {
|
if (applicationProperties.getSecurity().isSaml2Active()) {
|
||||||
// && runningEE
|
// && runningEE
|
||||||
// Configure the authentication provider
|
// Configure the authentication provider
|
||||||
OpenSaml4AuthenticationProvider authenticationProvider =
|
OpenSaml4AuthenticationProvider authenticationProvider =
|
||||||
|
@ -177,7 +177,7 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
if (blockRegistration && !isUserExists) {
|
if (blockRegistration && !isUserExists) {
|
||||||
log.warn("Blocked registration for OAuth2/SAML user: {}", username);
|
log.warn("Blocked registration for OAuth2/SAML user: {}", username);
|
||||||
response.sendRedirect(
|
response.sendRedirect(
|
||||||
request.getContextPath() + "/logout?oauth2_admin_blocked_user=true");
|
request.getContextPath() + "/logout?oAuth2AdminBlockedUser=true");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
|
|
||||||
// Redirect to logout if credentials are invalid
|
// Redirect to logout if credentials are invalid
|
||||||
if (!isUserExists && notSsoLogin) {
|
if (!isUserExists && notSsoLogin) {
|
||||||
response.sendRedirect(request.getContextPath() + "/logout?badcredentials=true");
|
response.sendRedirect(request.getContextPath() + "/logout?badCredentials=true");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isUserDisabled) {
|
if (isUserDisabled) {
|
||||||
|
@ -29,7 +29,7 @@ public class CustomOAuth2AuthenticationFailureHandler
|
|||||||
|
|
||||||
if (exception instanceof BadCredentialsException) {
|
if (exception instanceof BadCredentialsException) {
|
||||||
log.error("BadCredentialsException", exception);
|
log.error("BadCredentialsException", exception);
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?error=badcredentials");
|
getRedirectStrategy().sendRedirect(request, response, "/login?error=badCredentials");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (exception instanceof DisabledException) {
|
if (exception instanceof DisabledException) {
|
||||||
@ -52,8 +52,7 @@ public class CustomOAuth2AuthenticationFailureHandler
|
|||||||
}
|
}
|
||||||
log.error("OAuth2 Authentication error: " + errorCode);
|
log.error("OAuth2 Authentication error: " + errorCode);
|
||||||
log.error("OAuth2AuthenticationException", exception);
|
log.error("OAuth2AuthenticationException", exception);
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?erroroauth=" + errorCode);
|
getRedirectStrategy().sendRedirect(request, response, "/login?errorOAuth=" + errorCode);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
log.error("Unhandled authentication exception", exception);
|
log.error("Unhandled authentication exception", exception);
|
||||||
super.onAuthenticationFailure(request, response, exception);
|
super.onAuthenticationFailure(request, response, exception);
|
||||||
|
@ -26,13 +26,12 @@ import stirling.software.SPDF.utils.RequestUriUtils;
|
|||||||
public class CustomOAuth2AuthenticationSuccessHandler
|
public class CustomOAuth2AuthenticationSuccessHandler
|
||||||
extends SavedRequestAwareAuthenticationSuccessHandler {
|
extends SavedRequestAwareAuthenticationSuccessHandler {
|
||||||
|
|
||||||
private LoginAttemptService loginAttemptService;
|
private final LoginAttemptService loginAttemptService;
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
private ApplicationProperties applicationProperties;
|
private final UserService userService;
|
||||||
private UserService userService;
|
|
||||||
|
|
||||||
public CustomOAuth2AuthenticationSuccessHandler(
|
public CustomOAuth2AuthenticationSuccessHandler(
|
||||||
final LoginAttemptService loginAttemptService,
|
LoginAttemptService loginAttemptService,
|
||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
UserService userService) {
|
UserService userService) {
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
@ -76,23 +75,22 @@ public class CustomOAuth2AuthenticationSuccessHandler
|
|||||||
throw new LockedException(
|
throw new LockedException(
|
||||||
"Your account has been locked due to too many failed login attempts.");
|
"Your account has been locked due to too many failed login attempts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userService.isUserDisabled(username)) {
|
if (userService.isUserDisabled(username)) {
|
||||||
getRedirectStrategy()
|
getRedirectStrategy()
|
||||||
.sendRedirect(request, response, "/logout?userIsDisabled=true");
|
.sendRedirect(request, response, "/logout?userIsDisabled=true");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (userService.usernameExistsIgnoreCase(username)
|
if (userService.usernameExistsIgnoreCase(username)
|
||||||
&& userService.hasPassword(username)
|
&& userService.hasPassword(username)
|
||||||
&& !userService.isAuthenticationTypeByUsername(username, AuthenticationType.SSO)
|
&& !userService.isAuthenticationTypeByUsername(username, AuthenticationType.SSO)
|
||||||
&& oAuth.getAutoCreateUser()) {
|
&& oAuth.getAutoCreateUser()) {
|
||||||
response.sendRedirect(contextPath + "/logout?oauth2AuthenticationErrorWeb=true");
|
response.sendRedirect(contextPath + "/logout?oAuth2AuthenticationErrorWeb=true");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (oAuth.getBlockRegistration()
|
if (oAuth.getBlockRegistration()
|
||||||
&& !userService.usernameExistsIgnoreCase(username)) {
|
&& !userService.usernameExistsIgnoreCase(username)) {
|
||||||
response.sendRedirect(contextPath + "/logout?oauth2_admin_blocked_user=true");
|
response.sendRedirect(contextPath + "/logout?oAuth2AdminBlockedUser=true");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (principal instanceof OAuth2User) {
|
if (principal instanceof OAuth2User) {
|
||||||
userService.processSSOPostLogin(username, oAuth.getAutoCreateUser());
|
userService.processSSOPostLogin(username, oAuth.getAutoCreateUser());
|
||||||
|
@ -25,11 +25,11 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
|
|
||||||
private final OidcUserService delegate = new OidcUserService();
|
private final OidcUserService delegate = new OidcUserService();
|
||||||
|
|
||||||
private UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
private LoginAttemptService loginAttemptService;
|
private final LoginAttemptService loginAttemptService;
|
||||||
|
|
||||||
private ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
public CustomOAuth2UserService(
|
public CustomOAuth2UserService(
|
||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
@ -45,8 +45,9 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
String usernameAttribute = oauth2.getUseAsUsername();
|
String usernameAttribute = oauth2.getUseAsUsername();
|
||||||
|
|
||||||
if (usernameAttribute == null || usernameAttribute.trim().isEmpty()) {
|
if (usernameAttribute == null || usernameAttribute.isEmpty()) {
|
||||||
Client client = oauth2.getClient();
|
Client client = oauth2.getClient();
|
||||||
|
|
||||||
if (client != null && client.getKeycloak() != null) {
|
if (client != null && client.getKeycloak() != null) {
|
||||||
usernameAttribute = client.getKeycloak().getUseAsUsername();
|
usernameAttribute = client.getKeycloak().getUseAsUsername();
|
||||||
} else {
|
} else {
|
||||||
@ -59,13 +60,14 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
String username = user.getUserInfo().getClaimAsString(usernameAttribute);
|
String username = user.getUserInfo().getClaimAsString(usernameAttribute);
|
||||||
|
|
||||||
// Check if the username claim is null or empty
|
// Check if the username claim is null or empty
|
||||||
if (username == null || username.trim().isEmpty()) {
|
if (username == null || username.isBlank()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Claim '" + usernameAttribute + "' cannot be null or empty");
|
"Claim '" + usernameAttribute + "' cannot be null or empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<User> duser = userService.findByUsernameIgnoreCase(username);
|
Optional<User> internalUser = userService.findByUsernameIgnoreCase(username);
|
||||||
if (duser.isPresent()) {
|
|
||||||
|
if (internalUser.isPresent()) {
|
||||||
if (loginAttemptService.isBlocked(username)) {
|
if (loginAttemptService.isBlocked(username)) {
|
||||||
throw new LockedException(
|
throw new LockedException(
|
||||||
"Your account has been locked due to too many failed login attempts.");
|
"Your account has been locked due to too many failed login attempts.");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package stirling.software.SPDF.config.security.oauth2;
|
package stirling.software.SPDF.config.security.oauth2;
|
||||||
|
|
||||||
import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE;
|
import static org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE;
|
||||||
|
import static stirling.software.SPDF.utils.validation.Validator.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -28,9 +29,11 @@ import stirling.software.SPDF.model.ApplicationProperties;
|
|||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
||||||
import stirling.software.SPDF.model.User;
|
import stirling.software.SPDF.model.User;
|
||||||
import stirling.software.SPDF.model.provider.GithubProvider;
|
import stirling.software.SPDF.model.exception.NoProviderFoundException;
|
||||||
|
import stirling.software.SPDF.model.provider.GitHubProvider;
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||||
|
import stirling.software.SPDF.model.provider.Provider;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -50,7 +53,8 @@ public class OAuth2Configuration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true")
|
@ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true")
|
||||||
public ClientRegistrationRepository clientRegistrationRepository() {
|
public ClientRegistrationRepository clientRegistrationRepository()
|
||||||
|
throws NoProviderFoundException {
|
||||||
List<ClientRegistration> registrations = new ArrayList<>();
|
List<ClientRegistration> registrations = new ArrayList<>();
|
||||||
githubClientRegistration().ifPresent(registrations::add);
|
githubClientRegistration().ifPresent(registrations::add);
|
||||||
oidcClientRegistration().ifPresent(registrations::add);
|
oidcClientRegistration().ifPresent(registrations::add);
|
||||||
@ -58,54 +62,31 @@ public class OAuth2Configuration {
|
|||||||
keycloakClientRegistration().ifPresent(registrations::add);
|
keycloakClientRegistration().ifPresent(registrations::add);
|
||||||
|
|
||||||
if (registrations.isEmpty()) {
|
if (registrations.isEmpty()) {
|
||||||
log.error("At least one OAuth2 provider must be configured");
|
log.error("No OAuth2 provider registered");
|
||||||
System.exit(1);
|
throw new NoProviderFoundException("At least one OAuth2 provider must be configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InMemoryClientRegistrationRepository(registrations);
|
return new InMemoryClientRegistrationRepository(registrations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> googleClientRegistration() {
|
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
|
||||||
|
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
Client client = oauth.getClient();
|
|
||||||
|
|
||||||
if (client == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
GoogleProvider google = client.getGoogle();
|
|
||||||
return google != null && google.isSettingsValid()
|
|
||||||
? Optional.of(
|
|
||||||
ClientRegistration.withRegistrationId(google.getName())
|
|
||||||
.clientId(google.getClientId())
|
|
||||||
.clientSecret(google.getClientSecret())
|
|
||||||
.scope(google.getScopes())
|
|
||||||
.authorizationUri(google.getAuthorizationUri())
|
|
||||||
.tokenUri(google.getTokenUri())
|
|
||||||
.userInfoUri(google.getUserinfoUri())
|
|
||||||
.userNameAttributeName(google.getUseAsUsername())
|
|
||||||
.clientName(google.getClientName())
|
|
||||||
.redirectUri(REDIRECT_URI_PATH + google.getName())
|
|
||||||
.authorizationGrantType(AUTHORIZATION_CODE)
|
|
||||||
.build())
|
|
||||||
: Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ClientRegistration> keycloakClientRegistration() {
|
private Optional<ClientRegistration> keycloakClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
|
if (isOAuth2Enabled(oauth2) || isClientInitialised(oauth2)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
Client client = oauth.getClient();
|
|
||||||
if (client == null) {
|
Client client = oauth2.getClient();
|
||||||
return Optional.empty();
|
KeycloakProvider keycloakClient = client.getKeycloak();
|
||||||
}
|
Provider keycloak =
|
||||||
KeycloakProvider keycloak = client.getKeycloak();
|
new KeycloakProvider(
|
||||||
return keycloak != null && keycloak.isSettingsValid()
|
keycloakClient.getIssuer(),
|
||||||
|
keycloakClient.getClientId(),
|
||||||
|
keycloakClient.getClientSecret(),
|
||||||
|
keycloakClient.getScopes(),
|
||||||
|
keycloakClient.getUseAsUsername());
|
||||||
|
|
||||||
|
return validateProvider(keycloak)
|
||||||
? Optional.of(
|
? Optional.of(
|
||||||
ClientRegistrations.fromIssuerLocation(keycloak.getIssuer())
|
ClientRegistrations.fromIssuerLocation(keycloak.getIssuer())
|
||||||
.registrationId(keycloak.getName())
|
.registrationId(keycloak.getName())
|
||||||
@ -118,15 +99,56 @@ public class OAuth2Configuration {
|
|||||||
: Optional.empty();
|
: Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> githubClientRegistration() {
|
private Optional<ClientRegistration> googleClientRegistration() {
|
||||||
if (isOauthOrClientEmpty()) {
|
OAUTH2 oAuth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
|
if (isOAuth2Enabled(oAuth2) || isClientInitialised(oAuth2)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
GithubProvider github =
|
Client client = oAuth2.getClient();
|
||||||
applicationProperties.getSecurity().getOauth2().getClient().getGithub();
|
GoogleProvider googleClient = client.getGoogle();
|
||||||
|
Provider google =
|
||||||
|
new GoogleProvider(
|
||||||
|
googleClient.getClientId(),
|
||||||
|
googleClient.getClientSecret(),
|
||||||
|
googleClient.getScopes(),
|
||||||
|
googleClient.getUseAsUsername());
|
||||||
|
|
||||||
return github != null && github.isSettingsValid()
|
return validateProvider(google)
|
||||||
|
? Optional.of(
|
||||||
|
ClientRegistration.withRegistrationId(google.getName())
|
||||||
|
.clientId(google.getClientId())
|
||||||
|
.clientSecret(google.getClientSecret())
|
||||||
|
.scope(google.getScopes())
|
||||||
|
.authorizationUri(google.getAuthorizationUri())
|
||||||
|
.tokenUri(google.getTokenUri())
|
||||||
|
.userInfoUri(google.getUserInfoUri())
|
||||||
|
.userNameAttributeName(google.getUseAsUsername())
|
||||||
|
.clientName(google.getClientName())
|
||||||
|
.redirectUri(REDIRECT_URI_PATH + google.getName())
|
||||||
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
|
.build())
|
||||||
|
: Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ClientRegistration> githubClientRegistration() {
|
||||||
|
OAUTH2 oAuth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
|
if (isOAuth2Enabled(oAuth2)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Client client = oAuth2.getClient();
|
||||||
|
GitHubProvider githubClient = client.getGithub();
|
||||||
|
Provider github =
|
||||||
|
new GitHubProvider(
|
||||||
|
githubClient.getClientId(),
|
||||||
|
githubClient.getClientSecret(),
|
||||||
|
githubClient.getScopes(),
|
||||||
|
githubClient.getUseAsUsername());
|
||||||
|
|
||||||
|
return validateProvider(github)
|
||||||
? Optional.of(
|
? Optional.of(
|
||||||
ClientRegistration.withRegistrationId(github.getName())
|
ClientRegistration.withRegistrationId(github.getName())
|
||||||
.clientId(github.getClientId())
|
.clientId(github.getClientId())
|
||||||
@ -134,7 +156,7 @@ public class OAuth2Configuration {
|
|||||||
.scope(github.getScopes())
|
.scope(github.getScopes())
|
||||||
.authorizationUri(github.getAuthorizationUri())
|
.authorizationUri(github.getAuthorizationUri())
|
||||||
.tokenUri(github.getTokenUri())
|
.tokenUri(github.getTokenUri())
|
||||||
.userInfoUri(github.getUserinfoUri())
|
.userInfoUri(github.getUserInfoUri())
|
||||||
.userNameAttributeName(github.getUseAsUsername())
|
.userNameAttributeName(github.getUseAsUsername())
|
||||||
.clientName(github.getClientName())
|
.clientName(github.getClientName())
|
||||||
.redirectUri(REDIRECT_URI_PATH + github.getName())
|
.redirectUri(REDIRECT_URI_PATH + github.getName())
|
||||||
@ -146,49 +168,49 @@ public class OAuth2Configuration {
|
|||||||
private Optional<ClientRegistration> oidcClientRegistration() {
|
private Optional<ClientRegistration> oidcClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (oauth == null
|
if (isOAuth2Enabled(oauth) || isClientInitialised(oauth)) {
|
||||||
|| oauth.getIssuer() == null
|
|
||||||
|| oauth.getIssuer().isEmpty()
|
|
||||||
|| oauth.getClientId() == null
|
|
||||||
|| oauth.getClientId().isEmpty()
|
|
||||||
|| oauth.getClientSecret() == null
|
|
||||||
|| oauth.getClientSecret().isEmpty()
|
|
||||||
|| oauth.getScopes() == null
|
|
||||||
|| oauth.getScopes().isEmpty()
|
|
||||||
|| oauth.getUseAsUsername() == null
|
|
||||||
|| oauth.getUseAsUsername().isEmpty()) {
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isStringEmpty(oauth.getIssuer())
|
||||||
|
|| isStringEmpty(oauth.getClientId())
|
||||||
|
|| isStringEmpty(oauth.getClientSecret())
|
||||||
|
|| isCollectionEmpty(oauth.getScopes())
|
||||||
|
|| isStringEmpty(oauth.getUseAsUsername())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = oauth.getProvider();
|
||||||
|
String firstChar = String.valueOf(name.charAt(0));
|
||||||
|
String clientName = name.replaceFirst(firstChar, firstChar.toUpperCase());
|
||||||
|
|
||||||
return Optional.of(
|
return Optional.of(
|
||||||
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
|
||||||
.registrationId("oidc")
|
.registrationId(name)
|
||||||
.clientId(oauth.getClientId())
|
.clientId(oauth.getClientId())
|
||||||
.clientSecret(oauth.getClientSecret())
|
.clientSecret(oauth.getClientSecret())
|
||||||
.scope(oauth.getScopes())
|
.scope(oauth.getScopes())
|
||||||
.userNameAttributeName(oauth.getUseAsUsername())
|
.userNameAttributeName(oauth.getUseAsUsername())
|
||||||
.clientName("OIDC")
|
.clientName(clientName)
|
||||||
.redirectUri(REDIRECT_URI_PATH + "oidc")
|
.redirectUri(REDIRECT_URI_PATH + name)
|
||||||
.authorizationGrantType(AUTHORIZATION_CODE)
|
.authorizationGrantType(AUTHORIZATION_CODE)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOauthOrClientEmpty() {
|
private boolean isOAuth2Enabled(OAUTH2 oAuth2) {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
return oAuth2 == null || !oAuth2.getEnabled();
|
||||||
|
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client client = oauth.getClient();
|
private boolean isClientInitialised(OAUTH2 oauth2) {
|
||||||
|
Client client = oauth2.getClient();
|
||||||
return client != null;
|
return client == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
|
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
|
||||||
This is required for the internal; 'hasRole()' function to give out the correct role.
|
This is required for the internal; 'hasRole()' function to give out the correct role.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(
|
||||||
value = "security.oauth2.enabled",
|
value = "security.oauth2.enabled",
|
||||||
@ -213,13 +235,11 @@ public class OAuth2Configuration {
|
|||||||
(String) oauth2Auth.getAttributes().get(useAsUsername));
|
(String) oauth2Auth.getAttributes().get(useAsUsername));
|
||||||
if (userOpt.isPresent()) {
|
if (userOpt.isPresent()) {
|
||||||
User user = userOpt.get();
|
User user = userOpt.get();
|
||||||
if (user != null) {
|
|
||||||
mappedAuthorities.add(
|
mappedAuthorities.add(
|
||||||
new SimpleGrantedAuthority(
|
new SimpleGrantedAuthority(
|
||||||
userService.findRole(user).getAuthority()));
|
userService.findRole(user).getAuthority()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return mappedAuthorities;
|
return mappedAuthorities;
|
||||||
};
|
};
|
||||||
|
@ -26,13 +26,13 @@ public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthentica
|
|||||||
if (exception instanceof Saml2AuthenticationException) {
|
if (exception instanceof Saml2AuthenticationException) {
|
||||||
Saml2Error error = ((Saml2AuthenticationException) exception).getSaml2Error();
|
Saml2Error error = ((Saml2AuthenticationException) exception).getSaml2Error();
|
||||||
getRedirectStrategy()
|
getRedirectStrategy()
|
||||||
.sendRedirect(request, response, "/login?erroroauth=" + error.getErrorCode());
|
.sendRedirect(request, response, "/login?errorOAuth=" + error.getErrorCode());
|
||||||
} else if (exception instanceof ProviderNotFoundException) {
|
} else if (exception instanceof ProviderNotFoundException) {
|
||||||
getRedirectStrategy()
|
getRedirectStrategy()
|
||||||
.sendRedirect(
|
.sendRedirect(
|
||||||
request,
|
request,
|
||||||
response,
|
response,
|
||||||
"/login?erroroauth=not_authentication_provider_found");
|
"/login?errorOAuth=not_authentication_provider_found");
|
||||||
}
|
}
|
||||||
log.error("AuthenticationException: " + exception);
|
log.error("AuthenticationException: " + exception);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ public class CustomSaml2AuthenticationSuccessHandler
|
|||||||
"User {} exists with password but is not SSO user, redirecting to logout",
|
"User {} exists with password but is not SSO user, redirecting to logout",
|
||||||
username);
|
username);
|
||||||
response.sendRedirect(
|
response.sendRedirect(
|
||||||
contextPath + "/logout?oauth2AuthenticationErrorWeb=true");
|
contextPath + "/logout?oAuth2AuthenticationErrorWeb=true");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ public class CustomSaml2AuthenticationSuccessHandler
|
|||||||
if (saml2.getBlockRegistration() && !userExists) {
|
if (saml2.getBlockRegistration() && !userExists) {
|
||||||
log.debug("Registration blocked for new user: {}", username);
|
log.debug("Registration blocked for new user: {}", username);
|
||||||
response.sendRedirect(
|
response.sendRedirect(
|
||||||
contextPath + "/login?erroroauth=oauth2_admin_blocked_user");
|
contextPath + "/login?errorOAuth=oAuth2AdminBlockedUser");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.debug("Processing SSO post-login for user: {}", username);
|
log.debug("Processing SSO post-login for user: {}", username);
|
||||||
|
@ -26,24 +26,17 @@ import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
|||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(value = "security.saml2.enabled", havingValue = "true")
|
||||||
value = "security.saml2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public class SAML2Configuration {
|
public class SAML2Configuration {
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
public SAML2Configuration(ApplicationProperties applicationProperties) {
|
public SAML2Configuration(ApplicationProperties applicationProperties) {
|
||||||
|
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true")
|
||||||
name = "security.saml2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
|
public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
|
||||||
SAML2 samlConf = applicationProperties.getSecurity().getSaml2();
|
SAML2 samlConf = applicationProperties.getSecurity().getSaml2();
|
||||||
X509Certificate idpCert = CertificateUtils.readCertificate(samlConf.getidpCert());
|
X509Certificate idpCert = CertificateUtils.readCertificate(samlConf.getidpCert());
|
||||||
@ -73,10 +66,7 @@ public class SAML2Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(name = "security.saml2.enabled", havingValue = "true")
|
||||||
name = "security.saml2.enabled",
|
|
||||||
havingValue = "true",
|
|
||||||
matchIfMissing = false)
|
|
||||||
public OpenSaml4AuthenticationRequestResolver authenticationRequestResolver(
|
public OpenSaml4AuthenticationRequestResolver authenticationRequestResolver(
|
||||||
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository) {
|
||||||
OpenSaml4AuthenticationRequestResolver resolver =
|
OpenSaml4AuthenticationRequestResolver resolver =
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package stirling.software.SPDF.controller.web;
|
package stirling.software.SPDF.controller.web;
|
||||||
|
|
||||||
|
import static stirling.software.SPDF.utils.validation.Validator.validateProvider;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -29,7 +31,7 @@ import stirling.software.SPDF.model.ApplicationProperties.Security;
|
|||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
|
||||||
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
|
||||||
import stirling.software.SPDF.model.provider.GithubProvider;
|
import stirling.software.SPDF.model.provider.GitHubProvider;
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||||
import stirling.software.SPDF.repository.UserRepository;
|
import stirling.software.SPDF.repository.UserRepository;
|
||||||
@ -40,12 +42,11 @@ import stirling.software.SPDF.repository.UserRepository;
|
|||||||
public class AccountWebController {
|
public class AccountWebController {
|
||||||
|
|
||||||
public static final String OAUTH_2_AUTHORIZATION = "/oauth2/authorization/";
|
public static final String OAUTH_2_AUTHORIZATION = "/oauth2/authorization/";
|
||||||
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
private final SessionPersistentRegistry sessionPersistentRegistry;
|
private final SessionPersistentRegistry sessionPersistentRegistry;
|
||||||
|
// Assuming you have a repository for user operations
|
||||||
private final UserRepository // Assuming you have a repository for user operations
|
private final UserRepository userRepository;
|
||||||
userRepository;
|
|
||||||
|
|
||||||
public AccountWebController(
|
public AccountWebController(
|
||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
@ -62,28 +63,40 @@ public class AccountWebController {
|
|||||||
if (authentication != null && authentication.isAuthenticated()) {
|
if (authentication != null && authentication.isAuthenticated()) {
|
||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> providerList = new HashMap<>();
|
Map<String, String> providerList = new HashMap<>();
|
||||||
Security securityProps = applicationProperties.getSecurity();
|
Security securityProps = applicationProperties.getSecurity();
|
||||||
OAUTH2 oauth = securityProps.getOauth2();
|
OAUTH2 oauth = securityProps.getOauth2();
|
||||||
|
|
||||||
if (oauth != null) {
|
if (oauth != null) {
|
||||||
if (oauth.getEnabled()) {
|
if (oauth.getEnabled()) {
|
||||||
if (oauth.isSettingsValid()) {
|
if (oauth.isSettingsValid()) {
|
||||||
providerList.put(OAUTH_2_AUTHORIZATION + "oidc", oauth.getProvider());
|
String firstChar = String.valueOf(oauth.getProvider().charAt(0));
|
||||||
|
String clientName =
|
||||||
|
oauth.getProvider().replaceFirst(firstChar, firstChar.toUpperCase());
|
||||||
|
providerList.put(OAUTH_2_AUTHORIZATION + "oidc", clientName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Client client = oauth.getClient();
|
Client client = oauth.getClient();
|
||||||
|
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
GoogleProvider google = client.getGoogle();
|
GoogleProvider google = client.getGoogle();
|
||||||
if (google.isSettingsValid()) {
|
|
||||||
|
if (validateProvider(google)) {
|
||||||
providerList.put(
|
providerList.put(
|
||||||
OAUTH_2_AUTHORIZATION + google.getName(), google.getClientName());
|
OAUTH_2_AUTHORIZATION + google.getName(), google.getClientName());
|
||||||
}
|
}
|
||||||
GithubProvider github = client.getGithub();
|
|
||||||
if (github.isSettingsValid()) {
|
GitHubProvider github = client.getGithub();
|
||||||
|
|
||||||
|
if (validateProvider(github)) {
|
||||||
providerList.put(
|
providerList.put(
|
||||||
OAUTH_2_AUTHORIZATION + github.getName(), github.getClientName());
|
OAUTH_2_AUTHORIZATION + github.getName(), github.getClientName());
|
||||||
}
|
}
|
||||||
|
|
||||||
KeycloakProvider keycloak = client.getKeycloak();
|
KeycloakProvider keycloak = client.getKeycloak();
|
||||||
if (keycloak.isSettingsValid()) {
|
|
||||||
|
if (validateProvider(keycloak)) {
|
||||||
providerList.put(
|
providerList.put(
|
||||||
OAUTH_2_AUTHORIZATION + keycloak.getName(),
|
OAUTH_2_AUTHORIZATION + keycloak.getName(),
|
||||||
keycloak.getClientName());
|
keycloak.getClientName());
|
||||||
@ -91,101 +104,74 @@ public class AccountWebController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SAML2 saml2 = securityProps.getSaml2();
|
SAML2 saml2 = securityProps.getSaml2();
|
||||||
if (securityProps.isSaml2Activ()
|
|
||||||
|
if (securityProps.isSaml2Active()
|
||||||
&& applicationProperties.getSystem().getEnableAlphaFunctionality()) {
|
&& applicationProperties.getSystem().getEnableAlphaFunctionality()) {
|
||||||
providerList.put("/saml2/authenticate/" + saml2.getRegistrationId(), "SAML 2");
|
providerList.put("/saml2/authenticate/" + saml2.getRegistrationId(), "SAML 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove any null keys/values from the providerList
|
// Remove any null keys/values from the providerList
|
||||||
providerList
|
providerList
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.removeIf(entry -> entry.getKey() == null || entry.getValue() == null);
|
.removeIf(entry -> entry.getKey() == null || entry.getValue() == null);
|
||||||
model.addAttribute("providerlist", providerList);
|
model.addAttribute("providerList", providerList);
|
||||||
model.addAttribute("loginMethod", securityProps.getLoginMethod());
|
model.addAttribute("loginMethod", securityProps.getLoginMethod());
|
||||||
|
|
||||||
boolean altLogin = !providerList.isEmpty() ? securityProps.isAltLogin() : false;
|
boolean altLogin = !providerList.isEmpty() ? securityProps.isAltLogin() : false;
|
||||||
|
|
||||||
model.addAttribute("altLogin", altLogin);
|
model.addAttribute("altLogin", altLogin);
|
||||||
model.addAttribute("currentPage", "login");
|
model.addAttribute("currentPage", "login");
|
||||||
String error = request.getParameter("error");
|
String error = request.getParameter("error");
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case "badcredentials":
|
case "badCredentials" -> error = "login.invalid";
|
||||||
error = "login.invalid";
|
case "locked" -> error = "login.locked";
|
||||||
break;
|
case "oauth2AuthenticationError" -> error = "userAlreadyExistsOAuthMessage";
|
||||||
case "locked":
|
|
||||||
error = "login.locked";
|
|
||||||
break;
|
|
||||||
case "oauth2AuthenticationError":
|
|
||||||
error = "userAlreadyExistsOAuthMessage";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addAttribute("error", error);
|
model.addAttribute("error", error);
|
||||||
}
|
}
|
||||||
String erroroauth = request.getParameter("erroroauth");
|
String errorOAuth = request.getParameter("errorOAuth");
|
||||||
if (erroroauth != null) {
|
if (errorOAuth != null) {
|
||||||
switch (erroroauth) {
|
switch (errorOAuth) {
|
||||||
case "oauth2AutoCreateDisabled":
|
case "oAuth2AutoCreateDisabled" -> errorOAuth = "login.oAuth2AutoCreateDisabled";
|
||||||
erroroauth = "login.oauth2AutoCreateDisabled";
|
case "invalidUsername" -> errorOAuth = "login.invalid";
|
||||||
break;
|
case "userAlreadyExistsWeb" -> errorOAuth = "userAlreadyExistsWebMessage";
|
||||||
case "invalidUsername":
|
case "oAuth2AuthenticationErrorWeb" -> errorOAuth = "login.oauth2InvalidUserType";
|
||||||
erroroauth = "login.invalid";
|
case "invalid_token_response" -> errorOAuth = "login.oauth2InvalidTokenResponse";
|
||||||
break;
|
case "authorization_request_not_found" ->
|
||||||
case "userAlreadyExistsWeb":
|
errorOAuth = "login.oauth2RequestNotFound";
|
||||||
erroroauth = "userAlreadyExistsWebMessage";
|
case "access_denied" -> errorOAuth = "login.oauth2AccessDenied";
|
||||||
break;
|
case "invalid_user_info_response" ->
|
||||||
case "oauth2AuthenticationErrorWeb":
|
errorOAuth = "login.oauth2InvalidUserInfoResponse";
|
||||||
erroroauth = "login.oauth2InvalidUserType";
|
case "invalid_request" -> errorOAuth = "login.oauth2invalidRequest";
|
||||||
break;
|
case "invalid_id_token" -> errorOAuth = "login.oauth2InvalidIdToken";
|
||||||
case "invalid_token_response":
|
case "oAuth2AdminBlockedUser" -> errorOAuth = "login.oAuth2AdminBlockedUser";
|
||||||
erroroauth = "login.oauth2InvalidTokenResponse";
|
case "userIsDisabled" -> errorOAuth = "login.userIsDisabled";
|
||||||
break;
|
case "invalid_destination" -> errorOAuth = "login.invalid_destination";
|
||||||
case "authorization_request_not_found":
|
case "relying_party_registration_not_found" ->
|
||||||
erroroauth = "login.oauth2RequestNotFound";
|
errorOAuth = "login.relyingPartyRegistrationNotFound";
|
||||||
break;
|
|
||||||
case "access_denied":
|
|
||||||
erroroauth = "login.oauth2AccessDenied";
|
|
||||||
break;
|
|
||||||
case "invalid_user_info_response":
|
|
||||||
erroroauth = "login.oauth2InvalidUserInfoResponse";
|
|
||||||
break;
|
|
||||||
case "invalid_request":
|
|
||||||
erroroauth = "login.oauth2invalidRequest";
|
|
||||||
break;
|
|
||||||
case "invalid_id_token":
|
|
||||||
erroroauth = "login.oauth2InvalidIdToken";
|
|
||||||
break;
|
|
||||||
case "oauth2_admin_blocked_user":
|
|
||||||
erroroauth = "login.oauth2AdminBlockedUser";
|
|
||||||
break;
|
|
||||||
case "userIsDisabled":
|
|
||||||
erroroauth = "login.userIsDisabled";
|
|
||||||
break;
|
|
||||||
case "invalid_destination":
|
|
||||||
erroroauth = "login.invalid_destination";
|
|
||||||
break;
|
|
||||||
case "relying_party_registration_not_found":
|
|
||||||
erroroauth = "login.relyingPartyRegistrationNotFound";
|
|
||||||
break;
|
|
||||||
// Valid InResponseTo was not available from the validation context, unable to
|
// Valid InResponseTo was not available from the validation context, unable to
|
||||||
// evaluate
|
// evaluate
|
||||||
case "invalid_in_response_to":
|
case "invalid_in_response_to" -> errorOAuth = "login.invalid_in_response_to";
|
||||||
erroroauth = "login.invalid_in_response_to";
|
case "not_authentication_provider_found" ->
|
||||||
break;
|
errorOAuth = "login.not_authentication_provider_found";
|
||||||
case "not_authentication_provider_found":
|
|
||||||
erroroauth = "login.not_authentication_provider_found";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
model.addAttribute("erroroauth", erroroauth);
|
|
||||||
|
model.addAttribute("errorOAuth", errorOAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getParameter("messageType") != null) {
|
if (request.getParameter("messageType") != null) {
|
||||||
model.addAttribute("messageType", "changedCredsMessage");
|
model.addAttribute("messageType", "changedCredsMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getParameter("logout") != null) {
|
if (request.getParameter("logout") != null) {
|
||||||
model.addAttribute("logoutMessage", "You have been logged out.");
|
model.addAttribute("logoutMessage", "You have been logged out.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return "login";
|
return "login";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,40 +325,28 @@ public class AccountWebController {
|
|||||||
if (authentication != null && authentication.isAuthenticated()) {
|
if (authentication != null && authentication.isAuthenticated()) {
|
||||||
Object principal = authentication.getPrincipal();
|
Object principal = authentication.getPrincipal();
|
||||||
String username = null;
|
String username = null;
|
||||||
if (principal instanceof UserDetails) {
|
if (principal instanceof UserDetails userDetails) {
|
||||||
// Cast the principal object to UserDetails
|
|
||||||
UserDetails userDetails = (UserDetails) principal;
|
|
||||||
// Retrieve username and other attributes
|
// Retrieve username and other attributes
|
||||||
username = userDetails.getUsername();
|
username = userDetails.getUsername();
|
||||||
// Add oAuth2 Login attributes to the model
|
// Add oAuth2 Login attributes to the model
|
||||||
model.addAttribute("oAuth2Login", false);
|
model.addAttribute("oAuth2Login", false);
|
||||||
}
|
}
|
||||||
if (principal instanceof OAuth2User) {
|
if (principal instanceof OAuth2User userDetails) {
|
||||||
// Cast the principal object to OAuth2User
|
|
||||||
OAuth2User userDetails = (OAuth2User) principal;
|
|
||||||
// Retrieve username and other attributes
|
// Retrieve username and other attributes
|
||||||
username =
|
username = userDetails.getName();
|
||||||
userDetails.getAttribute(
|
|
||||||
applicationProperties.getSecurity().getOauth2().getUseAsUsername());
|
|
||||||
// Add oAuth2 Login attributes to the model
|
// Add oAuth2 Login attributes to the model
|
||||||
model.addAttribute("oAuth2Login", true);
|
model.addAttribute("oAuth2Login", true);
|
||||||
}
|
}
|
||||||
if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
|
if (principal instanceof CustomSaml2AuthenticatedPrincipal userDetails) {
|
||||||
// Cast the principal object to OAuth2User
|
|
||||||
CustomSaml2AuthenticatedPrincipal userDetails =
|
|
||||||
(CustomSaml2AuthenticatedPrincipal) principal;
|
|
||||||
// Retrieve username and other attributes
|
// Retrieve username and other attributes
|
||||||
username = userDetails.getName();
|
username = userDetails.getName();
|
||||||
// Add oAuth2 Login attributes to the model
|
// Add oAuth2 Login attributes to the model
|
||||||
model.addAttribute("oAuth2Login", true);
|
model.addAttribute("oAuth2Login", true);
|
||||||
}
|
}
|
||||||
if (username != null) {
|
if (username != null) {
|
||||||
// Fetch user details from the database
|
// Fetch user details from the database, assuming findByUsername method exists
|
||||||
Optional<User> user =
|
Optional<User> user = userRepository.findByUsernameIgnoreCaseWithSettings(username);
|
||||||
userRepository
|
|
||||||
.findByUsernameIgnoreCaseWithSettings( // Assuming findByUsername
|
|
||||||
// method exists
|
|
||||||
username);
|
|
||||||
if (!user.isPresent()) {
|
if (!user.isPresent()) {
|
||||||
return "redirect:/error";
|
return "redirect:/error";
|
||||||
}
|
}
|
||||||
@ -386,31 +360,20 @@ public class AccountWebController {
|
|||||||
log.error("exception", e);
|
log.error("exception", e);
|
||||||
return "redirect:/error";
|
return "redirect:/error";
|
||||||
}
|
}
|
||||||
|
|
||||||
String messageType = request.getParameter("messageType");
|
String messageType = request.getParameter("messageType");
|
||||||
if (messageType != null) {
|
if (messageType != null) {
|
||||||
switch (messageType) {
|
switch (messageType) {
|
||||||
case "notAuthenticated":
|
case "notAuthenticated" -> messageType = "notAuthenticatedMessage";
|
||||||
messageType = "notAuthenticatedMessage";
|
case "userNotFound" -> messageType = "userNotFoundMessage";
|
||||||
break;
|
case "incorrectPassword" -> messageType = "incorrectPasswordMessage";
|
||||||
case "userNotFound":
|
case "usernameExists" -> messageType = "usernameExistsMessage";
|
||||||
messageType = "userNotFoundMessage";
|
case "invalidUsername" -> messageType = "invalidUsernameMessage";
|
||||||
break;
|
|
||||||
case "incorrectPassword":
|
|
||||||
messageType = "incorrectPasswordMessage";
|
|
||||||
break;
|
|
||||||
case "usernameExists":
|
|
||||||
messageType = "usernameExistsMessage";
|
|
||||||
break;
|
|
||||||
case "invalidUsername":
|
|
||||||
messageType = "invalidUsernameMessage";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
model.addAttribute("messageType", messageType);
|
|
||||||
}
|
}
|
||||||
// Add attributes to the model
|
// Add attributes to the model
|
||||||
model.addAttribute("username", username);
|
model.addAttribute("username", username);
|
||||||
|
model.addAttribute("messageType", messageType);
|
||||||
model.addAttribute("role", user.get().getRolesAsString());
|
model.addAttribute("role", user.get().getRolesAsString());
|
||||||
model.addAttribute("settings", settingsJson);
|
model.addAttribute("settings", settingsJson);
|
||||||
model.addAttribute("changeCredsFlag", user.get().isFirstLogin());
|
model.addAttribute("changeCredsFlag", user.get().isFirstLogin());
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package stirling.software.SPDF.model;
|
package stirling.software.SPDF.model;
|
||||||
|
|
||||||
|
import static stirling.software.SPDF.utils.validation.Validator.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -35,7 +37,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.SPDF.config.InstallationPathConfig;
|
import stirling.software.SPDF.config.InstallationPathConfig;
|
||||||
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
import stirling.software.SPDF.config.YamlPropertySourceFactory;
|
||||||
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
import stirling.software.SPDF.model.exception.UnsupportedProviderException;
|
||||||
import stirling.software.SPDF.model.provider.GithubProvider;
|
import stirling.software.SPDF.model.provider.GitHubProvider;
|
||||||
import stirling.software.SPDF.model.provider.GoogleProvider;
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||||
import stirling.software.SPDF.model.provider.Provider;
|
import stirling.software.SPDF.model.provider.Provider;
|
||||||
@ -244,17 +246,17 @@ public class ApplicationProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSettingsValid() {
|
public boolean isSettingsValid() {
|
||||||
return isValid(this.getIssuer(), "issuer")
|
return !isStringEmpty(this.getIssuer())
|
||||||
&& isValid(this.getClientId(), "clientId")
|
&& !isStringEmpty(this.getClientId())
|
||||||
&& isValid(this.getClientSecret(), "clientSecret")
|
&& !isStringEmpty(this.getClientSecret())
|
||||||
&& isValid(this.getScopes(), "scopes")
|
&& !isCollectionEmpty(this.getScopes())
|
||||||
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
&& !isStringEmpty(this.getUseAsUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class Client {
|
public static class Client {
|
||||||
private GoogleProvider google = new GoogleProvider();
|
private GoogleProvider google = new GoogleProvider();
|
||||||
private GithubProvider github = new GithubProvider();
|
private GitHubProvider github = new GitHubProvider();
|
||||||
private KeycloakProvider keycloak = new KeycloakProvider();
|
private KeycloakProvider keycloak = new KeycloakProvider();
|
||||||
|
|
||||||
public Provider get(String registrationId) throws UnsupportedProviderException {
|
public Provider get(String registrationId) throws UnsupportedProviderException {
|
||||||
@ -262,8 +264,10 @@ public class ApplicationProperties {
|
|||||||
case "google" -> getGoogle();
|
case "google" -> getGoogle();
|
||||||
case "github" -> getGithub();
|
case "github" -> getGithub();
|
||||||
case "keycloak" -> getKeycloak();
|
case "keycloak" -> getKeycloak();
|
||||||
default -> throw new UnsupportedProviderException(
|
default ->
|
||||||
"Logout from the provider is not supported. Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
throw new UnsupportedProviderException(
|
||||||
|
"Logout from the provider " + registrationId + " is not supported. "
|
||||||
|
+ "Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package stirling.software.SPDF.model.exception;
|
||||||
|
|
||||||
|
public class NoProviderFoundException extends Exception {
|
||||||
|
public NoProviderFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NoProviderFoundException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,8 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
// @Setter
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class GithubProvider extends Provider {
|
public class GitHubProvider extends Provider {
|
||||||
|
|
||||||
private static final String NAME = "github";
|
private static final String NAME = "github";
|
||||||
private static final String CLIENT_NAME = "GitHub";
|
private static final String CLIENT_NAME = "GitHub";
|
||||||
@ -15,51 +14,68 @@ public class GithubProvider extends Provider {
|
|||||||
private static final String TOKEN_URI = "https://github.com/login/oauth/access_token";
|
private static final String TOKEN_URI = "https://github.com/login/oauth/access_token";
|
||||||
private static final String USER_INFO_URI = "https://api.github.com/user";
|
private static final String USER_INFO_URI = "https://api.github.com/user";
|
||||||
|
|
||||||
private String clientId;
|
public GitHubProvider(
|
||||||
private String clientSecret;
|
|
||||||
private Collection<String> scopes = new ArrayList<>();
|
|
||||||
private String useAsUsername = "login";
|
|
||||||
|
|
||||||
public GithubProvider(
|
|
||||||
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
||||||
super(null, NAME, CLIENT_NAME, clientId, clientSecret, scopes, useAsUsername);
|
super(
|
||||||
this.clientId = clientId;
|
null,
|
||||||
this.clientSecret = clientSecret;
|
NAME,
|
||||||
this.scopes = scopes;
|
CLIENT_NAME,
|
||||||
this.useAsUsername = useAsUsername;
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
scopes,
|
||||||
|
useAsUsername != null ? useAsUsername : "login",
|
||||||
|
AUTHORIZATION_URI,
|
||||||
|
TOKEN_URI,
|
||||||
|
USER_INFO_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getAuthorizationUri() {
|
public String getAuthorizationUri() {
|
||||||
return AUTHORIZATION_URI;
|
return AUTHORIZATION_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getTokenUri() {
|
public String getTokenUri() {
|
||||||
return TOKEN_URI;
|
return TOKEN_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserinfoUri() {
|
@Override
|
||||||
|
public String getUserInfoUri() {
|
||||||
return USER_INFO_URI;
|
return USER_INFO_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClientName() {
|
||||||
|
return CLIENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getScopes() {
|
public Collection<String> getScopes() {
|
||||||
|
Collection<String> scopes = super.getScopes();
|
||||||
|
|
||||||
if (scopes == null || scopes.isEmpty()) {
|
if (scopes == null || scopes.isEmpty()) {
|
||||||
scopes = new ArrayList<>();
|
scopes = new ArrayList<>();
|
||||||
scopes.add("read:user");
|
scopes.add("read:user");
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes;
|
return scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GitHub [clientId="
|
return "GitHub [clientId="
|
||||||
+ clientId
|
+ getClientId()
|
||||||
+ ", clientSecret="
|
+ ", clientSecret="
|
||||||
+ (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
|
+ (getClientSecret() != null && !getClientSecret().isEmpty() ? "*****" : "NULL")
|
||||||
+ ", scopes="
|
+ ", scopes="
|
||||||
+ scopes
|
+ getScopes()
|
||||||
+ ", useAsUsername="
|
+ ", useAsUsername="
|
||||||
+ useAsUsername
|
+ getUseAsUsername()
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,6 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
// @Setter
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class GoogleProvider extends Provider {
|
public class GoogleProvider extends Provider {
|
||||||
|
|
||||||
@ -16,18 +15,19 @@ public class GoogleProvider extends Provider {
|
|||||||
private static final String USER_INFO_URI =
|
private static final String USER_INFO_URI =
|
||||||
"https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
|
"https://www.googleapis.com/oauth2/v3/userinfo?alt=json";
|
||||||
|
|
||||||
private String clientId;
|
|
||||||
private String clientSecret;
|
|
||||||
private Collection<String> scopes = new ArrayList<>();
|
|
||||||
private String useAsUsername = "email";
|
|
||||||
|
|
||||||
public GoogleProvider(
|
public GoogleProvider(
|
||||||
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
String clientId, String clientSecret, Collection<String> scopes, String useAsUsername) {
|
||||||
super(null, NAME, CLIENT_NAME, clientId, clientSecret, scopes, useAsUsername);
|
super(
|
||||||
this.clientId = clientId;
|
null,
|
||||||
this.clientSecret = clientSecret;
|
NAME,
|
||||||
this.scopes = scopes;
|
CLIENT_NAME,
|
||||||
this.useAsUsername = useAsUsername;
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
scopes,
|
||||||
|
useAsUsername,
|
||||||
|
AUTHORIZATION_URI,
|
||||||
|
TOKEN_URI,
|
||||||
|
USER_INFO_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthorizationUri() {
|
public String getAuthorizationUri() {
|
||||||
@ -42,26 +42,39 @@ public class GoogleProvider extends Provider {
|
|||||||
return USER_INFO_URI;
|
return USER_INFO_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClientName() {
|
||||||
|
return CLIENT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getScopes() {
|
public Collection<String> getScopes() {
|
||||||
|
Collection<String> scopes = super.getScopes();
|
||||||
|
|
||||||
if (scopes == null || scopes.isEmpty()) {
|
if (scopes == null || scopes.isEmpty()) {
|
||||||
scopes = new ArrayList<>();
|
scopes = new ArrayList<>();
|
||||||
scopes.add("https://www.googleapis.com/auth/userinfo.email");
|
scopes.add("https://www.googleapis.com/auth/userinfo.email");
|
||||||
scopes.add("https://www.googleapis.com/auth/userinfo.profile");
|
scopes.add("https://www.googleapis.com/auth/userinfo.profile");
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopes;
|
return scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Google [clientId="
|
return "Google [clientId="
|
||||||
+ clientId
|
+ getClientId()
|
||||||
+ ", clientSecret="
|
+ ", clientSecret="
|
||||||
+ (clientSecret != null && !clientSecret.isEmpty() ? "MASKED" : "NULL")
|
+ (getClientSecret() != null && !getClientSecret().isEmpty() ? "*****" : "NULL")
|
||||||
+ ", scopes="
|
+ ", scopes="
|
||||||
+ scopes
|
+ getScopes()
|
||||||
+ ", useAsUsername="
|
+ ", useAsUsername="
|
||||||
+ useAsUsername
|
+ getUseAsUsername()
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,36 +5,44 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
// @Setter
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class KeycloakProvider extends Provider {
|
public class KeycloakProvider extends Provider {
|
||||||
|
|
||||||
private static final String NAME = "keycloak";
|
private static final String NAME = "keycloak";
|
||||||
private static final String CLIENT_NAME = "Keycloak";
|
private static final String CLIENT_NAME = "Keycloak";
|
||||||
|
|
||||||
private String issuer;
|
|
||||||
private String clientId;
|
|
||||||
private String clientSecret;
|
|
||||||
private Collection<String> scopes;
|
|
||||||
private String useAsUsername = "email";
|
|
||||||
|
|
||||||
public KeycloakProvider(
|
public KeycloakProvider(
|
||||||
String issuer,
|
String issuer,
|
||||||
String clientId,
|
String clientId,
|
||||||
String clientSecret,
|
String clientSecret,
|
||||||
Collection<String> scopes,
|
Collection<String> scopes,
|
||||||
String useAsUsername) {
|
String useAsUsername) {
|
||||||
super(issuer, NAME, CLIENT_NAME, clientId, clientSecret, scopes, useAsUsername);
|
super(
|
||||||
this.useAsUsername = useAsUsername;
|
issuer,
|
||||||
this.issuer = issuer;
|
NAME,
|
||||||
this.clientId = clientId;
|
CLIENT_NAME,
|
||||||
this.clientSecret = clientSecret;
|
clientId,
|
||||||
this.scopes = scopes;
|
clientSecret,
|
||||||
|
scopes,
|
||||||
|
useAsUsername,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClientName() {
|
||||||
|
return CLIENT_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getScopes() {
|
public Collection<String> getScopes() {
|
||||||
var scopes = super.getScopes();
|
Collection<String> scopes = super.getScopes();
|
||||||
|
|
||||||
if (scopes == null || scopes.isEmpty()) {
|
if (scopes == null || scopes.isEmpty()) {
|
||||||
scopes = new ArrayList<>();
|
scopes = new ArrayList<>();
|
||||||
@ -48,15 +56,15 @@ public class KeycloakProvider extends Provider {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Keycloak [issuer="
|
return "Keycloak [issuer="
|
||||||
+ issuer
|
+ getIssuer()
|
||||||
+ ", clientId="
|
+ ", clientId="
|
||||||
+ clientId
|
+ getClientId()
|
||||||
+ ", clientSecret="
|
+ ", clientSecret="
|
||||||
+ (clientSecret != null && !clientSecret.isBlank() ? "MASKED" : "NULL")
|
+ (getClientSecret() != null && !getClientSecret().isBlank() ? "*****" : "NULL")
|
||||||
+ ", scopes="
|
+ ", scopes="
|
||||||
+ scopes
|
+ getScopes()
|
||||||
+ ", useAsUsername="
|
+ ", useAsUsername="
|
||||||
+ useAsUsername
|
+ getUseAsUsername()
|
||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
package stirling.software.SPDF.model.provider;
|
package stirling.software.SPDF.model.provider;
|
||||||
|
|
||||||
|
import static stirling.software.SPDF.utils.validation.Validator.isStringEmpty;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Getter
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public abstract class Provider {
|
public class Provider {
|
||||||
|
|
||||||
private String issuer;
|
private String issuer;
|
||||||
private String name;
|
private String name;
|
||||||
@ -18,6 +21,9 @@ public abstract class Provider {
|
|||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
private Collection<String> scopes;
|
private Collection<String> scopes;
|
||||||
private String useAsUsername;
|
private String useAsUsername;
|
||||||
|
private String authorizationUri;
|
||||||
|
private String tokenUri;
|
||||||
|
private String userInfoUri;
|
||||||
|
|
||||||
public Provider(
|
public Provider(
|
||||||
String issuer,
|
String issuer,
|
||||||
@ -26,59 +32,43 @@ public abstract class Provider {
|
|||||||
String clientId,
|
String clientId,
|
||||||
String clientSecret,
|
String clientSecret,
|
||||||
Collection<String> scopes,
|
Collection<String> scopes,
|
||||||
String useAsUsername) {
|
String useAsUsername,
|
||||||
|
String authorizationUri,
|
||||||
|
String tokenUri,
|
||||||
|
String userInfoUri) {
|
||||||
this.issuer = issuer;
|
this.issuer = issuer;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.clientName = clientName;
|
this.clientName = clientName;
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
this.scopes = scopes;
|
this.scopes = scopes == null ? new ArrayList<>() : scopes;
|
||||||
this.useAsUsername = !useAsUsername.isBlank() ? useAsUsername : "email";
|
this.useAsUsername = isStringEmpty(useAsUsername) ? "email" : useAsUsername;
|
||||||
}
|
this.authorizationUri = authorizationUri;
|
||||||
|
this.tokenUri = tokenUri;
|
||||||
// todo: why are we passing name here if it's not used?
|
this.userInfoUri = userInfoUri;
|
||||||
public boolean isSettingsValid() {
|
|
||||||
return isValid(this.getIssuer(), "issuer")
|
|
||||||
&& isValid(this.getClientId(), "clientId")
|
|
||||||
&& isValid(this.getClientSecret(), "clientSecret")
|
|
||||||
&& isValid(this.getScopes(), "scopes")
|
|
||||||
&& isValid(this.getUseAsUsername(), "useAsUsername");
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValid(String value, String name) {
|
|
||||||
return value != null && !value.isBlank();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValid(Collection<String> value, String name) {
|
|
||||||
return value != null && !value.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIssuer(String issuer) {
|
|
||||||
this.issuer = issuer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientName(String clientName) {
|
|
||||||
this.clientName = clientName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientId(String clientId) {
|
|
||||||
this.clientId = clientId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientSecret(String clientSecret) {
|
|
||||||
this.clientSecret = clientSecret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setScopes(String scopes) {
|
public void setScopes(String scopes) {
|
||||||
|
if (scopes != null && !scopes.isBlank()) {
|
||||||
this.scopes =
|
this.scopes =
|
||||||
Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList());
|
Arrays.stream(scopes.split(",")).map(String::trim).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setUseAsUsername(String useAsUsername) {
|
@Override
|
||||||
this.useAsUsername = useAsUsername;
|
public String toString() {
|
||||||
|
return "Provider [name="
|
||||||
|
+ getName()
|
||||||
|
+ ", clientName="
|
||||||
|
+ getClientName()
|
||||||
|
+ ", clientId="
|
||||||
|
+ getClientId()
|
||||||
|
+ ", clientSecret="
|
||||||
|
+ (getClientSecret() != null && !getClientSecret().isEmpty() ? "*****" : "NULL")
|
||||||
|
+ ", scopes="
|
||||||
|
+ getScopes()
|
||||||
|
+ ", useAsUsername="
|
||||||
|
+ getUseAsUsername()
|
||||||
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
public class UrlUtils {
|
public class UrlUtils {
|
||||||
|
|
||||||
private UrlUtils() {}
|
|
||||||
|
|
||||||
public static String getOrigin(HttpServletRequest request) {
|
public static String getOrigin(HttpServletRequest request) {
|
||||||
String scheme = request.getScheme(); // http or https
|
String scheme = request.getScheme(); // http or https
|
||||||
String serverName = request.getServerName(); // localhost
|
String serverName = request.getServerName(); // localhost
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package stirling.software.SPDF.utils.validation;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import stirling.software.SPDF.model.provider.Provider;
|
||||||
|
|
||||||
|
public class Validator {
|
||||||
|
|
||||||
|
public static boolean validateProvider(Provider provider) {
|
||||||
|
if (provider == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStringEmpty(provider.getClientId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStringEmpty(provider.getClientSecret())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCollectionEmpty(provider.getScopes())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStringEmpty(provider.getUseAsUsername())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isStringEmpty(String input) {
|
||||||
|
return input == null || input.isBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCollectionEmpty(Collection<String> input) {
|
||||||
|
return input == null || input.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
@ -572,8 +572,8 @@ login.invalid=اسم المستخدم أو كلمة المرور غير صالح
|
|||||||
login.locked=تم قفل حسابك.
|
login.locked=تم قفل حسابك.
|
||||||
login.signinTitle=الرجاء تسجيل الدخول
|
login.signinTitle=الرجاء تسجيل الدخول
|
||||||
login.ssoSignIn=تسجيل الدخول عبر تسجيل الدخول الأحادي
|
login.ssoSignIn=تسجيل الدخول عبر تسجيل الدخول الأحادي
|
||||||
login.oauth2AutoCreateDisabled=تم تعطيل الإنشاء التلقائي لمستخدم OAuth2
|
login.oAuth2AutoCreateDisabled=تم تعطيل الإنشاء التلقائي لمستخدم OAuth2
|
||||||
login.oauth2AdminBlockedUser=تم حظر تسجيل أو تسجيل دخول المستخدمين غير المسجلين حاليًا. يرجى الاتصال بالمسؤول.
|
login.oAuth2AdminBlockedUser=تم حظر تسجيل أو تسجيل دخول المستخدمين غير المسجلين حاليًا. يرجى الاتصال بالمسؤول.
|
||||||
login.oauth2RequestNotFound=لم يتم العثور على طلب التفويض
|
login.oauth2RequestNotFound=لم يتم العثور على طلب التفويض
|
||||||
login.oauth2InvalidUserInfoResponse=استجابة معلومات المستخدم غير صالحة
|
login.oauth2InvalidUserInfoResponse=استجابة معلومات المستخدم غير صالحة
|
||||||
login.oauth2invalidRequest=طلب غير صالح
|
login.oauth2invalidRequest=طلب غير صالح
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Etibarsız istifadəçi adı və ya şifr.
|
|||||||
login.locked=Sizin hesabınız kilidlənmişdir.
|
login.locked=Sizin hesabınız kilidlənmişdir.
|
||||||
login.signinTitle=Zəhmət olmasa, daxil olun
|
login.signinTitle=Zəhmət olmasa, daxil olun
|
||||||
login.ssoSignIn=Single Sign-on vasitəsilə daxil olun
|
login.ssoSignIn=Single Sign-on vasitəsilə daxil olun
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create İstifadəçisi Deaktivləşdirilmişdir
|
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-Create İstifadəçisi Deaktivləşdirilmişdir
|
||||||
login.oauth2AdminBlockedUser=Qeydiyyatdan keçməmiş istifadəçilərin qeydiyyatı və daxil olması hal-hazırda bloklanmışdır. Zəhmət olmasa, administratorla əlaqə saxlayın.
|
login.oAuth2AdminBlockedUser=Qeydiyyatdan keçməmiş istifadəçilərin qeydiyyatı və daxil olması hal-hazırda bloklanmışdır. Zəhmət olmasa, administratorla əlaqə saxlayın.
|
||||||
login.oauth2RequestNotFound=Təsdiqlənmə sorğusu tapılmadı
|
login.oauth2RequestNotFound=Təsdiqlənmə sorğusu tapılmadı
|
||||||
login.oauth2InvalidUserInfoResponse=Yanlış İstifadəçi Məlumatı Cavabı
|
login.oauth2InvalidUserInfoResponse=Yanlış İstifadəçi Məlumatı Cavabı
|
||||||
login.oauth2invalidRequest=Etibarsız Sorğu
|
login.oauth2invalidRequest=Etibarsız Sorğu
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Невалидно потребителско име или пар
|
|||||||
login.locked=Вашият акаунт е заключен.
|
login.locked=Вашият акаунт е заключен.
|
||||||
login.signinTitle=Моля впишете се
|
login.signinTitle=Моля впишете се
|
||||||
login.ssoSignIn=Влизане чрез еднократно влизане
|
login.ssoSignIn=Влизане чрез еднократно влизане
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано
|
login.oAuth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано
|
||||||
login.oauth2AdminBlockedUser=Регистрацията или влизането на нерегистрирани потребители в момента е блокирано. Моля, свържете се с администратора.
|
login.oAuth2AdminBlockedUser=Регистрацията или влизането на нерегистрирани потребители в момента е блокирано. Моля, свържете се с администратора.
|
||||||
login.oauth2RequestNotFound=Заявката за оторизация не е намерена
|
login.oauth2RequestNotFound=Заявката за оторизация не е намерена
|
||||||
login.oauth2InvalidUserInfoResponse=Невалидна информация за потребителя
|
login.oauth2InvalidUserInfoResponse=Невалидна информация за потребителя
|
||||||
login.oauth2invalidRequest=Невалидна заявка
|
login.oauth2invalidRequest=Невалидна заявка
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nom d'usuari/contrasenya no vàlid
|
|||||||
login.locked=Compte bloquejat
|
login.locked=Compte bloquejat
|
||||||
login.signinTitle=Autenticat
|
login.signinTitle=Autenticat
|
||||||
login.ssoSignIn=Inicia sessió mitjançant inici de sessió únic
|
login.ssoSignIn=Inicia sessió mitjançant inici de sessió únic
|
||||||
login.oauth2AutoCreateDisabled=La creació automàtica d'usuaris OAUTH2 està desactivada
|
login.oAuth2AutoCreateDisabled=La creació automàtica d'usuaris OAUTH2 està desactivada
|
||||||
login.oauth2AdminBlockedUser=El registre o inici de sessió d'usuaris no registrats està actualment bloquejat. Si us plau, contacta amb l'administrador.
|
login.oAuth2AdminBlockedUser=El registre o inici de sessió d'usuaris no registrats està actualment bloquejat. Si us plau, contacta amb l'administrador.
|
||||||
login.oauth2RequestNotFound=Sol·licitud d'autorització no trobada
|
login.oauth2RequestNotFound=Sol·licitud d'autorització no trobada
|
||||||
login.oauth2InvalidUserInfoResponse=Resposta d'informació d'usuari no vàlida
|
login.oauth2InvalidUserInfoResponse=Resposta d'informació d'usuari no vàlida
|
||||||
login.oauth2invalidRequest=Sol·licitud no vàlida
|
login.oauth2invalidRequest=Sol·licitud no vàlida
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Neplatné uživatelské jméno nebo heslo.
|
|||||||
login.locked=Váš účet byl uzamčen.
|
login.locked=Váš účet byl uzamčen.
|
||||||
login.signinTitle=Prosím přihlaste se
|
login.signinTitle=Prosím přihlaste se
|
||||||
login.ssoSignIn=Přihlásit se přes Single Sign-on
|
login.ssoSignIn=Přihlásit se přes Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=Automatické vytváření OAUTH2 uživatelů je zakázáno
|
login.oAuth2AutoCreateDisabled=Automatické vytváření OAUTH2 uživatelů je zakázáno
|
||||||
login.oauth2AdminBlockedUser=Registrace nebo přihlášení neregistrovaných uživatelů je momentálně blokováno. Kontaktujte prosím správce.
|
login.oAuth2AdminBlockedUser=Registrace nebo přihlášení neregistrovaných uživatelů je momentálně blokováno. Kontaktujte prosím správce.
|
||||||
login.oauth2RequestNotFound=Požadavek na autorizaci nebyl nalezen
|
login.oauth2RequestNotFound=Požadavek na autorizaci nebyl nalezen
|
||||||
login.oauth2InvalidUserInfoResponse=Neplatná odpověď s informacemi o uživateli
|
login.oauth2InvalidUserInfoResponse=Neplatná odpověď s informacemi o uživateli
|
||||||
login.oauth2invalidRequest=Neplatný požadavek
|
login.oauth2invalidRequest=Neplatný požadavek
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Ugyldigt brugernavn eller adgangskode.
|
|||||||
login.locked=Din konto er blevet låst.
|
login.locked=Din konto er blevet låst.
|
||||||
login.signinTitle=Log venligst ind
|
login.signinTitle=Log venligst ind
|
||||||
login.ssoSignIn=Log ind via Single Sign-on
|
login.ssoSignIn=Log ind via Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Auto-Opret Bruger Deaktiveret
|
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-Opret Bruger Deaktiveret
|
||||||
login.oauth2AdminBlockedUser=Registrering eller login af ikke-registrerede brugere er i øjeblikket blokeret. Kontakt venligst administratoren.
|
login.oAuth2AdminBlockedUser=Registrering eller login af ikke-registrerede brugere er i øjeblikket blokeret. Kontakt venligst administratoren.
|
||||||
login.oauth2RequestNotFound=Autorisationsanmodning ikke fundet
|
login.oauth2RequestNotFound=Autorisationsanmodning ikke fundet
|
||||||
login.oauth2InvalidUserInfoResponse=Ugyldigt Brugerinfo Svar
|
login.oauth2InvalidUserInfoResponse=Ugyldigt Brugerinfo Svar
|
||||||
login.oauth2invalidRequest=Ugyldig Anmodning
|
login.oauth2invalidRequest=Ugyldig Anmodning
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Benutzername oder Passwort ungültig.
|
|||||||
login.locked=Ihr Konto wurde gesperrt.
|
login.locked=Ihr Konto wurde gesperrt.
|
||||||
login.signinTitle=Bitte melden Sie sich an.
|
login.signinTitle=Bitte melden Sie sich an.
|
||||||
login.ssoSignIn=Anmeldung per Single Sign-On
|
login.ssoSignIn=Anmeldung per Single Sign-On
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Benutzer automatisch erstellen deaktiviert
|
login.oAuth2AutoCreateDisabled=OAUTH2 Benutzer automatisch erstellen deaktiviert
|
||||||
login.oauth2AdminBlockedUser=Die Registrierung bzw. das anmelden von nicht registrierten Benutzern ist derzeit gesperrt. Bitte wenden Sie sich an den Administrator.
|
login.oAuth2AdminBlockedUser=Die Registrierung bzw. das anmelden von nicht registrierten Benutzern ist derzeit gesperrt. Bitte wenden Sie sich an den Administrator.
|
||||||
login.oauth2RequestNotFound=Autorisierungsanfrage nicht gefunden
|
login.oauth2RequestNotFound=Autorisierungsanfrage nicht gefunden
|
||||||
login.oauth2InvalidUserInfoResponse=Ungültige Benutzerinformationsantwort
|
login.oauth2InvalidUserInfoResponse=Ungültige Benutzerinformationsantwort
|
||||||
login.oauth2invalidRequest=ungültige Anfrage
|
login.oauth2invalidRequest=ungültige Anfrage
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Μη έγκυρο όνομα χρήστη ή κωδικός.
|
|||||||
login.locked=Ο λογαριασμός σας έχει κλειδωθεί.
|
login.locked=Ο λογαριασμός σας έχει κλειδωθεί.
|
||||||
login.signinTitle=Παρακαλώ συνδεθείτε
|
login.signinTitle=Παρακαλώ συνδεθείτε
|
||||||
login.ssoSignIn=Σύνδεση μέσω Single Sign-on
|
login.ssoSignIn=Σύνδεση μέσω Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=Η αυτόματη δημιουργία χρήστη OAUTH2 είναι απενεργοποιημένη
|
login.oAuth2AutoCreateDisabled=Η αυτόματη δημιουργία χρήστη OAUTH2 είναι απενεργοποιημένη
|
||||||
login.oauth2AdminBlockedUser=Η εγγραφή ή σύνδεση μη εγγεγραμμένων χρηστών είναι προς το παρόν αποκλεισμένη. Παρακαλώ επικοινωνήστε με τον διαχειριστή.
|
login.oAuth2AdminBlockedUser=Η εγγραφή ή σύνδεση μη εγγεγραμμένων χρηστών είναι προς το παρόν αποκλεισμένη. Παρακαλώ επικοινωνήστε με τον διαχειριστή.
|
||||||
login.oauth2RequestNotFound=Το αίτημα εξουσιοδότησης δεν βρέθηκε
|
login.oauth2RequestNotFound=Το αίτημα εξουσιοδότησης δεν βρέθηκε
|
||||||
login.oauth2InvalidUserInfoResponse=Μη έγκυρη απόκριση πληροφοριών χρήστη
|
login.oauth2InvalidUserInfoResponse=Μη έγκυρη απόκριση πληροφοριών χρήστη
|
||||||
login.oauth2invalidRequest=Μη έγκυρο αίτημα
|
login.oauth2invalidRequest=Μη έγκυρο αίτημα
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Invalid username or password.
|
|||||||
login.locked=Your account has been locked.
|
login.locked=Your account has been locked.
|
||||||
login.signinTitle=Please sign in
|
login.signinTitle=Please sign in
|
||||||
login.ssoSignIn=Login via Single Sign-on
|
login.ssoSignIn=Login via Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled
|
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Authorization request not found
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Invalid Request
|
login.oauth2invalidRequest=Invalid Request
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Invalid username or password.
|
|||||||
login.locked=Your account has been locked.
|
login.locked=Your account has been locked.
|
||||||
login.signinTitle=Please sign in
|
login.signinTitle=Please sign in
|
||||||
login.ssoSignIn=Login via Single Sign-on
|
login.ssoSignIn=Login via Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled
|
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Authorization request not found
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Invalid Request
|
login.oauth2invalidRequest=Invalid Request
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nombre de usuario o contraseña erróneos.
|
|||||||
login.locked=Su cuenta se ha bloqueado.
|
login.locked=Su cuenta se ha bloqueado.
|
||||||
login.signinTitle=Por favor, inicie sesión
|
login.signinTitle=Por favor, inicie sesión
|
||||||
login.ssoSignIn=Iniciar sesión a través del inicio de sesión único
|
login.ssoSignIn=Iniciar sesión a través del inicio de sesión único
|
||||||
login.oauth2AutoCreateDisabled=Usuario de creación automática de OAUTH2 DESACTIVADO
|
login.oAuth2AutoCreateDisabled=Usuario de creación automática de OAUTH2 DESACTIVADO
|
||||||
login.oauth2AdminBlockedUser=El registro o inicio de sesión de usuarios no registrados está actualmente bloqueado. Por favor, contáctese con el administrador.
|
login.oAuth2AdminBlockedUser=El registro o inicio de sesión de usuarios no registrados está actualmente bloqueado. Por favor, contáctese con el administrador.
|
||||||
login.oauth2RequestNotFound=Solicitud de autorización no encontrada
|
login.oauth2RequestNotFound=Solicitud de autorización no encontrada
|
||||||
login.oauth2InvalidUserInfoResponse=Respuesta de información de usuario no válida
|
login.oauth2InvalidUserInfoResponse=Respuesta de información de usuario no válida
|
||||||
login.oauth2invalidRequest=Solicitud no válida
|
login.oauth2invalidRequest=Solicitud no válida
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Okerreko erabiltzaile izena edo pasahitza.
|
|||||||
login.locked=Zure kontua blokeatu egin da.
|
login.locked=Zure kontua blokeatu egin da.
|
||||||
login.signinTitle=Mesedez, hasi saioa
|
login.signinTitle=Mesedez, hasi saioa
|
||||||
login.ssoSignIn=Hasi saioa Saioa hasteko modu bakarraren bidez
|
login.ssoSignIn=Hasi saioa Saioa hasteko modu bakarraren bidez
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Sortu automatikoki erabiltzailea desgaituta dago
|
login.oAuth2AutoCreateDisabled=OAUTH2 Sortu automatikoki erabiltzailea desgaituta dago
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Authorization request not found
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Invalid Request
|
login.oauth2invalidRequest=Invalid Request
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=نام کاربری یا رمز عبور اشتباه است.
|
|||||||
login.locked=حساب شما قفل شده است.
|
login.locked=حساب شما قفل شده است.
|
||||||
login.signinTitle=لطفاً وارد شوید
|
login.signinTitle=لطفاً وارد شوید
|
||||||
login.ssoSignIn=ورود از طریق Single Sign-on
|
login.ssoSignIn=ورود از طریق Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=ایجاد خودکار کاربر با OAUTH2 غیرفعال است
|
login.oAuth2AutoCreateDisabled=ایجاد خودکار کاربر با OAUTH2 غیرفعال است
|
||||||
login.oauth2AdminBlockedUser=ثبتنام یا ورود کاربران ثبتنشده در حال حاضر مسدود است. لطفاً با مدیر تماس بگیرید.
|
login.oAuth2AdminBlockedUser=ثبتنام یا ورود کاربران ثبتنشده در حال حاضر مسدود است. لطفاً با مدیر تماس بگیرید.
|
||||||
login.oauth2RequestNotFound=درخواست احراز هویت پیدا نشد
|
login.oauth2RequestNotFound=درخواست احراز هویت پیدا نشد
|
||||||
login.oauth2InvalidUserInfoResponse=پاسخ اطلاعات کاربری نامعتبر است
|
login.oauth2InvalidUserInfoResponse=پاسخ اطلاعات کاربری نامعتبر است
|
||||||
login.oauth2invalidRequest=درخواست نامعتبر
|
login.oauth2invalidRequest=درخواست نامعتبر
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nom d'utilisateur ou mot de passe invalide.
|
|||||||
login.locked=Votre compte a été verrouillé.
|
login.locked=Votre compte a été verrouillé.
|
||||||
login.signinTitle=Veuillez vous connecter
|
login.signinTitle=Veuillez vous connecter
|
||||||
login.ssoSignIn=Se connecter via l'authentification unique
|
login.ssoSignIn=Se connecter via l'authentification unique
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Création automatique d'utilisateur désactivée
|
login.oAuth2AutoCreateDisabled=OAUTH2 Création automatique d'utilisateur désactivée
|
||||||
login.oauth2AdminBlockedUser=La création ou l'authentification d'utilisateurs non enregistrés est actuellement bloquée. Veuillez contacter l'administrateur.
|
login.oAuth2AdminBlockedUser=La création ou l'authentification d'utilisateurs non enregistrés est actuellement bloquée. Veuillez contacter l'administrateur.
|
||||||
login.oauth2RequestNotFound=Demande d'autorisation introuvable
|
login.oauth2RequestNotFound=Demande d'autorisation introuvable
|
||||||
login.oauth2InvalidUserInfoResponse=Réponse contenant les informations de l'utilisateur est invalide
|
login.oauth2InvalidUserInfoResponse=Réponse contenant les informations de l'utilisateur est invalide
|
||||||
login.oauth2invalidRequest=Requête invalide
|
login.oauth2invalidRequest=Requête invalide
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=अमान्य उपयोगकर्ता नाम या
|
|||||||
login.locked=आपका खाता लॉक कर दिया गया है।
|
login.locked=आपका खाता लॉक कर दिया गया है।
|
||||||
login.signinTitle=कृपया साइन इन करें
|
login.signinTitle=कृपया साइन इन करें
|
||||||
login.ssoSignIn=सिंगल साइन-ऑन के माध्यम से लॉगिन करें
|
login.ssoSignIn=सिंगल साइन-ऑन के माध्यम से लॉगिन करें
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 स्वतः उपयोगकर्ता निर्माण अक्षम है
|
login.oAuth2AutoCreateDisabled=OAUTH2 स्वतः उपयोगकर्ता निर्माण अक्षम है
|
||||||
login.oauth2AdminBlockedUser=गैर-पंजीकृत उपयोगकर्ताओं का पंजीकरण या लॉगिन वर्तमान में अवरुद्ध है। कृपया व्यवस्थापक से संपर्क करें।
|
login.oAuth2AdminBlockedUser=गैर-पंजीकृत उपयोगकर्ताओं का पंजीकरण या लॉगिन वर्तमान में अवरुद्ध है। कृपया व्यवस्थापक से संपर्क करें।
|
||||||
login.oauth2RequestNotFound=प्राधिकरण अनुरोध नहीं मिला
|
login.oauth2RequestNotFound=प्राधिकरण अनुरोध नहीं मिला
|
||||||
login.oauth2InvalidUserInfoResponse=अमान्य उपयोगकर्ता जानकारी प्रतिक्रिया
|
login.oauth2InvalidUserInfoResponse=अमान्य उपयोगकर्ता जानकारी प्रतिक्रिया
|
||||||
login.oauth2invalidRequest=अमान्य अनुरोध
|
login.oauth2invalidRequest=अमान्य अनुरोध
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Neispravno korisničko ime ili zaporka.
|
|||||||
login.locked=Vaš račun je zaključan.
|
login.locked=Vaš račun je zaključan.
|
||||||
login.signinTitle=Molimo vas da se prijavite
|
login.signinTitle=Molimo vas da se prijavite
|
||||||
login.ssoSignIn=Prijavite se putem jedinstvene prijave
|
login.ssoSignIn=Prijavite se putem jedinstvene prijave
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno
|
login.oAuth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno
|
||||||
login.oauth2AdminBlockedUser=Registracija ili prijava nekadreguiranih korisnika trenutno su blokirane. Molimo Vas da kontaktirate administratora.
|
login.oAuth2AdminBlockedUser=Registracija ili prijava nekadreguiranih korisnika trenutno su blokirane. Molimo Vas da kontaktirate administratora.
|
||||||
login.oauth2RequestNotFound=Zahtjev za autorizaciju nije pronađen
|
login.oauth2RequestNotFound=Zahtjev za autorizaciju nije pronađen
|
||||||
login.oauth2InvalidUserInfoResponse=Nevažeće informacije o korisniku
|
login.oauth2InvalidUserInfoResponse=Nevažeće informacije o korisniku
|
||||||
login.oauth2invalidRequest=Neispravan zahtjev
|
login.oauth2invalidRequest=Neispravan zahtjev
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Érvénytelen felhasználónév vagy jelszó.
|
|||||||
login.locked=A fiókja zárolva van.
|
login.locked=A fiókja zárolva van.
|
||||||
login.signinTitle=Kérjük, jelentkezzen be
|
login.signinTitle=Kérjük, jelentkezzen be
|
||||||
login.ssoSignIn=Bejelentkezés egyszeri bejelentkezéssel
|
login.ssoSignIn=Bejelentkezés egyszeri bejelentkezéssel
|
||||||
login.oauth2AutoCreateDisabled=OAuth2 automatikus felhasználólétrehozás letiltva
|
login.oAuth2AutoCreateDisabled=OAuth2 automatikus felhasználólétrehozás letiltva
|
||||||
login.oauth2AdminBlockedUser=A nem regisztrált felhasználók regisztrációja vagy bejelentkezése jelenleg le van tiltva. Kérjük, forduljon a rendszergazdához.
|
login.oAuth2AdminBlockedUser=A nem regisztrált felhasználók regisztrációja vagy bejelentkezése jelenleg le van tiltva. Kérjük, forduljon a rendszergazdához.
|
||||||
login.oauth2RequestNotFound=A hitelesítési kérés nem található
|
login.oauth2RequestNotFound=A hitelesítési kérés nem található
|
||||||
login.oauth2InvalidUserInfoResponse=Érvénytelen felhasználói információ válasz
|
login.oauth2InvalidUserInfoResponse=Érvénytelen felhasználói információ válasz
|
||||||
login.oauth2invalidRequest=Érvénytelen kérés
|
login.oauth2invalidRequest=Érvénytelen kérés
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nama pengguna atau kata sandi tidak valid.
|
|||||||
login.locked=Akun Anda telah dikunci.
|
login.locked=Akun Anda telah dikunci.
|
||||||
login.signinTitle=Silakan masuk
|
login.signinTitle=Silakan masuk
|
||||||
login.ssoSignIn=Masuk melalui Single Sign - on
|
login.ssoSignIn=Masuk melalui Single Sign - on
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Buat Otomatis Pengguna Dinonaktifkan
|
login.oAuth2AutoCreateDisabled=OAUTH2 Buat Otomatis Pengguna Dinonaktifkan
|
||||||
login.oauth2AdminBlockedUser=Registrasi atau login pengguna yang tidak terdaftar saat ini diblokir. Silakan hubungi administrator.
|
login.oAuth2AdminBlockedUser=Registrasi atau login pengguna yang tidak terdaftar saat ini diblokir. Silakan hubungi administrator.
|
||||||
login.oauth2RequestNotFound=Permintaan otorisasi tidak ditemukan
|
login.oauth2RequestNotFound=Permintaan otorisasi tidak ditemukan
|
||||||
login.oauth2InvalidUserInfoResponse=Respons Info Pengguna Tidak Valid
|
login.oauth2InvalidUserInfoResponse=Respons Info Pengguna Tidak Valid
|
||||||
login.oauth2invalidRequest=Permintaan Tidak Valid
|
login.oauth2invalidRequest=Permintaan Tidak Valid
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nome utente o password errati.
|
|||||||
login.locked=Il tuo account è stato bloccato.
|
login.locked=Il tuo account è stato bloccato.
|
||||||
login.signinTitle=Per favore accedi
|
login.signinTitle=Per favore accedi
|
||||||
login.ssoSignIn=Accedi tramite Single Sign-on
|
login.ssoSignIn=Accedi tramite Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=Creazione automatica utente OAUTH2 DISABILITATA
|
login.oAuth2AutoCreateDisabled=Creazione automatica utente OAUTH2 DISABILITATA
|
||||||
login.oauth2AdminBlockedUser=La registrazione o l'accesso degli utenti non registrati è attualmente bloccata. Si prega di contattare l'amministratore.
|
login.oAuth2AdminBlockedUser=La registrazione o l'accesso degli utenti non registrati è attualmente bloccata. Si prega di contattare l'amministratore.
|
||||||
login.oauth2RequestNotFound=Richiesta di autorizzazione non trovata
|
login.oauth2RequestNotFound=Richiesta di autorizzazione non trovata
|
||||||
login.oauth2InvalidUserInfoResponse=Risposta relativa alle informazioni utente non valida
|
login.oauth2InvalidUserInfoResponse=Risposta relativa alle informazioni utente non valida
|
||||||
login.oauth2invalidRequest=Richiesta non valida
|
login.oauth2invalidRequest=Richiesta non valida
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=ユーザー名かパスワードが無効です。
|
|||||||
login.locked=あなたのアカウントはロックされています。
|
login.locked=あなたのアカウントはロックされています。
|
||||||
login.signinTitle=サインインしてください
|
login.signinTitle=サインインしてください
|
||||||
login.ssoSignIn=シングルサインオンでログイン
|
login.ssoSignIn=シングルサインオンでログイン
|
||||||
login.oauth2AutoCreateDisabled=OAuth 2自動作成ユーザーが無効
|
login.oAuth2AutoCreateDisabled=OAuth 2自動作成ユーザーが無効
|
||||||
login.oauth2AdminBlockedUser=現在、未登録ユーザーの登録またはログインはブロックされています。管理者にお問い合わせください。
|
login.oAuth2AdminBlockedUser=現在、未登録ユーザーの登録またはログインはブロックされています。管理者にお問い合わせください。
|
||||||
login.oauth2RequestNotFound=認証リクエストが見つかりません
|
login.oauth2RequestNotFound=認証リクエストが見つかりません
|
||||||
login.oauth2InvalidUserInfoResponse=無効なユーザー情報の応答
|
login.oauth2InvalidUserInfoResponse=無効なユーザー情報の応答
|
||||||
login.oauth2invalidRequest=無効なリクエスト
|
login.oauth2invalidRequest=無効なリクエスト
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=사용자 이름 또는 비밀번호가 잘못되었습니다.
|
|||||||
login.locked=계정이 잠겼습니다.
|
login.locked=계정이 잠겼습니다.
|
||||||
login.signinTitle=로그인해 주세요
|
login.signinTitle=로그인해 주세요
|
||||||
login.ssoSignIn=단일 로그인으로 로그인
|
login.ssoSignIn=단일 로그인으로 로그인
|
||||||
login.oauth2AutoCreateDisabled=OAuth2 사용자 자동 생성이 비활성화되었습니다
|
login.oAuth2AutoCreateDisabled=OAuth2 사용자 자동 생성이 비활성화되었습니다
|
||||||
login.oauth2AdminBlockedUser=현재 미등록 사용자의 등록 또는 로그인이 차단되어 있습니다. 관리자에게 문의하세요.
|
login.oAuth2AdminBlockedUser=현재 미등록 사용자의 등록 또는 로그인이 차단되어 있습니다. 관리자에게 문의하세요.
|
||||||
login.oauth2RequestNotFound=인증 요청을 찾을 수 없습니다
|
login.oauth2RequestNotFound=인증 요청을 찾을 수 없습니다
|
||||||
login.oauth2InvalidUserInfoResponse=잘못된 사용자 정보 응답
|
login.oauth2InvalidUserInfoResponse=잘못된 사용자 정보 응답
|
||||||
login.oauth2invalidRequest=잘못된 요청
|
login.oauth2invalidRequest=잘못된 요청
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Ongeldige gebruikersnaam of wachtwoord.
|
|||||||
login.locked=Je account is geblokkeerd.
|
login.locked=Je account is geblokkeerd.
|
||||||
login.signinTitle=Gelieve in te loggen
|
login.signinTitle=Gelieve in te loggen
|
||||||
login.ssoSignIn=Inloggen via Single Sign-on
|
login.ssoSignIn=Inloggen via Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Automatisch aanmaken gebruiker uitgeschakeld
|
login.oAuth2AutoCreateDisabled=OAUTH2 Automatisch aanmaken gebruiker uitgeschakeld
|
||||||
login.oauth2AdminBlockedUser=Registratie of inloggen van niet-registreerde gebruikers is helaas momenteel geblokkeerd. Neem contact op met de beheerder.
|
login.oAuth2AdminBlockedUser=Registratie of inloggen van niet-registreerde gebruikers is helaas momenteel geblokkeerd. Neem contact op met de beheerder.
|
||||||
login.oauth2RequestNotFound=Autorisatieverzoek niet gevonden
|
login.oauth2RequestNotFound=Autorisatieverzoek niet gevonden
|
||||||
login.oauth2InvalidUserInfoResponse=Ongeldige reactie op gebruikersinfo
|
login.oauth2InvalidUserInfoResponse=Ongeldige reactie op gebruikersinfo
|
||||||
login.oauth2invalidRequest=Ongeldig verzoek
|
login.oauth2invalidRequest=Ongeldig verzoek
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Ugyldig brukernavn eller passord.
|
|||||||
login.locked=Kontoen din har blitt låst.
|
login.locked=Kontoen din har blitt låst.
|
||||||
login.signinTitle=Vennligst logg inn
|
login.signinTitle=Vennligst logg inn
|
||||||
login.ssoSignIn=Logg inn via Enkel Pålogging
|
login.ssoSignIn=Logg inn via Enkel Pålogging
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Auto-Opretting av bruker deaktivert
|
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-Opretting av bruker deaktivert
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Autentiseringsforespørsel ikke funnet
|
login.oauth2RequestNotFound=Autentiseringsforespørsel ikke funnet
|
||||||
login.oauth2InvalidUserInfoResponse=Ugyldig brukerinforespons
|
login.oauth2InvalidUserInfoResponse=Ugyldig brukerinforespons
|
||||||
login.oauth2invalidRequest=Ugyldig forespørsel
|
login.oauth2invalidRequest=Ugyldig forespørsel
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nieprawidłowe dane logowania
|
|||||||
login.locked=Konto jest zablokowane
|
login.locked=Konto jest zablokowane
|
||||||
login.signinTitle=Zaloguj się
|
login.signinTitle=Zaloguj się
|
||||||
login.ssoSignIn=Zaloguj się za pomocą logowania jednokrotnego
|
login.ssoSignIn=Zaloguj się za pomocą logowania jednokrotnego
|
||||||
login.oauth2AutoCreateDisabled=Wyłączono automatyczne tworzenie użytkownika OAUTH2
|
login.oAuth2AutoCreateDisabled=Wyłączono automatyczne tworzenie użytkownika OAUTH2
|
||||||
login.oauth2AdminBlockedUser=Rejestracja lub logowanie niezarejestrowanych użytkowników jest obecnie zablokowane. Prosimy o kontakt z administratorem.
|
login.oAuth2AdminBlockedUser=Rejestracja lub logowanie niezarejestrowanych użytkowników jest obecnie zablokowane. Prosimy o kontakt z administratorem.
|
||||||
login.oauth2RequestNotFound=Błąd logowania OAuth2
|
login.oauth2RequestNotFound=Błąd logowania OAuth2
|
||||||
login.oauth2InvalidUserInfoResponse=Niewłaściwe dane logowania
|
login.oauth2InvalidUserInfoResponse=Niewłaściwe dane logowania
|
||||||
login.oauth2invalidRequest=Nieprawidłowe żądanie
|
login.oauth2invalidRequest=Nieprawidłowe żądanie
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Usuário ou senha inválidos.
|
|||||||
login.locked=Sua conta foi bloqueada.
|
login.locked=Sua conta foi bloqueada.
|
||||||
login.signinTitle=Por favor, inicie a sessão
|
login.signinTitle=Por favor, inicie a sessão
|
||||||
login.ssoSignIn=Iniciar sessão através de login único (SSO)
|
login.ssoSignIn=Iniciar sessão através de login único (SSO)
|
||||||
login.oauth2AutoCreateDisabled=Auto-Criar Usuário OAUTH2 Desativado
|
login.oAuth2AutoCreateDisabled=Auto-Criar Usuário OAUTH2 Desativado
|
||||||
login.oauth2AdminBlockedUser=O registro ou login de usuários não registrados está atualmente bloqueado. Entre em contato com o administrador.
|
login.oAuth2AdminBlockedUser=O registro ou login de usuários não registrados está atualmente bloqueado. Entre em contato com o administrador.
|
||||||
login.oauth2RequestNotFound=Solicitação de autorização não encontrada
|
login.oauth2RequestNotFound=Solicitação de autorização não encontrada
|
||||||
login.oauth2InvalidUserInfoResponse=Resposta de informação de usuário inválida
|
login.oauth2InvalidUserInfoResponse=Resposta de informação de usuário inválida
|
||||||
login.oauth2invalidRequest=Requisição Inválida
|
login.oauth2invalidRequest=Requisição Inválida
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nome de utilizador ou palavra-passe inválidos.
|
|||||||
login.locked=A sua conta foi bloqueada.
|
login.locked=A sua conta foi bloqueada.
|
||||||
login.signinTitle=Por favor inicie sessão
|
login.signinTitle=Por favor inicie sessão
|
||||||
login.ssoSignIn=Login via Single Sign-on
|
login.ssoSignIn=Login via Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=Criação Automática de Utilizador OAUTH2 Desativada
|
login.oAuth2AutoCreateDisabled=Criação Automática de Utilizador OAUTH2 Desativada
|
||||||
login.oauth2AdminBlockedUser=O registo ou login de utilizadores não registados está atualmente bloqueado. Por favor contacte o administrador.
|
login.oAuth2AdminBlockedUser=O registo ou login de utilizadores não registados está atualmente bloqueado. Por favor contacte o administrador.
|
||||||
login.oauth2RequestNotFound=Pedido de autorização não encontrado
|
login.oauth2RequestNotFound=Pedido de autorização não encontrado
|
||||||
login.oauth2InvalidUserInfoResponse=Resposta de Informação de Utilizador Inválida
|
login.oauth2InvalidUserInfoResponse=Resposta de Informação de Utilizador Inválida
|
||||||
login.oauth2invalidRequest=Pedido Inválido
|
login.oauth2invalidRequest=Pedido Inválido
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Nume de utilizator sau parolă invalidă.
|
|||||||
login.locked=Contul tău a fost blocat.
|
login.locked=Contul tău a fost blocat.
|
||||||
login.signinTitle=Te rugăm să te autentifici
|
login.signinTitle=Te rugăm să te autentifici
|
||||||
login.ssoSignIn=Conectare prin conectare unică
|
login.ssoSignIn=Conectare prin conectare unică
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Creare automată utilizator dezactivată
|
login.oAuth2AutoCreateDisabled=OAUTH2 Creare automată utilizator dezactivată
|
||||||
login.oauth2AdminBlockedUser=Înregistrarea sau conectarea utilizatorilor neînregistrați este în prezent blocată. Te rugăm să contactezi administratorul.
|
login.oAuth2AdminBlockedUser=Înregistrarea sau conectarea utilizatorilor neînregistrați este în prezent blocată. Te rugăm să contactezi administratorul.
|
||||||
login.oauth2RequestNotFound=Cererea de autorizare nu a fost găsită
|
login.oauth2RequestNotFound=Cererea de autorizare nu a fost găsită
|
||||||
login.oauth2InvalidUserInfoResponse=Răspuns Invalid la Informațiile Utilizatorului
|
login.oauth2InvalidUserInfoResponse=Răspuns Invalid la Informațiile Utilizatorului
|
||||||
login.oauth2invalidRequest=Cerere Invalidă
|
login.oauth2invalidRequest=Cerere Invalidă
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Неверное имя пользователя или парол
|
|||||||
login.locked=Ваша учетная запись заблокирована.
|
login.locked=Ваша учетная запись заблокирована.
|
||||||
login.signinTitle=Пожалуйста, войдите
|
login.signinTitle=Пожалуйста, войдите
|
||||||
login.ssoSignIn=Вход через единый вход
|
login.ssoSignIn=Вход через единый вход
|
||||||
login.oauth2AutoCreateDisabled=Автоматическое создание пользователей OAuth2 отключено
|
login.oAuth2AutoCreateDisabled=Автоматическое создание пользователей OAuth2 отключено
|
||||||
login.oauth2AdminBlockedUser=Регистрация или вход незарегистрированных пользователей в настоящее время заблокированы. Обратитесь к администратору.
|
login.oAuth2AdminBlockedUser=Регистрация или вход незарегистрированных пользователей в настоящее время заблокированы. Обратитесь к администратору.
|
||||||
login.oauth2RequestNotFound=Запрос авторизации не найден
|
login.oauth2RequestNotFound=Запрос авторизации не найден
|
||||||
login.oauth2InvalidUserInfoResponse=Недействительный ответ с информацией о пользователе
|
login.oauth2InvalidUserInfoResponse=Недействительный ответ с информацией о пользователе
|
||||||
login.oauth2invalidRequest=Недействительный запрос
|
login.oauth2invalidRequest=Недействительный запрос
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Neplatné používateľské meno alebo heslo.
|
|||||||
login.locked=Váš účet bol uzamknutý.
|
login.locked=Váš účet bol uzamknutý.
|
||||||
login.signinTitle=Prosím, prihláste sa
|
login.signinTitle=Prosím, prihláste sa
|
||||||
login.ssoSignIn=Prihlásiť sa cez Single Sign-on
|
login.ssoSignIn=Prihlásiť sa cez Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=Vytváranie používateľa cez OAUTH2 je zakázané
|
login.oAuth2AutoCreateDisabled=Vytváranie používateľa cez OAUTH2 je zakázané
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Authorization request not found
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Invalid Request
|
login.oauth2invalidRequest=Invalid Request
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Neveljavno uporabniško ime ali geslo.
|
|||||||
login.locked=Vaš račun je bil zaklenjen.
|
login.locked=Vaš račun je bil zaklenjen.
|
||||||
login.signinTitle=Prosim prijavite se
|
login.signinTitle=Prosim prijavite se
|
||||||
login.ssoSignIn=Prijava prek enotne prijave
|
login.ssoSignIn=Prijava prek enotne prijave
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Samodejno ustvarjanje uporabnika onemogočeno
|
login.oAuth2AutoCreateDisabled=OAUTH2 Samodejno ustvarjanje uporabnika onemogočeno
|
||||||
login.oauth2AdminBlockedUser=Registracija ali prijava neregistriranih uporabnikov je trenutno blokirana. Prosimo kontaktirajte skrbnika.
|
login.oAuth2AdminBlockedUser=Registracija ali prijava neregistriranih uporabnikov je trenutno blokirana. Prosimo kontaktirajte skrbnika.
|
||||||
login.oauth2RequestNotFound=Zahteva za avtorizacijo ni bila najdena
|
login.oauth2RequestNotFound=Zahteva za avtorizacijo ni bila najdena
|
||||||
login.oauth2InvalidUserInfoResponse=Neveljaven odgovor z informacijami o uporabniku
|
login.oauth2InvalidUserInfoResponse=Neveljaven odgovor z informacijami o uporabniku
|
||||||
login.oauth2invalidRequest=Neveljavna zahteva
|
login.oauth2invalidRequest=Neveljavna zahteva
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Neispravno korisničko ime ili lozinka.
|
|||||||
login.locked=Vaš nalog je zaključan.
|
login.locked=Vaš nalog je zaključan.
|
||||||
login.signinTitle=Molimo vas da se prijavite
|
login.signinTitle=Molimo vas da se prijavite
|
||||||
login.ssoSignIn=Prijavite se putem jedinstvene prijave
|
login.ssoSignIn=Prijavite se putem jedinstvene prijave
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno
|
login.oAuth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Authorization request not found
|
login.oauth2RequestNotFound=Authorization request not found
|
||||||
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
|
||||||
login.oauth2invalidRequest=Invalid Request
|
login.oauth2invalidRequest=Invalid Request
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Ogiltigt användarnamn eller lösenord.
|
|||||||
login.locked=Ditt konto har låsts.
|
login.locked=Ditt konto har låsts.
|
||||||
login.signinTitle=Vänligen logga in
|
login.signinTitle=Vänligen logga in
|
||||||
login.ssoSignIn=Logga in via enkel inloggning
|
login.ssoSignIn=Logga in via enkel inloggning
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Auto-skapa användare inaktiverad
|
login.oAuth2AutoCreateDisabled=OAUTH2 Auto-skapa användare inaktiverad
|
||||||
login.oauth2AdminBlockedUser=Registrering eller inloggning av icke-registrerade användare är för närvarande blockerad. Kontakta administratören.
|
login.oAuth2AdminBlockedUser=Registrering eller inloggning av icke-registrerade användare är för närvarande blockerad. Kontakta administratören.
|
||||||
login.oauth2RequestNotFound=Auktoriseringsbegäran hittades inte
|
login.oauth2RequestNotFound=Auktoriseringsbegäran hittades inte
|
||||||
login.oauth2InvalidUserInfoResponse=Ogiltigt svar på användarinformation
|
login.oauth2InvalidUserInfoResponse=Ogiltigt svar på användarinformation
|
||||||
login.oauth2invalidRequest=Ogiltig begäran
|
login.oauth2invalidRequest=Ogiltig begäran
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=ชื่อผู้ใช้หรือรหัสผ่าน
|
|||||||
login.locked=บัญชีของคุณถูกล็อค
|
login.locked=บัญชีของคุณถูกล็อค
|
||||||
login.signinTitle=กรุณาลงชื่อเข้าใช้
|
login.signinTitle=กรุณาลงชื่อเข้าใช้
|
||||||
login.ssoSignIn=เข้าสู่ระบบด้วย Single Sign-on
|
login.ssoSignIn=เข้าสู่ระบบด้วย Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=การสร้างผู้ใช้ OAuth2 อัตโนมัติถูกปิดใช้งาน
|
login.oAuth2AutoCreateDisabled=การสร้างผู้ใช้ OAuth2 อัตโนมัติถูกปิดใช้งาน
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=ไม่พบคำขอการอนุญาต
|
login.oauth2RequestNotFound=ไม่พบคำขอการอนุญาต
|
||||||
login.oauth2InvalidUserInfoResponse=การตอบกลับข้อมูลผู้ใช้ไม่ถูกต้อง
|
login.oauth2InvalidUserInfoResponse=การตอบกลับข้อมูลผู้ใช้ไม่ถูกต้อง
|
||||||
login.oauth2invalidRequest=คำขอไม่ถูกต้อง
|
login.oauth2invalidRequest=คำขอไม่ถูกต้อง
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Geçersiz kullanıcı adı veya şifre.
|
|||||||
login.locked=Hesabınız kilitlendi.
|
login.locked=Hesabınız kilitlendi.
|
||||||
login.signinTitle=Lütfen giriş yapınız.
|
login.signinTitle=Lütfen giriş yapınız.
|
||||||
login.ssoSignIn=Tek Oturum Açma ile Giriş Yap
|
login.ssoSignIn=Tek Oturum Açma ile Giriş Yap
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 Otomatik Oluşturma Kullanıcı Devre Dışı Bırakıldı
|
login.oAuth2AutoCreateDisabled=OAUTH2 Otomatik Oluşturma Kullanıcı Devre Dışı Bırakıldı
|
||||||
login.oauth2AdminBlockedUser=Kayıtlı olmayan kullanıcıların kayıt veya giriş yapması şu anda engellenmiştir. Lütfen yöneticiyle iletişime geçin.
|
login.oAuth2AdminBlockedUser=Kayıtlı olmayan kullanıcıların kayıt veya giriş yapması şu anda engellenmiştir. Lütfen yöneticiyle iletişime geçin.
|
||||||
login.oauth2RequestNotFound=Yetkilendirme isteği bulunamadı
|
login.oauth2RequestNotFound=Yetkilendirme isteği bulunamadı
|
||||||
login.oauth2InvalidUserInfoResponse=Geçersiz Kullanıcı Bilgisi Yanıtı
|
login.oauth2InvalidUserInfoResponse=Geçersiz Kullanıcı Bilgisi Yanıtı
|
||||||
login.oauth2invalidRequest=Geçersiz İstek
|
login.oauth2invalidRequest=Geçersiz İstek
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Недійсне ім'я користувача або парол
|
|||||||
login.locked=Ваш обліковий запис заблоковано.
|
login.locked=Ваш обліковий запис заблоковано.
|
||||||
login.signinTitle=Будь ласка, увійдіть
|
login.signinTitle=Будь ласка, увійдіть
|
||||||
login.ssoSignIn=Увійти через єдиний вхід
|
login.ssoSignIn=Увійти через єдиний вхід
|
||||||
login.oauth2AutoCreateDisabled=Автоматичне створення користувача OAUTH2 ВИМКНЕНО
|
login.oAuth2AutoCreateDisabled=Автоматичне створення користувача OAUTH2 ВИМКНЕНО
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Запит на авторизація не знайдено
|
login.oauth2RequestNotFound=Запит на авторизація не знайдено
|
||||||
login.oauth2InvalidUserInfoResponse=Недійсна відповідь з інформацією користувача
|
login.oauth2InvalidUserInfoResponse=Недійсна відповідь з інформацією користувача
|
||||||
login.oauth2invalidRequest=Недійсний запит
|
login.oauth2invalidRequest=Недійсний запит
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=Tên đăng nhập hoặc mật khẩu không hợp lệ.
|
|||||||
login.locked=Tài khoản của bạn đã bị khóa.
|
login.locked=Tài khoản của bạn đã bị khóa.
|
||||||
login.signinTitle=Vui lòng đăng nhập
|
login.signinTitle=Vui lòng đăng nhập
|
||||||
login.ssoSignIn=Đăng nhập qua Single Sign-on
|
login.ssoSignIn=Đăng nhập qua Single Sign-on
|
||||||
login.oauth2AutoCreateDisabled=Tự động tạo người dùng OAUTH2 bị vô hiệu hóa
|
login.oAuth2AutoCreateDisabled=Tự động tạo người dùng OAUTH2 bị vô hiệu hóa
|
||||||
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
login.oAuth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
|
||||||
login.oauth2RequestNotFound=Không tìm thấy yêu cầu ủy quyền
|
login.oauth2RequestNotFound=Không tìm thấy yêu cầu ủy quyền
|
||||||
login.oauth2InvalidUserInfoResponse=Phản hồi thông tin người dùng không hợp lệ
|
login.oauth2InvalidUserInfoResponse=Phản hồi thông tin người dùng không hợp lệ
|
||||||
login.oauth2invalidRequest=Yêu cầu không hợp lệ
|
login.oauth2invalidRequest=Yêu cầu không hợp lệ
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=སྤྱོད་མིང་ངམ་གསང་ཚིག་ན
|
|||||||
login.locked=ཁྱེད་ཀྱི་ཐོ་མཛོད་ཟྭ་རྒྱག་བརྒྱབ་ཟིན།
|
login.locked=ཁྱེད་ཀྱི་ཐོ་མཛོད་ཟྭ་རྒྱག་བརྒྱབ་ཟིན།
|
||||||
login.signinTitle=ནང་འཛུལ་གནང་རོགས།
|
login.signinTitle=ནང་འཛུལ་གནང་རོགས།
|
||||||
login.ssoSignIn=གཅིག་གྱུར་ནང་འཛུལ་བརྒྱུད་ནས་ནང་འཛུལ།
|
login.ssoSignIn=གཅིག་གྱུར་ནང་འཛུལ་བརྒྱུད་ནས་ནང་འཛུལ།
|
||||||
login.oauth2AutoCreateDisabled=OAUTH2 རང་འགུལ་སྤྱོད་མཁན་གསར་བཟོ་བཀག་སྡོམ་བྱས་ཟིན།
|
login.oAuth2AutoCreateDisabled=OAUTH2 རང་འགུལ་སྤྱོད་མཁན་གསར་བཟོ་བཀག་སྡོམ་བྱས་ཟིན།
|
||||||
login.oauth2AdminBlockedUser=ད་ལྟ་ཐོ་འགོད་མ་བྱས་པའི་སྤྱོད་མཁན་གྱི་ཐོ་འགོད་དང་ནང་འཛུལ་བཀག་སྡོམ་བྱས་ཡོད། དོ་དམ་པར་འབྲེལ་བ་གནང་རོགས།
|
login.oAuth2AdminBlockedUser=ད་ལྟ་ཐོ་འགོད་མ་བྱས་པའི་སྤྱོད་མཁན་གྱི་ཐོ་འགོད་དང་ནང་འཛུལ་བཀག་སྡོམ་བྱས་ཡོད། དོ་དམ་པར་འབྲེལ་བ་གནང་རོགས།
|
||||||
login.oauth2RequestNotFound=དབང་སྤྲོད་རེ་ཞུ་རྙེད་མ་བྱུང་།
|
login.oauth2RequestNotFound=དབང་སྤྲོད་རེ་ཞུ་རྙེད་མ་བྱུང་།
|
||||||
login.oauth2InvalidUserInfoResponse=སྤྱོད་མཁན་གྱི་གནས་ཚུལ་ལན་འདེབས་ནོར་འཁྲུལ།
|
login.oauth2InvalidUserInfoResponse=སྤྱོད་མཁན་གྱི་གནས་ཚུལ་ལན་འདེབས་ནོར་འཁྲུལ།
|
||||||
login.oauth2invalidRequest=རེ་ཞུ་ནོར་འཁྲུལ།
|
login.oauth2invalidRequest=རེ་ཞུ་ནོར་འཁྲུལ།
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=用户名或密码无效。
|
|||||||
login.locked=您的账户已被锁定。
|
login.locked=您的账户已被锁定。
|
||||||
login.signinTitle=请登录
|
login.signinTitle=请登录
|
||||||
login.ssoSignIn=通过单点登录登录
|
login.ssoSignIn=通过单点登录登录
|
||||||
login.oauth2AutoCreateDisabled=OAuth2 自动创建用户已禁用
|
login.oAuth2AutoCreateDisabled=OAuth2 自动创建用户已禁用
|
||||||
login.oauth2AdminBlockedUser=目前已阻止未注册用户的注册或登录。请联系管理员。
|
login.oAuth2AdminBlockedUser=目前已阻止未注册用户的注册或登录。请联系管理员。
|
||||||
login.oauth2RequestNotFound=找不到验证请求
|
login.oauth2RequestNotFound=找不到验证请求
|
||||||
login.oauth2InvalidUserInfoResponse=无效的用户信息响应
|
login.oauth2InvalidUserInfoResponse=无效的用户信息响应
|
||||||
login.oauth2invalidRequest=无效请求
|
login.oauth2invalidRequest=无效请求
|
||||||
|
@ -572,8 +572,8 @@ login.invalid=使用者名稱或密碼無效。
|
|||||||
login.locked=您的帳號已被鎖定。
|
login.locked=您的帳號已被鎖定。
|
||||||
login.signinTitle=請登入
|
login.signinTitle=請登入
|
||||||
login.ssoSignIn=透過 SSO 單一登入
|
login.ssoSignIn=透過 SSO 單一登入
|
||||||
login.oauth2AutoCreateDisabled=OAuth 2.0 自動建立使用者功能已停用
|
login.oAuth2AutoCreateDisabled=OAuth 2.0 自動建立使用者功能已停用
|
||||||
login.oauth2AdminBlockedUser=目前不允許未註冊的使用者註冊或登入。請聯絡系統管理員。
|
login.oAuth2AdminBlockedUser=目前不允許未註冊的使用者註冊或登入。請聯絡系統管理員。
|
||||||
login.oauth2RequestNotFound=找不到驗證請求
|
login.oauth2RequestNotFound=找不到驗證請求
|
||||||
login.oauth2InvalidUserInfoResponse=使用者資訊回應無效
|
login.oauth2InvalidUserInfoResponse=使用者資訊回應無效
|
||||||
login.oauth2invalidRequest=請求無效
|
login.oauth2invalidRequest=請求無效
|
||||||
|
@ -32,7 +32,7 @@ security:
|
|||||||
google:
|
google:
|
||||||
clientId: '' # client ID for Google OAuth2
|
clientId: '' # client ID for Google OAuth2
|
||||||
clientSecret: '' # client secret for Google OAuth2
|
clientSecret: '' # client secret for Google OAuth2
|
||||||
scopes: https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile # scopes for Google OAuth2
|
scopes: email, profile # scopes for Google OAuth2
|
||||||
useAsUsername: email # field to use as the username for Google OAuth2
|
useAsUsername: email # field to use as the username for Google OAuth2
|
||||||
github:
|
github:
|
||||||
clientId: '' # client ID for GitHub OAuth2
|
clientId: '' # client ID for GitHub OAuth2
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
const runningEE = /*[[${@runningEE}]]*/ false;
|
const runningEE = /*[[${@runningEE}]]*/ false;
|
||||||
const SSOAutoLogin = /*[[${@SSOAutoLogin}]]*/ false;
|
const SSOAutoLogin = /*[[${@SSOAutoLogin}]]*/ false;
|
||||||
const loginMethod = /*[[${loginMethod}]]*/ 'normal';
|
const loginMethod = /*[[${loginMethod}]]*/ 'normal';
|
||||||
const providerList = /*[[${providerlist}]]*/ {};
|
const providerList = /*[[${providerList}]]*/ {};
|
||||||
const shouldAutoRedirect = !hasRedirectError &&
|
const shouldAutoRedirect = !hasRedirectError &&
|
||||||
!hasLogout &&
|
!hasLogout &&
|
||||||
!hasMessage &&
|
!hasMessage &&
|
||||||
@ -104,8 +104,8 @@
|
|||||||
<br>
|
<br>
|
||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
<div th:if="${erroroauth}" class="alert alert-danger text-center">
|
<div th:if="${errorOAuth}" class="alert alert-danger text-center">
|
||||||
<div th:if="${erroroauth}" th:text="#{${erroroauth}}">OAuth2: Error Message</div>
|
<div th:if="${errorOAuth}" th:text="#{${errorOAuth}}">OAuth2: Error Message</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div th:if="${error}" class="alert alert-danger text-center">
|
<div th:if="${error}" class="alert alert-danger text-center">
|
||||||
@ -164,7 +164,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="mb-3" th:each="provider : ${providerlist}">
|
<div class="mb-3" th:each="provider : ${providerList}">
|
||||||
<a th:href="@{|${provider.key}|}" th:text="${provider.value}" class="w-100 btn btn-lg btn-primary">Login Provider</a>
|
<a th:href="@{|${provider.key}|}" th:text="${provider.value}" class="w-100 btn btn-lg btn-primary">Login Provider</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,266 @@
|
|||||||
|
package stirling.software.SPDF.config.security;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class CustomLogoutSuccessHandlerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccessfulLogout() throws IOException {
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
String logoutPath = "/login?logout=true";
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(response.encodeRedirectURL(logoutPath)).thenReturn(logoutPath);
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, null);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(logoutPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccessfulLogoutViaOAuth2() throws IOException {
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken oAuth2AuthenticationToken = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn(null);
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(oAuth2AuthenticationToken.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, oAuth2AuthenticationToken);
|
||||||
|
|
||||||
|
verify(response).sendRedirect("http://localhost:8080/login?logout=true");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUserIsDisabledRedirect() throws IOException {
|
||||||
|
String error = "userIsDisabled";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AdminBlockedUser")).thenReturn(null);
|
||||||
|
when(request.getParameter(error)).thenReturn("true");
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUserAlreadyExistsWebRedirect() throws IOException {
|
||||||
|
String error = "oAuth2AuthenticationErrorWeb";
|
||||||
|
String errorPath = "userAlreadyExistsWeb";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter(error)).thenReturn("true");
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + errorPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testErrorOAuthRedirect() throws IOException {
|
||||||
|
String error = "testError";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn("!!!" + error + "!!!");
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOAuth2AutoCreateDisabled() throws IOException {
|
||||||
|
String error = "oAuth2AutoCreateDisabled";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn(null);
|
||||||
|
when(request.getParameter(error)).thenReturn("true");
|
||||||
|
when(request.getContextPath()).thenReturn(url);
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOAuth2Error() throws IOException {
|
||||||
|
String error = "test";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AdminBlockedUser")).thenReturn(null);
|
||||||
|
when(request.getParameter("userIsDisabled")).thenReturn(null);
|
||||||
|
when(request.getParameter("error")).thenReturn("!@$!@£" + error + "£$%^*$");
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOAuth2BadCredentialsError() throws IOException {
|
||||||
|
String error = "badCredentials";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AdminBlockedUser")).thenReturn(null);
|
||||||
|
when(request.getParameter("userIsDisabled")).thenReturn(null);
|
||||||
|
when(request.getParameter("error")).thenReturn(null);
|
||||||
|
when(request.getParameter(error)).thenReturn("true");
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOAuth2AdminBlockedUser() throws IOException {
|
||||||
|
String error = "oAuth2AdminBlockedUser";
|
||||||
|
String url = "http://localhost:8080";
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
OAuth2AuthenticationToken authentication = mock(OAuth2AuthenticationToken.class);
|
||||||
|
ApplicationProperties.Security security = mock(ApplicationProperties.Security.class);
|
||||||
|
ApplicationProperties.Security.OAUTH2 oauth = mock(ApplicationProperties.Security.OAUTH2.class);
|
||||||
|
|
||||||
|
when(response.isCommitted()).thenReturn(false);
|
||||||
|
when(request.getParameter("oAuth2AuthenticationErrorWeb")).thenReturn(null);
|
||||||
|
when(request.getParameter("errorOAuth")).thenReturn(null);
|
||||||
|
when(request.getParameter("oAuth2AutoCreateDisabled")).thenReturn(null);
|
||||||
|
when(request.getParameter(error)).thenReturn("true");
|
||||||
|
when(request.getScheme()).thenReturn("http");
|
||||||
|
when(request.getServerName()).thenReturn("localhost");
|
||||||
|
when(request.getServerPort()).thenReturn(8080);
|
||||||
|
when(request.getContextPath()).thenReturn("");
|
||||||
|
when(applicationProperties.getSecurity()).thenReturn(security);
|
||||||
|
when(security.getOauth2()).thenReturn(oauth);
|
||||||
|
when(authentication.getAuthorizedClientRegistrationId()).thenReturn("test");
|
||||||
|
|
||||||
|
customLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
|
||||||
|
|
||||||
|
verify(response).sendRedirect(url + "/login?errorOAuth=" + error);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package stirling.software.SPDF.utils.validation;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import stirling.software.SPDF.model.provider.GitHubProvider;
|
||||||
|
import stirling.software.SPDF.model.provider.GoogleProvider;
|
||||||
|
import stirling.software.SPDF.model.provider.KeycloakProvider;
|
||||||
|
import stirling.software.SPDF.model.provider.Provider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class ValidatorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSuccessfulValidation() {
|
||||||
|
var provider = mock(GitHubProvider.class);
|
||||||
|
|
||||||
|
when(provider.getClientId()).thenReturn("clientId");
|
||||||
|
when(provider.getClientSecret()).thenReturn("clientSecret");
|
||||||
|
when(provider.getScopes()).thenReturn(List.of("read:user"));
|
||||||
|
when(provider.getUseAsUsername()).thenReturn("email");
|
||||||
|
|
||||||
|
assertTrue(Validator.validateProvider(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("providerParams")
|
||||||
|
void testUnsuccessfulValidation(Provider provider) {
|
||||||
|
assertFalse(Validator.validateProvider(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> providerParams() {
|
||||||
|
Provider generic = null;
|
||||||
|
var google = new GoogleProvider(null, "clientSecret", List.of("scope"), "email");
|
||||||
|
var github = new GitHubProvider("clientId", "", List.of("scope"), "login");
|
||||||
|
var keycloak = new KeycloakProvider("issuer", "clientId", "clientSecret", List.of("scope"), "email");
|
||||||
|
|
||||||
|
keycloak.setUseAsUsername(null);
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(generic),
|
||||||
|
Arguments.of(google),
|
||||||
|
Arguments.of(github),
|
||||||
|
Arguments.of(keycloak)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user