Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit e482ba6

Browse files
committed
EDR1 work in progress proposal and demo apps for EDR1 code.
1 parent 066d370 commit e482ba6

109 files changed

Lines changed: 6493 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/app-custom-rememberme/pom.xml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
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>net.java.jsr375</groupId>
8+
<artifactId>apps</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>app-custom-rememberme</artifactId>
13+
14+
<packaging>war</packaging>
15+
16+
<build>
17+
<finalName>app-custom-rememberme</finalName>
18+
19+
<plugins>
20+
<plugin>
21+
<artifactId>maven-compiler-plugin</artifactId>
22+
<version>3.3</version>
23+
<configuration>
24+
<source>1.8</source>
25+
<target>1.8</target>
26+
</configuration>
27+
</plugin>
28+
<plugin>
29+
<artifactId>maven-war-plugin</artifactId>
30+
<version>2.6</version>
31+
<configuration>
32+
<warName>app-custom-rememberme</warName>
33+
<failOnMissingWebXml>false</failOnMissingWebXml>
34+
</configuration>
35+
</plugin>
36+
</plugins>
37+
</build>
38+
</project>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package test;
2+
3+
import java.io.IOException;
4+
5+
import javax.annotation.security.DeclareRoles;
6+
import javax.servlet.ServletException;
7+
import javax.servlet.annotation.WebServlet;
8+
import javax.servlet.http.HttpServlet;
9+
import javax.servlet.http.HttpServletRequest;
10+
import javax.servlet.http.HttpServletResponse;
11+
12+
/**
13+
* Test Servlet that prints out the name of the authenticated caller and whether
14+
* this caller is in any of the roles {foo, bar, kaz}
15+
*
16+
*
17+
*/
18+
@DeclareRoles({ "foo", "bar", "kaz" })
19+
@WebServlet("/servlet")
20+
public class Servlet extends HttpServlet {
21+
22+
private static final long serialVersionUID = 1L;
23+
24+
@Override
25+
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
26+
27+
if (request.getParameter("logout") != null) {
28+
request.logout(); // slightly ill-defined, but only for current request
29+
request.getSession().invalidate();
30+
}
31+
32+
response.getWriter().write("This is a servlet \n");
33+
34+
String webName = null;
35+
if (request.getUserPrincipal() != null) {
36+
webName = request.getUserPrincipal().getName();
37+
}
38+
39+
response.getWriter().write("web username: " + webName + "\n");
40+
41+
response.getWriter().write("web user has role \"foo\": " + request.isUserInRole("foo") + "\n");
42+
response.getWriter().write("web user has role \"bar\": " + request.isUserInRole("bar") + "\n");
43+
response.getWriter().write("web user has role \"kaz\": " + request.isUserInRole("kaz") + "\n");
44+
45+
String mechanismCalled = (String) request.getAttribute("authentication-mechanism-called");
46+
47+
response.getWriter().write("\nauthentication mechanism called: " + (mechanismCalled != null? mechanismCalled : false) + "\n");
48+
}
49+
50+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package test;
2+
3+
import static javax.security.identitystore.CredentialValidationResult.Status.VALID;
4+
5+
import javax.enterprise.context.RequestScoped;
6+
import javax.inject.Inject;
7+
import javax.security.auth.message.AuthException;
8+
import javax.security.auth.message.AuthStatus;
9+
import javax.security.authentication.mechanism.http.HttpAuthenticationMechanism;
10+
import javax.security.authentication.mechanism.http.HttpMessageContext;
11+
import javax.security.authentication.mechanism.http.annotation.RememberMe;
12+
import javax.security.identitystore.CredentialValidationResult;
13+
import javax.security.identitystore.IdentityStore;
14+
import javax.security.identitystore.credential.Password;
15+
import javax.security.identitystore.credential.UsernamePasswordCredential;
16+
import javax.servlet.http.HttpServletRequest;
17+
import javax.servlet.http.HttpServletResponse;
18+
19+
@RememberMe(
20+
cookieMaxAgeSeconds = 3600,
21+
isRememberMeExpression ="this.isRememberMe(httpMessageContext)"
22+
)
23+
@RequestScoped
24+
public class TestAuthenticationMechanism implements HttpAuthenticationMechanism {
25+
26+
@Inject
27+
private IdentityStore identityStore;
28+
29+
@Override
30+
public AuthStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthException {
31+
32+
request.setAttribute("authentication-mechanism-called", "true");
33+
34+
if (request.getParameter("name") != null && request.getParameter("password") != null) {
35+
36+
// Get the (caller) name and password from the request
37+
// NOTE: This is for the smallest possible example only. In practice
38+
// putting the password in a request query parameter is highly
39+
// insecure
40+
String name = request.getParameter("name");
41+
Password password = new Password(request.getParameter("password"));
42+
43+
// Delegate the {credentials in -> identity data out} function to
44+
// the Identity Store
45+
CredentialValidationResult result = identityStore.validate(
46+
new UsernamePasswordCredential(name, password));
47+
48+
if (result.getStatus() == VALID) {
49+
// Communicate the details of the authenticated user to the
50+
// container. In many cases the underlying handler will just store the details
51+
// and the container will actually handle the login after we return from
52+
// this method.
53+
return httpMessageContext.notifyContainerAboutLogin(
54+
result.getCallerPrincipal(), result.getCallerGroups());
55+
} else {
56+
throw new AuthException("Login failed");
57+
}
58+
}
59+
60+
return httpMessageContext.doNothing();
61+
}
62+
63+
public Boolean isRememberMe(HttpMessageContext httpMessageContext) {
64+
return httpMessageContext.getRequest().getParameter("rememberme") != null;
65+
}
66+
67+
// Workaround for possible CDI bug; at least in Weld 2.3.2 default methods don't seem to be intercepted
68+
@Override
69+
public void cleanSubject(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) {
70+
HttpAuthenticationMechanism.super.cleanSubject(request, response, httpMessageContext);
71+
}
72+
73+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package test;
2+
3+
import static java.util.Arrays.asList;
4+
import static javax.security.identitystore.CredentialValidationResult.INVALID_RESULT;
5+
import static javax.security.identitystore.CredentialValidationResult.NOT_VALIDATED_RESULT;
6+
import static javax.security.identitystore.CredentialValidationResult.Status.VALID;
7+
8+
import javax.enterprise.context.RequestScoped;
9+
import javax.security.CallerPrincipal;
10+
import javax.security.identitystore.CredentialValidationResult;
11+
import javax.security.identitystore.IdentityStore;
12+
import javax.security.identitystore.credential.Credential;
13+
import javax.security.identitystore.credential.UsernamePasswordCredential;
14+
15+
@RequestScoped
16+
public class TestIdentityStore implements IdentityStore {
17+
18+
public CredentialValidationResult validate(Credential credential) {
19+
if (credential instanceof UsernamePasswordCredential) {
20+
return validate((UsernamePasswordCredential) credential);
21+
}
22+
23+
return NOT_VALIDATED_RESULT;
24+
}
25+
26+
public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {
27+
28+
if (usernamePasswordCredential.getCaller().equals("reza") &&
29+
usernamePasswordCredential.getPassword().compareTo("secret1")) {
30+
31+
return new CredentialValidationResult(
32+
VALID,
33+
new CallerPrincipal("reza"),
34+
asList("foo", "bar")
35+
);
36+
}
37+
38+
return INVALID_RESULT;
39+
}
40+
41+
42+
43+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package test;
2+
3+
import static javax.security.identitystore.CredentialValidationResult.INVALID_RESULT;
4+
import static javax.security.identitystore.CredentialValidationResult.Status.VALID;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.UUID;
9+
import java.util.concurrent.ConcurrentHashMap;
10+
11+
import javax.enterprise.context.ApplicationScoped;
12+
import javax.security.CallerPrincipal;
13+
import javax.security.identitystore.CredentialValidationResult;
14+
import javax.security.identitystore.RememberMeIdentityStore;
15+
import javax.security.identitystore.credential.RememberMeCredential;
16+
17+
@ApplicationScoped
18+
public class TestRememberMeIdentityStore implements RememberMeIdentityStore {
19+
20+
private final Map<String, CredentialValidationResult> identities = new ConcurrentHashMap<>();
21+
22+
@Override
23+
public CredentialValidationResult validate(RememberMeCredential credential) {
24+
if (identities.containsKey(credential.getToken())) {
25+
return identities.get(credential.getToken());
26+
}
27+
28+
return INVALID_RESULT;
29+
}
30+
31+
@Override
32+
public String generateLoginToken(CallerPrincipal callerPrincipal, List<String> groups) {
33+
String token = UUID.randomUUID().toString();
34+
35+
// NOTE: FOR EXAMPLE ONLY. AS TOKENKEY WOULD EFFECTIVELY BECOME THE REPLACEMENT PASSWORD
36+
// IT SHOULD NORMALLY NOT BE STORED DIRECTLY BUT EG USING STRONG HASHING
37+
identities.put(token, new CredentialValidationResult(VALID, callerPrincipal, groups));
38+
39+
return token;
40+
}
41+
42+
@Override
43+
public void removeLoginToken(String token) {
44+
identities.remove(token);
45+
}
46+
47+
}

apps/app-custom-rememberme/src/main/resources/empty.txt

Whitespace-only changes.

apps/app-custom-rememberme/src/main/webapp/WEB-INF/beans.xml

Whitespace-only changes.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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>foo</role-name>
7+
<group-name>foo</group-name>
8+
</security-role-mapping>
9+
10+
<security-role-mapping>
11+
<role-name>bar</role-name>
12+
<group-name>bar</group-name>
13+
</security-role-mapping>
14+
15+
<security-role-mapping>
16+
<role-name>kaz</role-name>
17+
<group-name>kaz</group-name>
18+
</security-role-mapping>
19+
20+
<parameter-encoding default-charset="UTF-8" />
21+
22+
</glassfish-web-app>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<application-bnd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-application-bnd_1_2.xsd"
4+
xmlns="http://websphere.ibm.com/xml/ns/javaee"
5+
version="1.2">
6+
7+
<security-role name="foo">
8+
<group name="foo" />
9+
</security-role>
10+
11+
<security-role name="bar">
12+
<group name="bar" />
13+
</security-role>
14+
15+
<security-role name="kaz">
16+
<group name="kaz" />
17+
</security-role>
18+
19+
20+
</application-bnd>
Lines changed: 5 additions & 0 deletions
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)