mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-02-07 00:17:07 +01:00
wip - working on saml2
This commit is contained in:
parent
7d784e2964
commit
f067e5df8c
@ -34,10 +34,7 @@ public class AppConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(
|
||||
name = "system.customHTMLFiles",
|
||||
havingValue = "true",
|
||||
matchIfMissing = false)
|
||||
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
|
||||
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
|
||||
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
|
||||
templateEngine.addTemplateResolver(new FileFallbackTemplateResolver(resourceLoader));
|
||||
@ -137,8 +134,8 @@ public class AppConfig {
|
||||
}
|
||||
|
||||
@ConditionalOnMissingClass("stirling.software.SPDF.config.security.SecurityConfiguration")
|
||||
@Bean(name = "activSecurity")
|
||||
public boolean missingActivSecurity() {
|
||||
@Bean(name = "activeSecurity")
|
||||
public boolean missingActiveSecurity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ public class SecurityConfiguration {
|
||||
}
|
||||
// Handle SAML
|
||||
if (applicationProperties.getSecurity().isSaml2Active()) {
|
||||
// && runningEE
|
||||
// todo: && runningEE
|
||||
// Configure the authentication provider
|
||||
OpenSaml4AuthenticationProvider authenticationProvider =
|
||||
new OpenSaml4AuthenticationProvider();
|
||||
@ -314,7 +314,7 @@ public class SecurityConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public boolean activSecurity() {
|
||||
public boolean activeSecurity() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -219,9 +219,7 @@ public class OAuth2Configuration {
|
||||
*/
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(
|
||||
value = "security.oauth2.enabled",
|
||||
havingValue = "true")
|
||||
@ConditionalOnProperty(value = "security.oauth2.enabled", havingValue = "true")
|
||||
GrantedAuthoritiesMapper userAuthoritiesMapper() {
|
||||
return (authorities) -> {
|
||||
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
|
||||
|
@ -8,7 +8,6 @@ import org.springframework.security.saml2.core.Saml2Error;
|
||||
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -21,7 +20,7 @@ public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthentica
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
AuthenticationException exception)
|
||||
throws IOException, ServletException {
|
||||
throws IOException {
|
||||
if (exception instanceof Saml2AuthenticationException) {
|
||||
Saml2Error error = ((Saml2AuthenticationException) exception).getSaml2Error();
|
||||
getRedirectStrategy()
|
||||
|
@ -140,19 +140,23 @@ public class AccountWebController {
|
||||
case "userAlreadyExistsWeb" -> errorOAuth = "userAlreadyExistsWebMessage";
|
||||
case "oAuth2AuthenticationErrorWeb" -> errorOAuth = "login.oauth2InvalidUserType";
|
||||
case "invalid_token_response" -> errorOAuth = "login.oauth2InvalidTokenResponse";
|
||||
case "authorization_request_not_found" -> errorOAuth = "login.oauth2RequestNotFound";
|
||||
case "authorization_request_not_found" ->
|
||||
errorOAuth = "login.oauth2RequestNotFound";
|
||||
case "access_denied" -> errorOAuth = "login.oauth2AccessDenied";
|
||||
case "invalid_user_info_response" -> errorOAuth = "login.oauth2InvalidUserInfoResponse";
|
||||
case "invalid_user_info_response" ->
|
||||
errorOAuth = "login.oauth2InvalidUserInfoResponse";
|
||||
case "invalid_request" -> errorOAuth = "login.oauth2invalidRequest";
|
||||
case "invalid_id_token" -> errorOAuth = "login.oauth2InvalidIdToken";
|
||||
case "oAuth2AdminBlockedUser" -> errorOAuth = "login.oAuth2AdminBlockedUser";
|
||||
case "userIsDisabled" -> errorOAuth = "login.userIsDisabled";
|
||||
case "invalid_destination" -> errorOAuth = "login.invalid_destination";
|
||||
case "relying_party_registration_not_found" -> errorOAuth = "login.relyingPartyRegistrationNotFound";
|
||||
case "relying_party_registration_not_found" ->
|
||||
errorOAuth = "login.relyingPartyRegistrationNotFound";
|
||||
// Valid InResponseTo was not available from the validation context, unable to
|
||||
// evaluate
|
||||
case "invalid_in_response_to" -> errorOAuth = "login.invalid_in_response_to";
|
||||
case "not_authentication_provider_found" -> errorOAuth = "login.not_authentication_provider_found";
|
||||
case "not_authentication_provider_found" ->
|
||||
errorOAuth = "login.not_authentication_provider_found";
|
||||
}
|
||||
|
||||
model.addAttribute("errorOAuth", errorOAuth);
|
||||
|
@ -109,7 +109,7 @@ public class ApplicationProperties {
|
||||
private int loginAttemptCount;
|
||||
private long loginResetTimeMinutes;
|
||||
private String loginMethod = "all";
|
||||
private String customGlobalAPIKey;
|
||||
private String customGlobalAPIKey; // todo: expose?
|
||||
|
||||
public Boolean isAltLogin() {
|
||||
return saml2.getEnabled() || oauth2.getEnabled();
|
||||
|
@ -17,6 +17,7 @@ security:
|
||||
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
|
||||
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
|
||||
loginMethod: saml2 # Accepts values like 'all' and 'normal'(only Login with Username/Password), 'oauth2'(only Login with OAuth2) or 'saml2'(only Login with SAML2)
|
||||
customGlobalAPIKey: 3R3T-WFPY-UNRW-LJFA-MMXM-YVJK-WCKY-PCRT # todo: this is in ApplicationProperties but not here. Should we add it
|
||||
initialLogin:
|
||||
username: '' # initial username for the first login
|
||||
password: '' # initial password for the first login
|
||||
@ -28,20 +29,20 @@ security:
|
||||
clientId: '' # client ID for Keycloak OAuth2
|
||||
clientSecret: '' # client secret for Keycloak OAuth2
|
||||
scopes: openid, profile, email # scopes for Keycloak OAuth2
|
||||
useAsUsername: preferred_username # field to use as the username for Keycloak OAuth2
|
||||
useAsUsername: preferred_username # field to use as the username for Keycloak OAuth2. Available options are: [email | preferred_name]
|
||||
google:
|
||||
clientId: '' # client ID for Google OAuth2
|
||||
clientSecret: '' # client secret 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. Available options are: [email | name | given_name | family_name]
|
||||
github:
|
||||
clientId: '' # client ID for GitHub OAuth2
|
||||
clientSecret: '' # client secret for GitHub OAuth2
|
||||
scopes: read:user # scope for GitHub OAuth2
|
||||
useAsUsername: login # field to use as the username for GitHub OAuth2
|
||||
issuer: '' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint
|
||||
clientId: '' # client ID from your provider
|
||||
clientSecret: '' # client secret from your provider
|
||||
useAsUsername: login # field to use as the username for GitHub OAuth2. Available options are: [email | login | name]
|
||||
issuer: 'https://authentik.dev.stirlingpdf.com/application/o/stirlingpdf-oauth/' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint
|
||||
clientId: '5ibI9Ud5cRNFIcS1gIJME0shO6VZOy6Ae6XUrZL0' # client ID from your provider
|
||||
clientSecret: 'DFSD3B7MKLkWuEAasxxm2hghuzulPr37jdkrojPsGBz9MGwkfc' # client secret from your provider
|
||||
autoCreateUser: true # set to 'true' to allow auto-creation of non-existing users
|
||||
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
|
||||
useAsUsername: email # default is 'email'; custom fields can be used as the username
|
||||
|
@ -253,11 +253,11 @@
|
||||
<label for="cacheInputs" th:text="#{settings.cacheInputs.name}"></label>
|
||||
</div>
|
||||
|
||||
<a th:if="${@loginEnabled and @activSecurity}" th:href="@{'/account'}" class="btn btn-sm btn-outline-primary"
|
||||
<a th:if="${@loginEnabled and @activeSecurity}" th:href="@{'/account'}" class="btn btn-sm btn-outline-primary"
|
||||
role="button" th:text="#{settings.accountSettings}" target="_blank">Account Settings</a>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a th:if="${@loginEnabled and @activSecurity}" class="btn btn-danger" role="button"
|
||||
<a th:if="${@loginEnabled and @activeSecurity}" class="btn btn-danger" role="button"
|
||||
th:text="#{settings.signOut}" th:href="@{'/logout'}">Sign Out</a>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" th:text="#{close}"></button>
|
||||
</div>
|
||||
|
@ -29,7 +29,6 @@ class ValidatorTest {
|
||||
when(provider.getClientId()).thenReturn("clientId");
|
||||
when(provider.getClientSecret()).thenReturn("clientSecret");
|
||||
when(provider.getScopes()).thenReturn(List.of("read:user"));
|
||||
when(provider.getUseAsUsername()).thenReturn(UsernameAttribute.EMAIL);
|
||||
|
||||
assertTrue(Validator.validateProvider(provider));
|
||||
}
|
||||
@ -44,15 +43,11 @@ class ValidatorTest {
|
||||
Provider generic = null;
|
||||
var google = new GoogleProvider(null, "clientSecret", List.of("scope"), UsernameAttribute.EMAIL);
|
||||
var github = new GitHubProvider("clientId", "", List.of("scope"), UsernameAttribute.LOGIN);
|
||||
var keycloak = new KeycloakProvider("issuer", "clientId", "clientSecret", List.of("scope"), UsernameAttribute.EMAIL);
|
||||
|
||||
keycloak.setUseAsUsername(null);
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(generic),
|
||||
Arguments.of(google),
|
||||
Arguments.of(github),
|
||||
Arguments.of(keycloak)
|
||||
Arguments.of(github)
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user