Skip to content

Commit

Permalink
Adjust Spring Security settings to work around spring-projects/spring…
Browse files Browse the repository at this point in the history
  • Loading branch information
ilgrosso committed Oct 10, 2023
1 parent 2fd8969 commit 54ccb4d
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -430,7 +430,7 @@ under the License.
<commons-jexl.version>3.3</commons-jexl.version>
<commons-text.version>1.10.0</commons-text.version>

<pac4j.version>6.0.0-RC9</pac4j.version>
<pac4j.version>6.0.0-RC10-SNAPSHOT</pac4j.version>

<cas.version>7.0.0-SNAPSHOT</cas.version>
<cas-client.version>4.0.3</cas-client.version>
Expand Down
Expand Up @@ -26,13 +26,13 @@ public class WAProperties extends SyncopeProperties {

private static final long serialVersionUID = 7925827623055998239L;

private long contextRefreshDelay = 15;
private int contextRefreshDelay = 15;

public long getContextRefreshDelay() {
public int getContextRefreshDelay() {
return contextRefreshDelay;
}

public void setContextRefreshDelay(final long contextRefreshDelay) {
public void setContextRefreshDelay(final int contextRefreshDelay) {
this.contextRefreshDelay = contextRefreshDelay;
}
}
4 changes: 4 additions & 0 deletions wa/starter/pom.xml
Expand Up @@ -123,6 +123,10 @@ under the License.
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-web</artifactId>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-web-api</artifactId>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-webflow</artifactId>
Expand Down
Expand Up @@ -61,6 +61,7 @@
import org.apache.syncope.wa.starter.saml.idp.WASamlIdPCasEventListener;
import org.apache.syncope.wa.starter.saml.idp.metadata.WASamlIdPMetadataGenerator;
import org.apache.syncope.wa.starter.saml.idp.metadata.WASamlIdPMetadataLocator;
import org.apache.syncope.wa.starter.security.WAWebSecurityConfigurerAdapter;
import org.apache.syncope.wa.starter.services.WAServiceRegistry;
import org.apache.syncope.wa.starter.surrogate.WASurrogateAuthenticationService;
import org.apache.syncope.wa.starter.webauthn.WAWebAuthnCredentialRepository;
Expand Down Expand Up @@ -88,18 +89,25 @@
import org.apereo.cas.trusted.authentication.api.MultifactorAuthenticationTrustStorage;
import org.apereo.cas.util.LdapUtils;
import org.apereo.cas.util.crypto.CipherExecutor;
import org.apereo.cas.web.CasWebSecurityConfigurer;
import org.apereo.cas.webauthn.storage.WebAuthnCredentialRepository;
import org.ldaptive.ConnectionFactory;
import org.pac4j.core.client.Client;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.context.SecurityContextRepository;

@Configuration(proxyBeanMethods = false)
public class WAContext {
Expand Down Expand Up @@ -129,6 +137,31 @@ public OpenAPI casSwaggerOpenApi(final ConfigurableApplicationContext ctx) {
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT"));
}

@SuppressWarnings("rawtypes")
@ConditionalOnMissingBean(name = "waWebSecurityConfigurerAdapter")
@Bean(name = { "waWebSecurityConfigurerAdapter", "casWebSecurityConfigurerAdapter" })
public SecurityFilterChain waWebSecurityConfigurerAdapter(
@Qualifier("securityContextRepository")
final SecurityContextRepository securityContextRepository,
final HttpSecurity http,
final ObjectProvider<PathMappedEndpoints> pathMappedEndpoints,
final List<CasWebSecurityConfigurer> configurersList,
final WebEndpointProperties webEndpointProperties,
final SecurityProperties securityProperties,
final CasConfigurationProperties casProperties,
final WAProperties waProperties) throws Exception {

WAWebSecurityConfigurerAdapter adapter = new WAWebSecurityConfigurerAdapter(
waProperties,
casProperties,
securityProperties,
webEndpointProperties,
pathMappedEndpoints,
configurersList,
securityContextRepository);
return adapter.configureHttpSecurity(http).build();
}

@ConditionalOnMissingBean
@Bean
public AccessMapper defaultAccessMapper() {
Expand Down
@@ -0,0 +1,111 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.wa.starter.security;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.syncope.wa.bootstrap.WAProperties;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.CasWebSecurityConfigurer;
import org.apereo.cas.web.security.CasWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.context.SecurityContextRepository;

public class WAWebSecurityConfigurerAdapter extends CasWebSecurityConfigurerAdapter {

protected final WAProperties waProperties;

@SuppressWarnings("rawtypes")
public WAWebSecurityConfigurerAdapter(
final WAProperties waProperties,
final CasConfigurationProperties casProperties,
final SecurityProperties securityProperties,
final WebEndpointProperties webEndpointProperties,
final ObjectProvider<PathMappedEndpoints> pathMappedEndpoints,
final List<CasWebSecurityConfigurer> protocolEndpointWebSecurityConfigurers,
final SecurityContextRepository securityContextRepository) {

super(casProperties, securityProperties, webEndpointProperties, pathMappedEndpoints,
protocolEndpointWebSecurityConfigurers, securityContextRepository);
this.waProperties = waProperties;
}

@Override
protected void configureEndpointAccessAuthenticated(
final HttpSecurity http,
final EndpointRequest.EndpointRequestMatcher endpoint) throws Exception {

http.authorizeHttpRequests(customizer -> customizer.requestMatchers(endpoint).authenticated());

http.with(new AbstractHttpConfigurer<HttpBasicConfigurer<HttpSecurity>, HttpSecurity>() {

@Override
public void configure(final HttpSecurity http) throws Exception {
BasicAuthenticationFilter filter = new BasicAuthenticationFilter(
http.getSharedObject(AuthenticationManager.class),
new BasicAuthenticationEntryPoint()) {

@Override
protected void doFilterInternal(
final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain chain)
throws IOException, ServletException {

if (request.getRequestURI().contains("/oidc")) {
logger.trace("Skip processing since this is an OIDC request");
return;
}

super.doFilter(request, response, chain);
}
};
filter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
http.addFilter(postProcess(filter));
}
}, Customizer.withDefaults());

UserDetails user = User.withUsername(waProperties.getAnonymousUser()).
password("{noop}" + waProperties.getAnonymousKey()).
roles(IdRepoEntitlement.ANONYMOUS).
build();
http.userDetailsService(new InMemoryUserDetailsManager(user));

http.csrf(AbstractHttpConfigurer::disable);
}
}
3 changes: 0 additions & 3 deletions wa/starter/src/main/resources/wa.properties
Expand Up @@ -94,9 +94,6 @@ cas.sso.services.allow-missing-service-parameter=true
# by default for now.
cas.acceptable-usage-policy.core.enabled=false

spring.security.user.name=${anonymousUser}
spring.security.user.password=${anonymousKey}

springdoc.show-actuator=true
springdoc.model-and-view-allowed=true
springdoc.writer-with-default-pretty-printer=true
Expand Down
7 changes: 7 additions & 0 deletions wa/starter/src/test/resources/debug/log4j2.xml
Expand Up @@ -45,9 +45,16 @@ under the License.
<appender-ref ref="main"/>
</asyncLogger>

<asyncLogger name="io.micrometer" additivity="false" level="ERROR">
<appender-ref ref="main"/>
</asyncLogger>

<asyncLogger name="org.springframework" additivity="false" level="INFO">
<appender-ref ref="main"/>
</asyncLogger>
<asyncLogger name="org.springframework.security" additivity="false" level="TRACE">
<appender-ref ref="main"/>
</asyncLogger>

<asyncLogger name="org.apache.syncope.client.lib" additivity="false" level="OFF">
<appender-ref ref="main"/>
Expand Down
6 changes: 4 additions & 2 deletions wa/starter/src/test/resources/debug/wa-debug.properties
Expand Up @@ -16,11 +16,13 @@
# under the License.
spring.main.allow-circular-references=true

#keymaster.address=http://localhost:9080/syncope/rest/keymaster
keymaster.address=https://localhost:9443/syncope/rest/keymaster
keymaster.address=http://localhost:9080/syncope/rest/keymaster
#keymaster.address=https://localhost:9443/syncope/rest/keymaster
keymaster.username=${anonymousUser}
keymaster.password=${anonymousKey}

management.endpoints.web.exposure.include=info,health,env,beans,loggers,ssoSessions,registeredServices,refresh,authenticationHandlers,authenticationPolicies,resolveAttributes

cas.server.name=http://localhost:8080
cas.server.prefix=${cas.server.name}/syncope-wa
cas.authn.accept.users=admin::password
Expand Down

0 comments on commit 54ccb4d

Please sign in to comment.