Skip to content

Commit

Permalink
Merged in bugfix/shibui-2333 (pull request #604)
Browse files Browse the repository at this point in the history
SHIBUI-2333

Approved-by: Dmitriy Kopylenko
Approved-by: Bill Smith
  • Loading branch information
chasegawa committed Aug 30, 2022
2 parents 6c29611 + cbdd7ae commit 0b39de8
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 17 deletions.
1 change: 1 addition & 0 deletions backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# identityProviderMetadataPath: "/etc/shibui/idp-metadata.xml"
# forceServiceProviderMetadataGeneration: false
# callbackUrl: "https://localhost:8443/callback"
# postLogoutURL: "https://idp.example.com/idp/profile/Logout" # Must set this to get IDP logout
# maximumAuthenticationLifetime: 3600000
# requireAssertedRoleForNewUsers: false
# saml2ProfileMapping:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.unicon.shibui.pac4j.authenticator.ShibuiSAML2Authenticator;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.core.engine.LogoutLogic;
import org.pac4j.core.matching.matcher.PathMatcher;
import org.pac4j.core.profile.definition.CommonProfileDefinition;
import org.pac4j.http.client.direct.HeaderClient;
Expand Down Expand Up @@ -69,32 +70,39 @@ public Config config(final Pac4jConfigurationProperties pac4jConfigProps,
case "SAML2":
default:
log.info("**** Configuring PAC4J SAML2");
final SAML2Configuration saml2Config = new SAML2Configuration();
saml2Config.setKeystorePath(pac4jConfigProps.getKeystorePath());
saml2Config.setKeystorePassword(pac4jConfigProps.getKeystorePassword());
saml2Config.setPrivateKeyPassword(pac4jConfigProps.getPrivateKeyPassword());
saml2Config.setIdentityProviderMetadataPath(pac4jConfigProps.getIdentityProviderMetadataPath());
saml2Config.setMaximumAuthenticationLifetime(pac4jConfigProps.getMaximumAuthenticationLifetime());
saml2Config.setServiceProviderEntityId(pac4jConfigProps.getServiceProviderEntityId());
saml2Config.setServiceProviderMetadataPath(pac4jConfigProps.getServiceProviderMetadataPath());
saml2Config.setForceServiceProviderMetadataGeneration(pac4jConfigProps.isForceServiceProviderMetadataGeneration());
saml2Config.setWantsAssertionsSigned(pac4jConfigProps.isWantAssertionsSigned());
saml2Config.setAttributeAsId(pac4jConfigProps.getSimpleProfileMapping().getUsername());
final SAML2Configuration saml2Config = buildSaml2ConfigFromPac4JConfiguration(pac4jConfigProps);


final SAML2Client saml2Client = new SAML2Client(saml2Config);
saml2Client.setName(PAC4J_CLIENT_NAME);
saml2Client.addAuthorizationGenerator(saml2ModelAuthorizationGenerator);
SAML2Authenticator saml2Authenticator = new ShibuiSAML2Authenticator(saml2Config.getAttributeAsId(), saml2Config.getMappedAttributes(), userService);
saml2Authenticator.setProfileDefinition(new CommonProfileDefinition(p -> new BetterSAML2Profile(pac4jConfigProps.getSimpleProfileMapping())));
saml2Client.setAuthenticator(saml2Authenticator);

saml2Client.setName(PAC4J_CLIENT_NAME);
clients.setClients(saml2Client);
break;
}
config.setClients(clients);
return config;
}


private SAML2Configuration buildSaml2ConfigFromPac4JConfiguration(Pac4jConfigurationProperties pac4jConfigProps) {
SAML2Configuration saml2Config = new SAML2Configuration();
saml2Config.setKeystorePath(pac4jConfigProps.getKeystorePath());
saml2Config.setKeystorePassword(pac4jConfigProps.getKeystorePassword());
saml2Config.setPrivateKeyPassword(pac4jConfigProps.getPrivateKeyPassword());
saml2Config.setIdentityProviderMetadataPath(pac4jConfigProps.getIdentityProviderMetadataPath());
saml2Config.setMaximumAuthenticationLifetime(pac4jConfigProps.getMaximumAuthenticationLifetime());
saml2Config.setServiceProviderEntityId(pac4jConfigProps.getServiceProviderEntityId());
saml2Config.setServiceProviderMetadataPath(pac4jConfigProps.getServiceProviderMetadataPath());
saml2Config.setForceServiceProviderMetadataGeneration(pac4jConfigProps.isForceServiceProviderMetadataGeneration());
saml2Config.setWantsAssertionsSigned(pac4jConfigProps.isWantAssertionsSigned());
saml2Config.setAttributeAsId(pac4jConfigProps.getSimpleProfileMapping().getUsername());
saml2Config.setPostLogoutURL(pac4jConfigProps.getPostLogoutURL());
return saml2Config;
}

@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return this::registerErrorPages;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class Pac4jConfigurationProperties {
private String serviceProviderEntityId = "https://unicon.net/shibui";
private String serviceProviderMetadataPath = "/tmp/sp-metadata.xml";
private String typeOfAuth = "SAML2";
private String postLogoutURL;

private boolean wantAssertionsSigned = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import edu.internet2.tier.shibboleth.admin.ui.security.service.IRolesService;
import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService;
import edu.internet2.tier.shibboleth.admin.ui.service.EmailService;
import org.jadira.usertype.spi.utils.lang.StringUtils;
import org.pac4j.core.authorization.authorizer.DefaultAuthorizers;
import org.pac4j.core.config.Config;
import org.pac4j.core.matching.matcher.Matcher;
import org.pac4j.springframework.security.web.CallbackFilter;
import org.pac4j.springframework.security.web.LogoutFilter;
import org.pac4j.springframework.security.web.SecurityFilter;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
Expand Down Expand Up @@ -64,12 +66,23 @@ public Pac4jWebSecurityConfigurerAdapter(final Config config, UserService userSe
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/unsecured/**/*").permitAll();

// adding the authorizor bypasses the default behavior of checking CSRF in Pac4J's default securitylogic+defaultauthorizationchecker
// adding the authorizer bypasses the default behavior of checking CSRF in Pac4J's default securitylogic+defaultauthorizationchecker
final SecurityFilter securityFilter = new SecurityFilter(this.config, PAC4J_CLIENT_NAME, DefaultAuthorizers.IS_AUTHENTICATED);

// add filter based on auth type
http.antMatcher("/**").addFilterBefore(getFilter(config, pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class);
// If the post logout URL is configured, setup the logout filter
if (StringUtils.isNotEmpty(pac4jConfigurationProperties.getPostLogoutURL())){
final LogoutFilter logoutFilter = new LogoutFilter(config);
logoutFilter.setLocalLogout(Boolean.TRUE);
logoutFilter.setSuffix("login"); // "logout" is redirected before we ever hit the filters - sent to /login?logout
logoutFilter.setCentralLogout(Boolean.TRUE);
logoutFilter.setDefaultUrl(pac4jConfigurationProperties.getPostLogoutURL());
http.antMatcher("/**").addFilterBefore(logoutFilter, BasicAuthenticationFilter.class);
}

// add filters
http.antMatcher("/**").addFilterBefore(getFilter(pac4jConfigurationProperties.getTypeOfAuth()), BasicAuthenticationFilter.class);
http.antMatcher("/**").addFilterBefore(securityFilter, BasicAuthenticationFilter.class);

// add the new user filter
http.addFilterAfter(new AddNewUserFilter(pac4jConfigurationProperties, userService, rolesService, getPathMatcher("exclude-paths-matcher"), groupService, emailService), SecurityFilter.class);

Expand All @@ -84,7 +97,7 @@ private Matcher getPathMatcher(String name) {
return config.getMatchers().get(name);
}

private Filter getFilter(Config config2, String typeOfAuth) {
private Filter getFilter(String typeOfAuth) {
switch (typeOfAuth) {
case "SAML2":
return new CallbackFilter(this.config);
Expand Down
1 change: 1 addition & 0 deletions testbed/authentication/shibui/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ shibui:
forceServiceProviderMetadataGeneration: true
callbackUrl: "https://shibui.unicon.local/callback"
maximumAuthenticationLifetime: 3600000
postLogoutURL: "https://idp.unicon.local/idp/profile/Logout"
simpleProfileMapping:
username: urn:oid:0.9.2342.19200300.100.1.1
firstName: urn:oid:2.5.4.42
Expand Down

0 comments on commit 0b39de8

Please sign in to comment.