Merge pull request #7546 from eclipse/jetty-10.0.x-7545-OpenIdXML

Add distribution test for OpenID and fix issues with jetty-openid.xml
This commit is contained in:
Lachlan 2022-02-17 09:54:43 +11:00 committed by GitHub
commit 0f5824640a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 776 additions and 2 deletions

View File

@ -24,6 +24,7 @@ import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.util.ajax.JSON;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.slf4j.Logger;
@ -86,8 +87,13 @@ public class OpenIdConfiguration extends ContainerLifeCycle
* @param authMethod Authentication method to use with the Token Endpoint.
* @param httpClient The {@link HttpClient} instance to use.
*/
public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint,
String clientId, String clientSecret, String authMethod, HttpClient httpClient)
public OpenIdConfiguration(@Name("issuer") String issuer,
@Name("authorizationEndpoint") String authorizationEndpoint,
@Name("tokenEndpoint") String tokenEndpoint,
@Name("clientId") String clientId,
@Name("clientSecret") String clientSecret,
@Name("authMethod") String authMethod,
@Name("httpClient") HttpClient httpClient)
{
this.issuer = issuer;
this.clientId = clientId;

View File

@ -149,6 +149,11 @@
<artifactId>websocket-jetty-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-openid</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-felix-webapp</artifactId>

View File

@ -41,6 +41,7 @@ import org.eclipse.jetty.http3.client.HTTP3Client;
import org.eclipse.jetty.http3.client.http.HttpClientTransportOverHTTP3;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.start.FS;
import org.eclipse.jetty.tests.distribution.openid.OpenIdProvider;
import org.eclipse.jetty.toolchain.test.PathAssert;
import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets;
import org.eclipse.jetty.unixsocket.server.UnixSocketConnector;
@ -1143,4 +1144,89 @@ public class DistributionTests extends AbstractJettyHomeTest
}
}
}
@Test
public void testOpenID() throws Exception
{
Path jettyBase = newTestJettyBaseDirectory();
String jettyVersion = System.getProperty("jettyVersion");
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
.jettyVersion(jettyVersion)
.jettyBase(jettyBase)
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
.build();
String[] args1 = {
"--create-startd",
"--approve-all-licenses",
"--add-to-start=http,webapp,deploy,openid"
};
String clientId = "clientId123";
String clientSecret = "clientSecret456";
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
try (JettyHomeTester.Run run1 = distribution.start(args1))
{
assertTrue(run1.awaitFor(10, TimeUnit.SECONDS));
assertEquals(0, run1.getExitValue());
File webApp = distribution.resolveArtifact("org.eclipse.jetty.tests:test-openid-webapp:war:" + jettyVersion);
distribution.installWarFile(webApp, "test");
int port = distribution.freePort();
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
openIdProvider.start();
String[] args2 = {
"jetty.http.port=" + port,
"jetty.ssl.port=" + port,
"jetty.openid.provider=" + openIdProvider.getProvider(),
"jetty.openid.clientId=" + clientId,
"jetty.openid.clientSecret=" + clientSecret,
//"jetty.server.dumpAfterStart=true",
};
try (JettyHomeTester.Run run2 = distribution.start(args2))
{
assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS));
startHttpClient(false);
String uri = "http://localhost:" + port + "/test";
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
// Initially not authenticated
ContentResponse response = client.GET(uri + "/");
assertThat(response.getStatus(), is(HttpStatus.OK_200));
String content = response.getContentAsString();
assertThat(content, containsString("not authenticated"));
// Request to login is success
response = client.GET(uri + "/login");
assertThat(response.getStatus(), is(HttpStatus.OK_200));
content = response.getContentAsString();
assertThat(content, containsString("success"));
// Now authenticated we can get info
response = client.GET(uri + "/");
assertThat(response.getStatus(), is(HttpStatus.OK_200));
content = response.getContentAsString();
assertThat(content, containsString("userId: 123456789"));
assertThat(content, containsString("name: Alice"));
assertThat(content, containsString("email: Alice@example.com"));
// Request to admin page gives 403 as we do not have admin role
response = client.GET(uri + "/admin");
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
// We are no longer authenticated after logging out
response = client.GET(uri + "/logout");
assertThat(response.getStatus(), is(HttpStatus.OK_200));
content = response.getContentAsString();
assertThat(content, containsString("not authenticated"));
}
}
finally
{
openIdProvider.stop();
}
}
}

View File

@ -0,0 +1,53 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.tests.distribution.openid;
import java.util.Base64;
/**
* A basic JWT encoder for testing purposes.
*/
public class JwtEncoder
{
private static final Base64.Encoder ENCODER = Base64.getUrlEncoder();
private static final String DEFAULT_HEADER = "{\"INFO\": \"this is not used or checked in our implementation\"}";
private static final String DEFAULT_SIGNATURE = "we do not validate signature as we use the authorization code flow";
public static String encode(String idToken)
{
return stripPadding(ENCODER.encodeToString(DEFAULT_HEADER.getBytes())) + "." +
stripPadding(ENCODER.encodeToString(idToken.getBytes())) + "." +
stripPadding(ENCODER.encodeToString(DEFAULT_SIGNATURE.getBytes()));
}
private static String stripPadding(String paddedBase64)
{
return paddedBase64.split("=")[0];
}
/**
* Create a basic JWT for testing using argument supplied attributes.
*/
public static String createIdToken(String provider, String clientId, String subject, String name, long expiry)
{
return "{" +
"\"iss\": \"" + provider + "\"," +
"\"sub\": \"" + subject + "\"," +
"\"aud\": \"" + clientId + "\"," +
"\"exp\": " + expiry + "," +
"\"name\": \"" + name + "\"," +
"\"email\": \"" + name + "@example.com" + "\"" +
"}";
}
}

View File

@ -0,0 +1,341 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.tests.distribution.openid;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.security.openid.OpenIdConfiguration;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OpenIdProvider extends ContainerLifeCycle
{
private static final Logger LOG = LoggerFactory.getLogger(OpenIdProvider.class);
private static final String CONFIG_PATH = "/.well-known/openid-configuration";
private static final String AUTH_PATH = "/auth";
private static final String TOKEN_PATH = "/token";
private final Map<String, User> issuedAuthCodes = new HashMap<>();
protected final String clientId;
protected final String clientSecret;
protected final List<String> redirectUris = new ArrayList<>();
private final ServerConnector connector;
private final Server server;
private int port = 0;
private String provider;
private User preAuthedUser;
public static void main(String[] args) throws Exception
{
String clientId = "CLIENT_ID123";
String clientSecret = "PASSWORD123";
int port = 5771;
String redirectUri = "http://localhost:8080/openid/auth";
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
openIdProvider.addRedirectUri(redirectUri);
openIdProvider.setPort(port);
openIdProvider.start();
try
{
openIdProvider.join();
}
finally
{
openIdProvider.stop();
}
}
public OpenIdProvider(String clientId, String clientSecret)
{
this.clientId = clientId;
this.clientSecret = clientSecret;
server = new Server();
connector = new ServerConnector(server);
server.addConnector(connector);
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setContextPath("/");
contextHandler.addServlet(new ServletHolder(new OpenIdConfigServlet()), CONFIG_PATH);
contextHandler.addServlet(new ServletHolder(new OpenIdAuthEndpoint()), AUTH_PATH);
contextHandler.addServlet(new ServletHolder(new OpenIdTokenEndpoint()), TOKEN_PATH);
server.setHandler(contextHandler);
addBean(server);
}
public void join() throws InterruptedException
{
server.join();
}
public OpenIdConfiguration getOpenIdConfiguration()
{
String provider = getProvider();
String authEndpoint = provider + AUTH_PATH;
String tokenEndpoint = provider + TOKEN_PATH;
return new OpenIdConfiguration(provider, authEndpoint, tokenEndpoint, clientId, clientSecret, null);
}
@Override
protected void doStart() throws Exception
{
connector.setPort(port);
super.doStart();
provider = "http://localhost:" + connector.getLocalPort();
}
public void setPort(int port)
{
if (isStarted())
throw new IllegalStateException();
this.port = port;
}
public void setUser(User user)
{
this.preAuthedUser = user;
}
public String getProvider()
{
if (!isStarted() && port == 0)
throw new IllegalStateException("Port of OpenIdProvider not configured");
return provider;
}
public void addRedirectUri(String uri)
{
redirectUris.add(uri);
}
public class OpenIdAuthEndpoint extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
if (!clientId.equals(req.getParameter("client_id")))
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid client_id");
return;
}
String redirectUri = req.getParameter("redirect_uri");
if (!redirectUris.contains(redirectUri))
{
LOG.warn("invalid redirectUri {}", redirectUri);
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri");
return;
}
String scopeString = req.getParameter("scope");
List<String> scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(StringUtil.csvSplit(scopeString));
if (!scopes.contains("openid"))
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no openid scope");
return;
}
if (!"code".equals(req.getParameter("response_type")))
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "response_type must be code");
return;
}
String state = req.getParameter("state");
if (state == null)
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param");
return;
}
if (preAuthedUser == null)
{
PrintWriter writer = resp.getWriter();
resp.setContentType("text/html");
writer.println("<h2>Login to OpenID Connect Provider</h2>");
writer.println("<form action=\"" + AUTH_PATH + "\" method=\"post\">");
writer.println("<input type=\"text\" autocomplete=\"off\" placeholder=\"Username\" name=\"username\" required>");
writer.println("<input type=\"hidden\" name=\"redirectUri\" value=\"" + redirectUri + "\">");
writer.println("<input type=\"hidden\" name=\"state\" value=\"" + state + "\">");
writer.println("<input type=\"submit\">");
writer.println("</form>");
}
else
{
redirectUser(req, preAuthedUser, redirectUri, state);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
String redirectUri = req.getParameter("redirectUri");
if (!redirectUris.contains(redirectUri))
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri");
return;
}
String state = req.getParameter("state");
if (state == null)
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param");
return;
}
String username = req.getParameter("username");
if (username == null)
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no username");
return;
}
User user = new User(username);
redirectUser(req, user, redirectUri, state);
}
public void redirectUser(HttpServletRequest request, User user, String redirectUri, String state) throws IOException
{
String authCode = UUID.randomUUID().toString().replace("-", "");
issuedAuthCodes.put(authCode, user);
try
{
final Request baseRequest = Objects.requireNonNull(Request.getBaseRequest(request));
final Response baseResponse = baseRequest.getResponse();
redirectUri += "?code=" + authCode + "&state=" + state;
int redirectCode = (baseRequest.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion()
? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER);
baseResponse.sendRedirect(redirectCode, baseResponse.encodeRedirectURL(redirectUri));
}
catch (Throwable t)
{
issuedAuthCodes.remove(authCode);
throw t;
}
}
}
public class OpenIdTokenEndpoint extends HttpServlet
{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
String code = req.getParameter("code");
if (!clientId.equals(req.getParameter("client_id")) ||
!clientSecret.equals(req.getParameter("client_secret")) ||
!redirectUris.contains(req.getParameter("redirect_uri")) ||
!"authorization_code".equals(req.getParameter("grant_type")) ||
code == null)
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "bad auth request");
return;
}
User user = issuedAuthCodes.remove(code);
if (user == null)
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid auth code");
return;
}
String accessToken = "ABCDEFG";
long expiry = System.currentTimeMillis() + Duration.ofMinutes(10).toMillis();
String response = "{" +
"\"access_token\": \"" + accessToken + "\"," +
"\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId)) + "\"," +
"\"expires_in\": " + expiry + "," +
"\"token_type\": \"Bearer\"" +
"}";
resp.setContentType("text/plain");
resp.getWriter().print(response);
}
}
public class OpenIdConfigServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
String discoveryDocument = "{" +
"\"issuer\": \"" + provider + "\"," +
"\"authorization_endpoint\": \"" + provider + AUTH_PATH + "\"," +
"\"token_endpoint\": \"" + provider + TOKEN_PATH + "\"," +
"}";
resp.getWriter().write(discoveryDocument);
}
}
public static class User
{
private final String subject;
private final String name;
public User(String name)
{
this(UUID.nameUUIDFromBytes(name.getBytes()).toString(), name);
}
public User(String subject, String name)
{
this.subject = subject;
this.name = name;
}
public String getName()
{
return name;
}
public String getSubject()
{
return subject;
}
public String getIdToken(String provider, String clientId)
{
long expiry = System.currentTimeMillis() + Duration.ofMinutes(1).toMillis();
return JwtEncoder.createIdToken(provider, clientId, subject, name, expiry);
}
}
}

View File

@ -41,5 +41,6 @@
<module>test-bad-websocket-webapp</module>
<module>test-websocket-client-webapp</module>
<module>test-websocket-client-provided-webapp</module>
<module>test-openid-webapp</module>
</modules>
</project>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-webapps-parent</artifactId>
<version>10.0.9-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-openid-webapp</artifactId>
<packaging>war</packaging>
<name>Test :: Jetty OpenId Webapp</name>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-slf4j-impl</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,31 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.test.openid;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AdminPage extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
@SuppressWarnings("unchecked")
Map<String, Object> userInfo = (Map<String, Object>)request.getSession().getAttribute("org.eclipse.jetty.security.openid.claims");
response.getWriter().println(userInfo.get("sub") + ": success");
}
}

View File

@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.test.openid;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ErrorPage extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
response.setContentType("text/html");
response.getWriter().println("not authorized");
response.getWriter().println("<br><a href=\"" + request.getContextPath() + "\">Home</a>");
}
}

View File

@ -0,0 +1,45 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.test.openid;
import java.io.IOException;
import java.security.Principal;
import java.util.Map;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HomePage extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
response.setContentType("text/html");
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null)
{
@SuppressWarnings("unchecked")
Map<String, Object> userInfo = (Map<String, Object>)request.getSession().getAttribute("org.eclipse.jetty.security.openid.claims");
response.getWriter().println("userId: " + userInfo.get("sub") + "<br>");
response.getWriter().println("name: " + userInfo.get("name") + "<br>");
response.getWriter().println("email: " + userInfo.get("email") + "<br>");
response.getWriter().println("<br><a href=\"" + request.getContextPath() + "/logout\">Logout</a>");
}
else
{
response.getWriter().println("not authenticated");
response.getWriter().println("<br><a href=\"" + request.getContextPath() + "/login\">Login</a>");
}
}
}

View File

@ -0,0 +1,30 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.test.openid;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginPage extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
response.setContentType("text/html");
response.getWriter().println("success");
response.getWriter().println("<br><a href=\"" + request.getContextPath() + "\">Home</a>");
}
}

View File

@ -0,0 +1,29 @@
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.test.openid;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogoutPage extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
request.getSession().invalidate();
response.sendRedirect(request.getContextPath());
}
}

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="false"
version="3.1">
<login-config>
<auth-method>OPENID</auth-method>
</login-config>
<servlet>
<servlet-name>AdminPage</servlet-name>
<servlet-class>org.eclipse.jetty.test.openid.AdminPage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AdminPage</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ErrorPage</servlet-name>
<servlet-class>org.eclipse.jetty.test.openid.ErrorPage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorPage</servlet-name>
<url-pattern>/error</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HomePage</servlet-name>
<servlet-class>org.eclipse.jetty.test.openid.HomePage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HomePage</servlet-name>
<url-pattern/>
</servlet-mapping>
<servlet>
<servlet-name>LoginPage</servlet-name>
<servlet-class>org.eclipse.jetty.test.openid.LoginPage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginPage</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutPage</servlet-name>
<servlet-class>org.eclipse.jetty.test.openid.LogoutPage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutPage</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>**</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>User Pages</web-resource-name>
<url-pattern>/profile</url-pattern>
<url-pattern>/login</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>**</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Admin Page</web-resource-name>
<url-pattern>/admin</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
</web-app>