Skip to content

Commit e587749

Browse files
committed
A few JACC related; getting the Request and Subject from the policy
context.
1 parent 714cfe8 commit e587749

14 files changed

+599
-0
lines changed

jacc/contexts/pom.xml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>org.javaee7.jacc</groupId>
8+
<artifactId>jacc-samples</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
<relativePath>../pom.xml</relativePath>
11+
</parent>
12+
13+
<artifactId>contexts</artifactId>
14+
<packaging>war</packaging>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>org.javaee7.jaspic</groupId>
19+
<artifactId>common</artifactId>
20+
<version>1.0-SNAPSHOT</version>
21+
</dependency>
22+
</dependencies>
23+
24+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.javaee7.jacc.contexts.bean;
2+
3+
import javax.ejb.Stateless;
4+
import javax.security.jacc.PolicyContext;
5+
import javax.security.jacc.PolicyContextException;
6+
import javax.servlet.http.HttpServletRequest;
7+
8+
/**
9+
*
10+
* @author Arjan Tijms
11+
*
12+
*/
13+
@Stateless
14+
public class JaccRequestBean {
15+
16+
public HttpServletRequest getRequest() throws PolicyContextException {
17+
return (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
18+
}
19+
20+
public boolean hasAttribute() throws PolicyContextException {
21+
return "true".equals(getRequest().getAttribute("jaccTest"));
22+
}
23+
24+
public boolean hasParameter() throws PolicyContextException {
25+
return "true".equals(getRequest().getParameter("jacc_test"));
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.javaee7.jacc.contexts.sam;
2+
3+
import javax.servlet.ServletContextEvent;
4+
import javax.servlet.annotation.WebListener;
5+
6+
import org.javaee7.jaspic.common.BaseServletContextListener;
7+
import org.javaee7.jaspic.common.JaspicUtils;
8+
9+
/**
10+
*
11+
* @author Arjan Tijms
12+
*
13+
*/
14+
@WebListener
15+
public class SamAutoRegistrationListener extends BaseServletContextListener {
16+
17+
@Override
18+
public void contextInitialized(ServletContextEvent sce) {
19+
JaspicUtils.registerSAM(sce.getServletContext(), new TestServerAuthModule());
20+
}
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.javaee7.jacc.contexts.sam;
2+
3+
import static javax.security.auth.message.AuthStatus.SEND_SUCCESS;
4+
import static javax.security.auth.message.AuthStatus.SUCCESS;
5+
6+
import java.io.IOException;
7+
import java.security.Principal;
8+
import java.util.Map;
9+
10+
import javax.security.auth.Subject;
11+
import javax.security.auth.callback.Callback;
12+
import javax.security.auth.callback.CallbackHandler;
13+
import javax.security.auth.callback.UnsupportedCallbackException;
14+
import javax.security.auth.message.AuthException;
15+
import javax.security.auth.message.AuthStatus;
16+
import javax.security.auth.message.MessageInfo;
17+
import javax.security.auth.message.MessagePolicy;
18+
import javax.security.auth.message.callback.CallerPrincipalCallback;
19+
import javax.security.auth.message.callback.GroupPrincipalCallback;
20+
import javax.security.auth.message.module.ServerAuthModule;
21+
import javax.servlet.http.HttpServletRequest;
22+
import javax.servlet.http.HttpServletResponse;
23+
24+
/**
25+
* Very basic SAM that returns a single hardcoded user named "test" with role "architect" when the request parameter
26+
* <code>doLogin</code> is present.
27+
*
28+
* @author Arjan Tijms
29+
*
30+
*/
31+
public class TestServerAuthModule implements ServerAuthModule {
32+
33+
private CallbackHandler handler;
34+
private Class<?>[] supportedMessageTypes = new Class[] { HttpServletRequest.class, HttpServletResponse.class };
35+
36+
@Override
37+
public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler,
38+
@SuppressWarnings("rawtypes") Map options) throws AuthException {
39+
this.handler = handler;
40+
}
41+
42+
@Override
43+
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
44+
throws AuthException {
45+
46+
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
47+
48+
Callback[] callbacks;
49+
50+
if (request.getParameter("doLogin") != null) {
51+
52+
// For the test perform a login by directly "returning" the details of the authenticated user.
53+
// Normally credentials would be checked and the details fetched from some repository
54+
55+
callbacks = new Callback[] {
56+
// The name of the authenticated user
57+
new CallerPrincipalCallback(clientSubject, "test"),
58+
// the roles of the authenticated user
59+
new GroupPrincipalCallback(clientSubject, new String[] { "architect" })
60+
};
61+
} else {
62+
63+
// The JASPIC protocol for "do nothing"
64+
callbacks = new Callback[] { new CallerPrincipalCallback(clientSubject, (Principal) null) };
65+
}
66+
67+
try {
68+
69+
// Communicate the details of the authenticated user to the container. In many
70+
// cases the handler will just store the details and the container will actually handle
71+
// the login after we return from this method.
72+
handler.handle(callbacks);
73+
74+
} catch (IOException | UnsupportedCallbackException e) {
75+
throw (AuthException) new AuthException().initCause(e);
76+
}
77+
78+
return SUCCESS;
79+
}
80+
81+
@Override
82+
public Class<?>[] getSupportedMessageTypes() {
83+
return supportedMessageTypes;
84+
}
85+
86+
@Override
87+
public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException {
88+
return SEND_SUCCESS;
89+
}
90+
91+
@Override
92+
public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException {
93+
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.javaee7.jacc.contexts.servlet;
2+
3+
import java.io.IOException;
4+
5+
import javax.security.jacc.PolicyContext;
6+
import javax.security.jacc.PolicyContextException;
7+
import javax.servlet.ServletException;
8+
import javax.servlet.annotation.WebServlet;
9+
import javax.servlet.http.HttpServlet;
10+
import javax.servlet.http.HttpServletRequest;
11+
import javax.servlet.http.HttpServletResponse;
12+
13+
/**
14+
*
15+
* @author Arjan Tijms
16+
*
17+
*/
18+
@WebServlet(urlPatterns = "/requestServlet")
19+
public class RequestServlet extends HttpServlet {
20+
21+
private static final long serialVersionUID = 1L;
22+
23+
@Override
24+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25+
26+
request.setAttribute("jaccTest", "true");
27+
28+
try {
29+
HttpServletRequest requestFromPolicy = (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
30+
31+
if (requestFromPolicy != null) {
32+
response.getWriter().print("Obtained request from context.");
33+
34+
if ("true".equals(requestFromPolicy.getAttribute("jaccTest"))) {
35+
response.getWriter().print("Attribute present in request from context.");
36+
}
37+
38+
if ("true".equals(requestFromPolicy.getParameter("jacc_test"))) {
39+
response.getWriter().print("Request parameter present in request from context.");
40+
}
41+
42+
}
43+
} catch (PolicyContextException e) {
44+
e.printStackTrace(response.getWriter());
45+
}
46+
47+
}
48+
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.javaee7.jacc.contexts.servlet;
2+
3+
import java.io.IOException;
4+
5+
import javax.inject.Inject;
6+
import javax.security.jacc.PolicyContextException;
7+
import javax.servlet.ServletException;
8+
import javax.servlet.annotation.WebServlet;
9+
import javax.servlet.http.HttpServlet;
10+
import javax.servlet.http.HttpServletRequest;
11+
import javax.servlet.http.HttpServletResponse;
12+
13+
import org.javaee7.jacc.contexts.bean.JaccRequestBean;
14+
15+
/**
16+
*
17+
* @author Arjan Tijms
18+
*
19+
*/
20+
@WebServlet(urlPatterns = "/requestServletEJB")
21+
public class RequestServletEJB extends HttpServlet {
22+
23+
private static final long serialVersionUID = 1L;
24+
25+
@Inject
26+
private JaccRequestBean jaccRequestBean;
27+
28+
@Override
29+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
30+
31+
request.setAttribute("jaccTest", "true");
32+
33+
try {
34+
if (jaccRequestBean.getRequest() != null) {
35+
response.getWriter().print("Obtained request from context.");
36+
37+
if (jaccRequestBean.hasAttribute()) {
38+
response.getWriter().print("Attribute present in request from context.");
39+
}
40+
41+
if (jaccRequestBean.hasParameter()) {
42+
response.getWriter().print("Request parameter present in request from context.");
43+
}
44+
45+
}
46+
} catch (PolicyContextException e) {
47+
e.printStackTrace(response.getWriter());
48+
}
49+
50+
}
51+
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package org.javaee7.jacc.contexts.servlet;
2+
3+
import static java.security.Policy.getPolicy;
4+
import static java.util.Collections.list;
5+
6+
import java.io.IOException;
7+
import java.security.CodeSource;
8+
import java.security.Permission;
9+
import java.security.PermissionCollection;
10+
import java.security.Principal;
11+
import java.security.ProtectionDomain;
12+
import java.security.cert.Certificate;
13+
import java.util.HashSet;
14+
import java.util.Set;
15+
16+
import javax.security.auth.Subject;
17+
import javax.security.jacc.PolicyContext;
18+
import javax.security.jacc.PolicyContextException;
19+
import javax.security.jacc.WebRoleRefPermission;
20+
import javax.servlet.ServletException;
21+
import javax.servlet.annotation.WebServlet;
22+
import javax.servlet.http.HttpServlet;
23+
import javax.servlet.http.HttpServletRequest;
24+
import javax.servlet.http.HttpServletResponse;
25+
26+
/**
27+
* This Servlet demonstrates both how to obtain the Subject and then how to retrieve the roles from
28+
* this Subject.
29+
*
30+
* @author Arjan Tijms
31+
*
32+
*/
33+
@WebServlet(urlPatterns = "/subjectServlet")
34+
public class SubjectServlet extends HttpServlet {
35+
36+
private static final long serialVersionUID = 1L;
37+
38+
@Override
39+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
40+
41+
try {
42+
Subject subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
43+
44+
if (subject != null) {
45+
response.getWriter().print("Obtained subject from context.\n");
46+
47+
// Get the permissions associated with the Subject we obtained
48+
PermissionCollection permissionCollection = getPermissionCollection(subject);
49+
50+
// Resolve any potentially unresolved permissions
51+
permissionCollection.implies(new WebRoleRefPermission("", "nothing"));
52+
53+
// Filter just the roles from all the permissions, which may include things like
54+
// java.net.SocketPermission, java.io.FilePermission, and obtain the actual role names.
55+
Set<String> roles = filterRoles(request, permissionCollection);
56+
57+
for (String role : roles) {
58+
response.getWriter().print("User has role " + role + "\n");
59+
}
60+
}
61+
} catch (PolicyContextException e) {
62+
e.printStackTrace(response.getWriter());
63+
}
64+
}
65+
66+
private PermissionCollection getPermissionCollection(Subject subject) {
67+
return getPolicy().getPermissions(
68+
new ProtectionDomain(
69+
new CodeSource(null, (Certificate[]) null),
70+
null, null,
71+
subject.getPrincipals().toArray(new Principal[subject.getPrincipals().size()])
72+
)
73+
);
74+
}
75+
76+
private Set<String> filterRoles(HttpServletRequest request, PermissionCollection permissionCollection) {
77+
Set<String> roles = new HashSet<>();
78+
for (Permission permission : list(permissionCollection.elements())) {
79+
if (permission instanceof WebRoleRefPermission) {
80+
String role = permission.getActions();
81+
82+
// Note that the WebRoleRefPermission is given for every Servlet in the application, even when
83+
// no role refs are used anywhere. This will also include Servlets like the default servlet and the
84+
// implicit JSP servlet. So if there are 2 application roles, and 3 application servlets, then
85+
// at least 6 WebRoleRefPermission elements will be present in the collection.
86+
if (!roles.contains(role) && request.isUserInRole(role)) {
87+
roles.add(role);
88+
}
89+
}
90+
}
91+
92+
return roles;
93+
}
94+
95+
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
3+
<glassfish-web-app>
4+
5+
<security-role-mapping>
6+
<role-name>architect</role-name>
7+
<group-name>architect</group-name>
8+
</security-role-mapping>
9+
10+
<parameter-encoding default-charset="UTF-8" />
11+
12+
</glassfish-web-app>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0"?>
2+
3+
<jboss-web>
4+
<security-domain>jaspitest</security-domain>
5+
</jboss-web>

0 commit comments

Comments
 (0)