-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #11560 - Implement EIP-4361 Sign-In With Ethereum #11883
Closed
Closed
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
436ca41
Issue #11560 - Implement EIP-4361 Sign-In With Ethereum
lachlan-roberts 90e5919
PR #11883 - javadoc and code cleanup
lachlan-roberts ac5925a
PR #11883 - test fixes and cleanup
lachlan-roberts 70e6192
PR #11883 - fixes to EthereumCredentials
lachlan-roberts 614025a
Add openid and siwe documentation sections.
lachlan-roberts 4006228
Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-…
lachlan-roberts 225e89c
update version for jetty-siwe pom.xml
lachlan-roberts aa945d5
add jetty module for siwe
lachlan-roberts 52c6c88
add siwe.mod, distribution tests and documentation
lachlan-roberts 9ea7431
changes from review
lachlan-roberts 32b7043
add javadoc for test classes
lachlan-roberts 2f66835
PR #11883 - changes from review
lachlan-roberts 44286fe
PR #11883 - changes from review
lachlan-roberts f1f1602
PR #11883 - changes from review
lachlan-roberts 9581ef1
Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-…
lachlan-roberts 37af005
Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-…
lachlan-roberts cc61f78
update poms to 12.0.13-SNAPSHOT
lachlan-roberts a525b70
Move SignInWithEthereumEmbeddedExample to code-examples in documentation
lachlan-roberts 063e3fc
PR #11883 - fix build issue with poms
lachlan-roberts 37aed0e
PR #11883 - remove experimental warning and fix to documentation
lachlan-roberts b07a8c0
Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.0.x-…
lachlan-roberts File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
...es/src/main/java/org/eclipse/jetty/docs/programming/security/siwe/SignInWithEthereum.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// | ||
// ======================================================================== | ||
// Copyright (c) 1995 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.security.siwe.example; | ||
|
||
import java.io.PrintWriter; | ||
import java.nio.file.Paths; | ||
import java.util.Objects; | ||
|
||
import org.eclipse.jetty.http.HttpHeader; | ||
import org.eclipse.jetty.io.Content; | ||
import org.eclipse.jetty.security.AuthenticationState; | ||
import org.eclipse.jetty.security.Constraint; | ||
import org.eclipse.jetty.security.SecurityHandler; | ||
import org.eclipse.jetty.security.siwe.EthereumAuthenticator; | ||
import org.eclipse.jetty.server.Handler; | ||
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.server.handler.ContextHandler; | ||
import org.eclipse.jetty.server.handler.ResourceHandler; | ||
import org.eclipse.jetty.session.SessionHandler; | ||
import org.eclipse.jetty.util.Callback; | ||
|
||
public class SignInWithEthereum | ||
{ | ||
public static SecurityHandler createSecurityHandler(Handler handler) | ||
{ | ||
// tag::configureSecurityHandler[] | ||
// This uses jetty-core, but you can configure a ConstraintSecurityHandler for use with EE10. | ||
SecurityHandler.PathMapped securityHandler = new SecurityHandler.PathMapped(); | ||
securityHandler.setHandler(handler); | ||
securityHandler.put("/*", Constraint.ANY_USER); | ||
|
||
// Add the EthereumAuthenticator to the securityHandler. | ||
EthereumAuthenticator authenticator = new EthereumAuthenticator(); | ||
securityHandler.setAuthenticator(authenticator); | ||
|
||
// In embedded you can configure via EthereumAuthenticator APIs. | ||
authenticator.setLoginPath("/login.html"); | ||
|
||
// Or you can configure with parameters on the SecurityHandler. | ||
securityHandler.setParameter(EthereumAuthenticator.LOGIN_PATH_PARAM, "/login.html"); | ||
// end::configureSecurityHandler[] | ||
return securityHandler; | ||
} | ||
} |
117 changes: 117 additions & 0 deletions
117
...a/org/eclipse/jetty/docs/programming/security/siwe/SignInWithEthereumEmbeddedExample.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// | ||
// ======================================================================== | ||
// Copyright (c) 1995 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.docs.programming.security.siwe; | ||
|
||
import java.io.PrintWriter; | ||
import java.nio.file.Paths; | ||
import java.util.Objects; | ||
|
||
import org.eclipse.jetty.http.HttpHeader; | ||
import org.eclipse.jetty.io.Content; | ||
import org.eclipse.jetty.security.AuthenticationState; | ||
import org.eclipse.jetty.security.Constraint; | ||
import org.eclipse.jetty.security.SecurityHandler; | ||
import org.eclipse.jetty.security.siwe.EthereumAuthenticator; | ||
import org.eclipse.jetty.server.Handler; | ||
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.server.handler.ContextHandler; | ||
import org.eclipse.jetty.server.handler.ResourceHandler; | ||
import org.eclipse.jetty.session.SessionHandler; | ||
import org.eclipse.jetty.util.Callback; | ||
|
||
public class SignInWithEthereumEmbeddedExample | ||
{ | ||
public static void main(String[] args) throws Exception | ||
{ | ||
Server server = new Server(); | ||
ServerConnector connector = new ServerConnector(server); | ||
connector.setPort(8080); | ||
server.addConnector(connector); | ||
|
||
String resourcePath = Paths.get(Objects.requireNonNull(SignInWithEthereumEmbeddedExample.class.getClassLoader().getResource("")).toURI()) | ||
.resolve("../../src/main/resources/") | ||
.normalize().toString(); | ||
System.err.println(resourcePath); | ||
ResourceHandler resourceHandler = new ResourceHandler(); | ||
resourceHandler.setDirAllowed(false); | ||
resourceHandler.setBaseResourceAsString(resourcePath); | ||
|
||
Handler.Abstract handler = new Handler.Wrapper(resourceHandler) | ||
{ | ||
@Override | ||
public boolean handle(Request request, Response response, Callback callback) throws Exception | ||
{ | ||
String pathInContext = Request.getPathInContext(request); | ||
if ("/login.html".equals(pathInContext)) | ||
{ | ||
return super.handle(request, response, callback); | ||
} | ||
else if ("/logout".equals(pathInContext)) | ||
{ | ||
AuthenticationState.logout(request, response); | ||
Response.sendRedirect(request, response, callback, "/"); | ||
callback.succeeded(); | ||
return true; | ||
} | ||
|
||
AuthenticationState authState = Objects.requireNonNull(AuthenticationState.getAuthenticationState(request)); | ||
response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/html"); | ||
try (PrintWriter writer = new PrintWriter(Content.Sink.asOutputStream(response))) | ||
{ | ||
writer.write("UserPrincipal: " + authState.getUserPrincipal()); | ||
writer.write("<br><a href=\"/logout\">Logout</a>"); | ||
} | ||
callback.succeeded(); | ||
return true; | ||
} | ||
}; | ||
|
||
SecurityHandler securityHandler = createSecurityHandler(handler); | ||
SessionHandler sessionHandler = new SessionHandler(); | ||
sessionHandler.setHandler(securityHandler); | ||
|
||
ContextHandler contextHandler = new ContextHandler(); | ||
contextHandler.setContextPath("/"); | ||
contextHandler.setHandler(sessionHandler); | ||
|
||
server.setHandler(contextHandler); | ||
server.start(); | ||
server.join(); | ||
} | ||
|
||
public static SecurityHandler createSecurityHandler(Handler handler) | ||
{ | ||
// tag::configureSecurityHandler[] | ||
// This uses jetty-core, but you can configure a ConstraintSecurityHandler for use with EE10. | ||
SecurityHandler.PathMapped securityHandler = new SecurityHandler.PathMapped(); | ||
securityHandler.setHandler(handler); | ||
securityHandler.put("/*", Constraint.ANY_USER); | ||
|
||
// Add the EthereumAuthenticator to the securityHandler. | ||
EthereumAuthenticator authenticator = new EthereumAuthenticator(); | ||
securityHandler.setAuthenticator(authenticator); | ||
|
||
// In embedded you can configure via EthereumAuthenticator APIs. | ||
authenticator.setLoginPath("/login.html"); | ||
|
||
// Or you can configure with parameters on the SecurityHandler. | ||
securityHandler.setParameter(EthereumAuthenticator.LOGIN_PATH_PARAM, "/login.html"); | ||
// end::configureSecurityHandler[] | ||
|
||
return securityHandler; | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
documentation/jetty/modules/code/examples/src/main/resources/login.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Sign-In with Ethereum</title> | ||
<script src="https://cdn.jsdelivr.net/npm/web3@1.6.1/dist/web3.min.js"></script> | ||
</head> | ||
<body> | ||
<h4>Sign-In with Ethereum</h4> | ||
<button id="siwe">Sign-In with Ethereum</button> | ||
<form id="loginForm" action="/auth/login" method="POST" style="display: none;"> | ||
<input type="hidden" id="signatureField" name="signature"> | ||
<input type="hidden" id="messageField" name="message"> | ||
</form> | ||
<p class="alert" style="display: none;">Result: <span id="siweResult"></span></p> | ||
|
||
<script> | ||
let provider = window.ethereum; | ||
let accounts; | ||
|
||
if (!provider) { | ||
document.getElementById('siweResult').innerText = 'MetaMask is not installed. Please install MetaMask to use this feature.'; | ||
} else { | ||
document.getElementById('siwe').addEventListener('click', async () => { | ||
try { | ||
// Request account access if needed | ||
accounts = await provider.request({ method: 'eth_requestAccounts' }); | ||
const domain = window.location.host; | ||
const from = accounts[0]; | ||
|
||
// Fetch nonce from the server | ||
const nonceResponse = await fetch('/auth/nonce'); | ||
const nonceData = await nonceResponse.json(); | ||
const nonce = nonceData.nonce; | ||
|
||
const siweMessage = `${domain} wants you to sign in with your Ethereum account:\n${from}\n\nI accept the MetaMask Terms of Service: https://community.metamask.io/tos\n\nURI: https://${domain}\nVersion: 1\nChain ID: 1\nNonce: ${nonce}\nIssued At: ${new Date().toISOString()}`; | ||
const signature = await provider.request({ | ||
method: 'personal_sign', | ||
params: [siweMessage, from] | ||
}); | ||
console.log("signature: " + signature) | ||
console.log("nonce: " + nonce) | ||
console.log("length: " + length) | ||
|
||
document.getElementById('signatureField').value = signature; | ||
document.getElementById('messageField').value = siweMessage; | ||
document.getElementById('loginForm').submit(); | ||
} catch (error) { | ||
console.error('Error during login:', error); | ||
document.getElementById('siweResult').innerText = `Error: ${error.message}`; | ||
document.getElementById('siweResult').parentElement.style.display = 'block'; | ||
} | ||
}); | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
documentation/jetty/modules/programming-guide/pages/security/index.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// | ||
// ======================================================================== | ||
// Copyright (c) 1995 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 | ||
// ======================================================================== | ||
// | ||
|
||
= Jetty Security | ||
|
||
TODO: introduction | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that TODO shown in the resulting documentation, or is it treated like a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shows the todo in the documentation, but the documentation is very incomplete and doesn't yet have any other security modules. And a bunch of the other main headers have the same TODOs for the introduction page.
But I will remove this index file and just have a header without an intro page for this.