Skip to content

Commit

Permalink
Fixes #4441 - Add security role refs to SecurityManager API
Browse files Browse the repository at this point in the history
  • Loading branch information
mnriem committed Dec 30, 2024
1 parent cce201d commit 8b32678
Show file tree
Hide file tree
Showing 12 changed files with 203 additions and 62 deletions.
15 changes: 15 additions & 0 deletions core/api/src/main/java/cloud/piranha/core/api/SecurityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
Expand Down Expand Up @@ -209,6 +210,13 @@ default String getRealmName() {
* @return the security constraints.
*/
List<SecurityConstraint> getSecurityConstraints();

/**
* Get the security role references.
*
* @return the security role references.
*/
Map<String, List<SecurityRoleReference>> getSecurityRoleReferences();

/**
* Get the handler that may be used by the login method to contact an
Expand Down Expand Up @@ -365,6 +373,13 @@ default void setRealmName(String realmName) {
* @param securityConstraints the security constraints.
*/
void setSecurityConstraints(List<SecurityConstraint> securityConstraints);

/**
* Set the security role references.
*
* @param securityRoleReferences the security role references.
*/
void setSecurityRoleReferences(Map<String, List<SecurityRoleReference>> securityRoleReferences);

/**
* Set the handler that may be used by the login method to contact an
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2002-2024 Manorrock.com. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package cloud.piranha.core.api;

/**
* A security role ref(erence).
*
* @author Manfred Riem (mriem@manorrock.com)
*/
public class SecurityRoleReference {

/**
* Stores the role link.
*/
private String roleLink;

/**
* Stores the role name.
*/
private String roleName;

/**
* Get the role link.
*
* @return the role link.
*/
public String getRoleLink() {
return roleLink;
}

/**
* Get the role name.
*
* @return the role name.
*/
public String getRoleName() {
return roleName;
}

/**
* Set the role link.
*
* @param roleLink the role link.
*/
public void setRoleLink(String roleLink) {
this.roleLink = roleLink;
}

/**
* Set the role name.
*
* @param roleName the role name.
*/
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@
package cloud.piranha.core.impl;

import cloud.piranha.core.api.SecurityConstraint;
import cloud.piranha.core.api.SecurityRoleReference;
import cloud.piranha.core.api.WebApplication;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
Expand All @@ -53,12 +56,18 @@ public class DefaultSecurityManager implements cloud.piranha.core.api.SecurityMa
* Stores the security constraints.
*/
private List<SecurityConstraint> securityConstraints;

/**
* Stores the security role references.
*/
private Map<String, List<SecurityRoleReference>> securityRoleReferences;

/**
* Constructor.
*/
public DefaultSecurityManager() {
securityConstraints = new ArrayList<>();
securityRoleReferences = new HashMap<>();
}

@Override
Expand All @@ -80,6 +89,11 @@ public List<SecurityConstraint> getSecurityConstraints() {
return securityConstraints;
}

@Override
public Map<String, List<SecurityRoleReference>> getSecurityRoleReferences() {
return securityRoleReferences;
}

@Override
public WebApplication getWebApplication() {
return null;
Expand All @@ -104,6 +118,11 @@ public void setSecurityConstraints(List<SecurityConstraint> securityConstraints)
this.securityConstraints = securityConstraints;
}

@Override
public void setSecurityRoleReferences(Map<String, List<SecurityRoleReference>> securityRoleReferences) {
this.securityRoleReferences = securityRoleReferences;
}

@Override
public void setWebApplication(WebApplication webApplication) {
}
Expand Down
7 changes: 0 additions & 7 deletions extension/exousia/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,5 @@
<artifactId>javassist</artifactId>
<version>3.29.2-GA</version>
</dependency>
<!-- provided -->
<dependency>
<groupId>cloud.piranha.extension</groupId>
<artifactId>piranha-extension-webxml</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.glassfish.exousia.mapping.SecurityRoleRef;

import cloud.piranha.core.api.WebApplication;
import cloud.piranha.extension.webxml.WebXmlManager;
import jakarta.security.jacc.PolicyConfiguration;
import jakarta.security.jacc.PolicyContextException;
import jakarta.servlet.FilterRegistration;
Expand Down Expand Up @@ -232,13 +231,9 @@ private List<SecurityConstraint> getConstraintsFromSecurityManager(WebApplicatio
* @throws ServletException when a Servlet error occurs.
*/
public Map<String, List<SecurityRoleRef>> getSecurityRoleRefsFromWebXml(WebApplication webApplication) throws ServletException {
WebXmlManager manager = (WebXmlManager) webApplication.getAttribute("cloud.piranha.extension.webxml.WebXmlManager");
return piranhaToExousiaConverter.getSecurityRoleRefsFromWebXml(webApplication.getServletRegistrations().keySet(), manager.getWebXml());
return piranhaToExousiaConverter.getSecurityRoleRefsFromSecurityManager(webApplication.getServletRegistrations().keySet(), webApplication);
}




private boolean hasPermissionsSet(ServletContext servletContext) {
return getOptionalAttribute(servletContext, UNCHECKED_PERMISSIONS) != null
|| getOptionalAttribute(servletContext, PERROLE_PERMISSIONS) != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@

import cloud.piranha.core.api.SecurityManager;
import cloud.piranha.core.api.SecurityWebResourceCollection;
import cloud.piranha.extension.webxml.WebXmlServletSecurityRoleRef;
import cloud.piranha.extension.webxml.WebXml;
import cloud.piranha.extension.webxml.WebXmlServlet;
import cloud.piranha.core.api.WebApplication;
import jakarta.servlet.ServletSecurityElement;
import jakarta.servlet.annotation.ServletSecurity;
import static jakarta.servlet.annotation.ServletSecurity.TransportGuarantee.CONFIDENTIAL;
import static jakarta.servlet.annotation.ServletSecurity.TransportGuarantee.NONE;
import java.util.ArrayList;
import java.util.Collections;
import static java.util.Collections.emptyList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -112,7 +108,7 @@ public List<SecurityConstraint> getConstraintsFromSecurityManager(SecurityManage

List<SecurityConstraint> constraints = new ArrayList<>();

for (cloud.piranha.core.api.SecurityConstraint xmlConstraint
for (cloud.piranha.core.api.SecurityConstraint xmlConstraint
: securityManager.getSecurityConstraints()) {

List<WebResourceCollection> webResourceCollections = new ArrayList<>();
Expand All @@ -135,55 +131,31 @@ public List<SecurityConstraint> getConstraintsFromSecurityManager(SecurityManage
}

/**
* Get the security role refs from web.xml
* Get the security role refs from the web application.
*
* @param servletNames the servlet names.
* @param webXml the web.xml.
* @param webApplication the web application.
* @return the security role refs.
*/
public Map<String, List<SecurityRoleRef>> getSecurityRoleRefsFromWebXml(Set<String> servletNames, WebXml webXml) {
public Map<String, List<SecurityRoleRef>> getSecurityRoleRefsFromSecurityManager(Set<String> servletNames, WebApplication webApplication) {
Map<String, List<SecurityRoleRef>> securityRoleRefs = new HashMap<>();

SecurityManager securityManager = webApplication.getManager().getSecurityManager();
for (String servletName : servletNames) {
securityRoleRefs.put(servletName, webXml == null ? emptyList() : getSecurityRoleRefsByServletName(webXml, servletName));
}

return securityRoleRefs;
}

private List<SecurityRoleRef> getSecurityRoleRefsByServletName(WebXml webXml, String servletName) {
List<WebXmlServletSecurityRoleRef> piranhaSecurityRoleRefs = getWebXmlSecurityRoleRefsByServletName(webXml, servletName);
if (piranhaSecurityRoleRefs.isEmpty()) {
return Collections.emptyList();
}

List<SecurityRoleRef> exousiaSecurityRoleRefs = new ArrayList<>();

for (WebXmlServletSecurityRoleRef piranhaSecurityRoleRef : piranhaSecurityRoleRefs) {
exousiaSecurityRoleRefs.add(new SecurityRoleRef(
piranhaSecurityRoleRef.roleName(),
piranhaSecurityRoleRef.roleLink()));
}

return exousiaSecurityRoleRefs;
}

private List<WebXmlServletSecurityRoleRef> getWebXmlSecurityRoleRefsByServletName(WebXml webXml, String servletName) {
WebXmlServlet servlet = getServletByName(webXml, servletName);
if (servlet == null) {
return emptyList();
}

return servlet.getSecurityRoleRefs();
}

private WebXmlServlet getServletByName(WebXml webXml, String servletName) {
for (WebXmlServlet servlet : webXml.getServlets()) {
if (servlet.getServletName().equals(servletName)) {
return servlet;
List<SecurityRoleRef> securityRoleRefList = new ArrayList<>();
if (securityManager.getSecurityRoleReferences().get(servletName) != null) {
securityManager.getSecurityRoleReferences().get(servletName).forEach(
roleReference -> {
SecurityRoleRef securityRole = new SecurityRoleRef(
roleReference.getRoleName(),
roleReference.getRoleLink());
securityRoleRefList.add(securityRole);
}
);
}
securityRoleRefs.put(servletName, securityRoleRefList);
}

return null;
return securityRoleRefs;
}
}
}
1 change: 0 additions & 1 deletion extension/exousia/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,5 @@
requires cloud.piranha.core.impl;
requires jakarta.security.jacc;
requires jakarta.servlet;
requires static cloud.piranha.extension.webxml;
requires transitive org.glassfish.exousia;
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import cloud.piranha.core.api.AuthenticatedIdentity;
import cloud.piranha.core.api.SecurityConstraint;
import cloud.piranha.core.api.SecurityManager;
import cloud.piranha.core.api.SecurityRoleReference;
import cloud.piranha.core.api.WebApplication;
import cloud.piranha.core.api.WebApplicationRequest;
import cloud.piranha.core.impl.DefaultAuthenticatedIdentity;
Expand All @@ -54,7 +55,9 @@
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.glassfish.epicyro.config.helper.Caller;
import org.glassfish.epicyro.services.DefaultAuthenticationService;

Expand Down Expand Up @@ -101,6 +104,11 @@ public class ServletSecurityManager implements SecurityManager {
*/
protected List<SecurityConstraint> securityConstraints;

/**
* Stores the security role references.
*/
protected Map<String, List<SecurityRoleReference>> securityRoleReferences;

/**
* Handler for the specific HttpServletRequest#login method call
*/
Expand All @@ -115,7 +123,8 @@ public class ServletSecurityManager implements SecurityManager {
* Constructor.
*/
public ServletSecurityManager() {
this.securityConstraints = new ArrayList<>();
securityConstraints = new ArrayList<>();
securityRoleReferences = new HashMap<>();
}

@Override
Expand Down Expand Up @@ -236,6 +245,11 @@ public List<SecurityConstraint> getSecurityConstraints() {
return securityConstraints;
}

@Override
public Map<String, List<SecurityRoleReference>> getSecurityRoleReferences() {
return securityRoleReferences;
}

private String getServletName(HttpServletRequest request) {
ServletConfig servletConfig = (ServletConfig) request.getAttribute(DefaultServletEnvironment.class.getName());
if (servletConfig != null && servletConfig.getServletName() != null) {
Expand Down Expand Up @@ -347,6 +361,11 @@ public void setSecurityConstraints(List<SecurityConstraint> securityConstraints)
this.securityConstraints = securityConstraints;
}

@Override
public void setSecurityRoleReferences(Map<String, List<SecurityRoleReference>> securityRoleReferences) {
this.securityRoleReferences = securityRoleReferences;
}

@Override
public void setUsernamePasswordLoginHandler(UsernamePasswordLoginHandler usernamePasswordLoginHandler) {
this.usernamePasswordLoginHandler = usernamePasswordLoginHandler;
Expand Down
Loading

0 comments on commit 8b32678

Please sign in to comment.