Created
December 30, 2021 14:52
-
-
Save simon04/c302d738e7f24b90267a1d341d720d6d to your computer and use it in GitHub Desktop.
Revisions
-
simon04 created this gist
Dec 30, 2021 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,90 @@ package at.tbbm.manual_input.util; import com.auth0.jwk.Jwk; import com.auth0.jwk.JwkException; import com.auth0.jwk.JwkProvider; import com.auth0.jwk.UrlJwkProvider; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.DecodedJWT; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.DefaultUserIdentity; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.UserIdentity; import javax.security.auth.Subject; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URL; import java.security.Principal; import java.security.interfaces.RSAPublicKey; import java.util.regex.Pattern; public record JwtAuthenticator(Pattern skipPattern, JwkProvider provider) implements Authenticator { public JwtAuthenticator(Pattern skipPattern, URL jwks) { this(skipPattern, new UrlJwkProvider(jwks)); } @Override public String getAuthMethod() { return "BEARER"; } @Override public void prepareRequest(ServletRequest request) { } @Override public void setConfiguration(AuthConfiguration configuration) { } @Override public Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String requestPath = httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length()); if (skipPattern.matcher(requestPath).matches()) { return Authentication.NOT_CHECKED; } try { DecodedJWT jwt = decodedJWT(httpServletRequest); verify(jwt); return buildUserAuthentication(jwt); } catch (JwkException | JWTVerificationException e) { try { ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (IOException e2) { throw new UncheckedIOException(e2); } return Authentication.UNAUTHENTICATED; } } private DecodedJWT decodedJWT(HttpServletRequest httpServletRequest) { String token = httpServletRequest.getHeader(HttpHeader.AUTHORIZATION.asString()).substring("Bearer ".length()); return JWT.decode(token); } private void verify(DecodedJWT jwt) throws JwkException { Jwk jwk = provider.get(jwt.getKeyId()); Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null); JWT.require(algorithm).build().verify(jwt); } private UserAuthentication buildUserAuthentication(DecodedJWT jwt) { Principal email = () -> jwt.getClaims().get("email").asString(); UserIdentity identity = new DefaultUserIdentity(new Subject(), email, new String[]{"role1", "role2"}); return new UserAuthentication(getAuthMethod(), identity); } @Override public boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, Authentication.User validatedUser) { return true; } }