Skip to content

Commit 010b44d

Browse files
committed
Initial setup and Payara API example for JACC per web module
1 parent 45acb8b commit 010b44d

File tree

21 files changed

+1685
-1
lines changed

21 files changed

+1685
-1
lines changed

.gitignore

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Directories #
2+
build/
3+
bin/
4+
target/
5+
libs/
6+
tmp/
7+
node_modules/
8+
9+
# OS Files #
10+
.DS_Store
11+
12+
*.class
13+
14+
# Package Files #
15+
*.jar
16+
*.war
17+
*.ear
18+
*.db
19+
rebel.xml
20+
21+
######################
22+
# Windows
23+
######################
24+
25+
# Windows image file caches
26+
Thumbs.db
27+
28+
# Folder config file
29+
Desktop.ini
30+
31+
######################
32+
# OSX
33+
######################
34+
35+
.DS_Store
36+
.svn
37+
38+
# Thumbnails
39+
._*
40+
41+
# Files that might appear on external disk
42+
.Spotlight-V100
43+
.Trashes
44+
45+
######################
46+
# NetBeans
47+
######################
48+
nbproject/
49+
build/
50+
nbbuild/
51+
dist/
52+
nbdist/
53+
nbactions.xml
54+
nb-configuration.xml
55+
56+
######################
57+
# IDEA
58+
######################
59+
*.iml
60+
*.ipr
61+
*.iws
62+
.idea/
63+
atlassian-ide-plugin.xml
64+
65+
66+
######################
67+
# Eclipse
68+
######################
69+
70+
*.pydevproject
71+
.project
72+
.metadata
73+
*.tmp
74+
*.bak
75+
*.swp
76+
*~.nib
77+
local.properties
78+
.classpath
79+
.settings/
80+
.loadpath
81+
82+
# External tool builders
83+
.externalToolBuilders/
84+
85+
# Locally stored "Eclipse launch configurations"
86+
*.launch
87+
88+
# CDT-specific
89+
.cproject
90+
91+
# PDT-specific
92+
.buildpath
93+
94+
# Testing environment specific
95+
derby.log

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# vendoree-samples
2-
Samples for EE related/additional functionality that's specific for a vendor (such as JBoss, Payara, etc)
2+
3+
Samples for EE related/additional functionality that's specific to a vendor (such as JBoss, Payara, etc)

payara/jacc-per-app/pom.xml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.vendoree</groupId>
9+
<artifactId>payara</artifactId>
10+
<version>1.0-SNAPSHOT</version>
11+
</parent>
12+
13+
<artifactId>jacc-per-app</artifactId>
14+
<packaging>war</packaging>
15+
<name>Vendor EE: Payara - Jacc Providers per Application</name>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.omnifaces</groupId>
20+
<artifactId>jacc-provider</artifactId>
21+
<version>0.1</version>
22+
</dependency>
23+
24+
<dependency>
25+
<groupId>fish.payara.api</groupId>
26+
<artifactId>payara-api</artifactId>
27+
<version>5.182-SNAPSHOT</version>
28+
</dependency>
29+
</dependencies>
30+
31+
</project>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/** Copyright Payara Services Limited **/
2+
3+
package org.vendoree.payara.jaccperapp;
4+
5+
import javax.servlet.ServletContext;
6+
import javax.servlet.ServletContextEvent;
7+
import javax.servlet.ServletContextListener;
8+
import javax.servlet.annotation.WebListener;
9+
10+
import org.omnifaces.jaccprovider.TestPolicyConfigurationFactory;
11+
12+
import fish.payara.jacc.JaccConfigurationFactory;
13+
14+
/**
15+
* The core of this sample; installing our own JACC Policy for the current web application.
16+
*
17+
* @author Arjan Tijms
18+
*
19+
*/
20+
@WebListener
21+
public class JaccInstaller implements ServletContextListener {
22+
23+
@Override
24+
public void contextInitialized(ServletContextEvent sce) {
25+
26+
JaccConfigurationFactory.getJaccConfigurationFactory().registerContextProvider(
27+
getAppContextId(sce.getServletContext()),
28+
new TestPolicyConfigurationFactory(),
29+
new LoggingTestPolicy());
30+
31+
}
32+
33+
private String getAppContextId(ServletContext servletContext) {
34+
return servletContext.getVirtualServerName() + " " + servletContext.getContextPath();
35+
}
36+
37+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/** Copyright Payara Services Limited **/
2+
3+
package org.vendoree.payara.jaccperapp;
4+
5+
import java.security.Permission;
6+
import java.security.ProtectionDomain;
7+
import java.util.concurrent.ConcurrentLinkedQueue;
8+
9+
import javax.security.jacc.WebResourcePermission;
10+
import javax.security.jacc.WebRoleRefPermission;
11+
import javax.security.jacc.WebUserDataPermission;
12+
13+
import org.omnifaces.jaccprovider.TestPolicy;
14+
15+
/**
16+
* Test policy used for easy testing that the policy is indeed used.
17+
*
18+
* <p>
19+
* This inherits from {@link TestPolicy}, which comes from an external dependency, and is a standalone JACC policy
20+
* used for testing as well. It implements the default Servlet authorization rules and is compatible with various
21+
* application servers.
22+
*
23+
* @author Arjan Tijms
24+
*
25+
*/
26+
public class LoggingTestPolicy extends TestPolicy {
27+
28+
public static final ConcurrentLinkedQueue<Permission> loggedPermissions = new ConcurrentLinkedQueue<>();
29+
30+
@Override
31+
public boolean implies(ProtectionDomain domain, Permission permission) {
32+
33+
if (permission instanceof WebResourcePermission || permission instanceof WebRoleRefPermission || permission instanceof WebUserDataPermission) {
34+
// Only for test! Don't log like this in an actual application!
35+
loggedPermissions.add(permission);
36+
System.out.println(permission);
37+
}
38+
39+
return super.implies(domain, permission);
40+
}
41+
42+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/** Copyright Payara Services Limited **/
2+
3+
package org.vendoree.payara.jaccperapp;
4+
5+
import java.io.IOException;
6+
import java.security.Permission;
7+
8+
import javax.annotation.security.DeclareRoles;
9+
import javax.servlet.ServletException;
10+
import javax.servlet.annotation.HttpConstraint;
11+
import javax.servlet.annotation.ServletSecurity;
12+
import javax.servlet.annotation.WebServlet;
13+
import javax.servlet.http.HttpServlet;
14+
import javax.servlet.http.HttpServletRequest;
15+
import javax.servlet.http.HttpServletResponse;
16+
17+
/**
18+
* Protected test Servlet printinhg out authentication details and the permissions
19+
* logged by our special test JACC Policy; {@link LoggingTestPolicy}.
20+
*
21+
* <p>
22+
* If the Servlet is accessible and the permission are logged, it's proof that the JACC provider
23+
* we set in {@link JaccInstaller} is used and works.
24+
*
25+
* @author Arjan Tijms
26+
*/
27+
@DeclareRoles({ "a", "b", "c" })
28+
@WebServlet("/protected/servlet")
29+
@ServletSecurity(@HttpConstraint(rolesAllowed = "a"))
30+
public class ProtectedServlet extends HttpServlet {
31+
32+
private static final long serialVersionUID = 1L;
33+
34+
@Override
35+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
36+
37+
response.getWriter().write("This is a protected servlet \n");
38+
39+
String webName = null;
40+
if (request.getUserPrincipal() != null) {
41+
webName = request.getUserPrincipal().getName();
42+
}
43+
44+
response.getWriter().write("web username: " + webName + "\n");
45+
46+
response.getWriter().write("web user has role \"a\": " + request.isUserInRole("a") + "\n");
47+
response.getWriter().write("web user has role \"b\": " + request.isUserInRole("b") + "\n");
48+
response.getWriter().write("web user has role \"c\": " + request.isUserInRole("c") + "\n");
49+
50+
response.getWriter().write("\nLogged permissions: \n");
51+
52+
for (Permission permission : LoggingTestPolicy.loggedPermissions) {
53+
response.getWriter().write(permission + "\n");
54+
}
55+
56+
LoggingTestPolicy.loggedPermissions.clear();
57+
}
58+
59+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/** Copyright Payara Services Limited **/
2+
3+
package org.vendoree.payara.jaccperapp;
4+
5+
import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID;
6+
7+
import javax.enterprise.context.ApplicationScoped;
8+
import javax.inject.Inject;
9+
import javax.security.enterprise.AuthenticationException;
10+
import javax.security.enterprise.AuthenticationStatus;
11+
import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
12+
import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext;
13+
import javax.security.enterprise.credential.UsernamePasswordCredential;
14+
import javax.security.enterprise.identitystore.CredentialValidationResult;
15+
import javax.security.enterprise.identitystore.IdentityStoreHandler;
16+
import javax.servlet.http.HttpServletRequest;
17+
import javax.servlet.http.HttpServletResponse;
18+
19+
20+
/**
21+
* Test authentication mechanism for authenticating with <code>name</code> and <code>password</code>
22+
* request parameters. This only makes sense for testing.
23+
*
24+
* @author Arjan Tijms
25+
*
26+
*/
27+
@ApplicationScoped
28+
public class TestAuthenticationMechanism implements HttpAuthenticationMechanism {
29+
30+
@Inject
31+
private IdentityStoreHandler identityStoreHandler;
32+
33+
@Override
34+
public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException {
35+
36+
if (request.getParameter("name") != null && request.getParameter("password") != null) {
37+
38+
CredentialValidationResult result = identityStoreHandler.validate(
39+
new UsernamePasswordCredential(
40+
request.getParameter("name"),
41+
request.getParameter("password")));
42+
43+
if (result.getStatus() == VALID) {
44+
return httpMessageContext.notifyContainerAboutLogin(
45+
result.getCallerPrincipal(), result.getCallerGroups());
46+
}
47+
48+
return httpMessageContext.responseUnauthorized();
49+
}
50+
51+
return httpMessageContext.doNothing();
52+
}
53+
54+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/** Copyright Payara Services Limited **/
2+
3+
package org.vendoree.payara.jaccperapp;
4+
5+
import static java.util.Arrays.asList;
6+
import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT;
7+
8+
import java.util.HashSet;
9+
10+
import javax.enterprise.context.ApplicationScoped;
11+
import javax.security.enterprise.credential.UsernamePasswordCredential;
12+
import javax.security.enterprise.identitystore.CredentialValidationResult;
13+
import javax.security.enterprise.identitystore.IdentityStore;
14+
15+
/**
16+
* Test identity store that just provides a build-in user with name/password test/secret and roles a and b.
17+
*
18+
* @author Arjan Tijms
19+
*/
20+
@ApplicationScoped
21+
public class TestIdentityStore implements IdentityStore {
22+
23+
public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {
24+
25+
if (usernamePasswordCredential.compareTo("test", "secret")) {
26+
return new CredentialValidationResult("test", new HashSet<>(asList("a", "b")));
27+
}
28+
29+
return INVALID_RESULT;
30+
}
31+
32+
}

0 commit comments

Comments
 (0)