mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-07-14 13:48:15 +02:00
wip - testing different name attributes for SSO
This commit is contained in:
parent
d3cfc813e7
commit
acabb69e1f
@ -169,7 +169,9 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles different error scenarios during logout. Will return a <code>String</code> containing the error request parameter.
|
* 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.
|
* @param request the user's <code>HttpServletRequest</code> request.
|
||||||
* @return a <code>String</code> containing the error request parameter.
|
* @return a <code>String</code> containing the error request parameter.
|
||||||
*/
|
*/
|
||||||
|
@ -24,11 +24,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,
|
||||||
@ -44,8 +44,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 {
|
||||||
@ -58,13 +59,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.");
|
||||||
|
@ -28,6 +28,7 @@ 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.exception.NoProviderFoundException;
|
||||||
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;
|
||||||
@ -51,7 +52,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);
|
||||||
@ -59,8 +61,8 @@ 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);
|
||||||
@ -69,7 +71,7 @@ public class OAuth2Configuration {
|
|||||||
private Optional<ClientRegistration> keycloakClientRegistration() {
|
private Optional<ClientRegistration> keycloakClientRegistration() {
|
||||||
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (isOauthOrClientEmpty(oauth2)) {
|
if (isOAuth2Enabled(oauth2) || isClientInitialised(oauth2)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,13 +99,13 @@ public class OAuth2Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> googleClientRegistration() {
|
private Optional<ClientRegistration> googleClientRegistration() {
|
||||||
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oAuth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (isOauthOrClientEmpty(oauth2)) {
|
if (isOAuth2Enabled(oAuth2) || isClientInitialised(oAuth2)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
Client client = oauth2.getClient();
|
Client client = oAuth2.getClient();
|
||||||
GoogleProvider googleClient = client.getGoogle();
|
GoogleProvider googleClient = client.getGoogle();
|
||||||
Provider google =
|
Provider google =
|
||||||
new GoogleProvider(
|
new GoogleProvider(
|
||||||
@ -130,13 +132,13 @@ public class OAuth2Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ClientRegistration> githubClientRegistration() {
|
private Optional<ClientRegistration> githubClientRegistration() {
|
||||||
OAUTH2 oauth2 = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oAuth2 = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (isOauthOrClientEmpty(oauth2)) {
|
if (isOAuth2Enabled(oAuth2)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
Client client = oauth2.getClient();
|
Client client = oAuth2.getClient();
|
||||||
GitHubProvider githubClient = client.getGithub();
|
GitHubProvider githubClient = client.getGithub();
|
||||||
Provider github =
|
Provider github =
|
||||||
new GitHubProvider(
|
new GitHubProvider(
|
||||||
@ -165,7 +167,7 @@ public class OAuth2Configuration {
|
|||||||
private Optional<ClientRegistration> oidcClientRegistration() {
|
private Optional<ClientRegistration> oidcClientRegistration() {
|
||||||
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
|
||||||
|
|
||||||
if (isOauthOrClientEmpty(oauth)) {
|
if (isOAuth2Enabled(oauth) || isClientInitialised(oauth)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,12 +196,12 @@ public class OAuth2Configuration {
|
|||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOauthOrClientEmpty(OAUTH2 oauth) {
|
private boolean isOAuth2Enabled(OAUTH2 oAuth2) {
|
||||||
if (oauth == null || !oauth.getEnabled()) {
|
return oAuth2 == null || !oAuth2.getEnabled();
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Client client = oauth.getClient();
|
private boolean isClientInitialised(OAUTH2 oauth2) {
|
||||||
|
Client client = oauth2.getClient();
|
||||||
return client == null;
|
return client == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ public class AccountWebController {
|
|||||||
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;
|
||||||
|
@ -245,11 +245,11 @@ public class ApplicationProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSettingsValid() {
|
public boolean isSettingsValid() {
|
||||||
return isStringEmpty(this.getIssuer())
|
return !isStringEmpty(this.getIssuer())
|
||||||
&& isStringEmpty(this.getClientId())
|
&& !isStringEmpty(this.getClientId())
|
||||||
&& isStringEmpty(this.getClientSecret())
|
&& !isStringEmpty(this.getClientSecret())
|
||||||
&& isCollectionEmpty(this.getScopes())
|
&& !isCollectionEmpty(this.getScopes())
|
||||||
&& isStringEmpty(this.getUseAsUsername());
|
&& !isStringEmpty(this.getUseAsUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -57,9 +57,7 @@ public class Provider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Provider [issuer="
|
return "Provider [name="
|
||||||
+ getIssuer()
|
|
||||||
+ ", name="
|
|
||||||
+ getName()
|
+ getName()
|
||||||
+ ", clientName="
|
+ ", clientName="
|
||||||
+ getClientName()
|
+ getClientName()
|
||||||
|
@ -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 &&
|
||||||
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user