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 characters
apiVersion: extensions/v1beta1 | |
kind: Deployment | |
metadata: | |
name: web | |
namespace: default | |
spec: | |
selector: | |
matchLabels: | |
run: web | |
template: |
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 characters
<?xml version="1.0" encoding="utf-8"?> | |
<web-app version="3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns="http://xmlns.jcp.org/xml/ns/javaee" | |
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> | |
<servlet> | |
<servlet-name>appengine-spring-boot</servlet-name> | |
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |
<init-param> | |
<param-name>contextClass</param-name> |
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 characters
import os | |
import google.auth | |
import google.oauth2.service_account | |
from google.auth.transport.requests import Request | |
import requests | |
IAM_SCOPE = 'https://www.googleapis.com/auth/iam' | |
OAUTH_TOKEN_URI = 'https://www.googleapis.com/oauth2/v4/token' |
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 characters
_adc_credentials, _ = google.auth.default(scopes=[IAM_SCOPE]) | |
# For service accounts using the Compute Engine metadata service, which is the | |
# case for Cloud Function service accounts, service_account_email isn't | |
# available until refresh is called. | |
_adc_credentials.refresh(GRequest()) | |
# Since the Compute Engine metadata service doesn't expose the service | |
# account key, we use the IAM signBlob API to sign instead. In order for this | |
# to work, the Cloud Function's service account needs the "Service Account |
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 characters
# Check path against whitelist. | |
path = proxied_request.path | |
if not path: | |
path = '/' | |
# TODO: Implement proper wildcarding for paths. | |
if '*' not in _whitelist and path not in _whitelist: | |
logging.warn('Rejected {} {}, not in whitelist'.format( | |
proxied_request.method, url)) | |
return 'Requested path {} not in whitelist'.format(path), 403 |
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 characters
# Strip hop-by-hop headers and Content-Encoding. | |
headers = _strip_hop_by_hop_headers(resp.headers) | |
headers.pop('Content-Encoding', None) | |
return resp.content, resp.status_code, headers.items() |
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 characters
global _oidc_token | |
if not _oidc_token or _oidc_token.is_expired(): | |
_oidc_token = _get_google_oidc_token() | |
logging.info('Renewed OIDC bearer token for {}'.format( | |
_adc_credentials.service_account_email)) | |
# Add the Authorization header with the OIDC token. | |
headers['Authorization'] = 'Bearer {}'.format(_oidc_token) | |
# We don't want to forward the Host header. |
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 characters
class OIDCToken(object): | |
def __init__(self, token_str): | |
self._token_str = token_str | |
self._claims = jwt.decode(token_str, verify=False) | |
def __str__(self): | |
return self._token_str | |
def is_expired(self): |
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 characters
def handle_request(proxied_request): | |
"""Proxy the given request to the URL in the Forward-Host header with an | |
Authorization header set using an OIDC bearer token for the Cloud | |
Function's service account. If the header is not present, return a 400 | |
error. | |
""" | |
host = proxied_request.headers.get(HOST_HEADER) | |
if not host: | |
return 'Required header {} not present'.format(HOST_HEADER), 400 |
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 characters
private DecodedJWT getGoogleIdToken() throws IOException { | |
String jwt = getSignedJwt(); | |
final GenericData tokenRequest = new GenericData() | |
.set("grant_type", JWT_BEARER_TOKEN_GRANT_TYPE) | |
.set("assertion", jwt); | |
final UrlEncodedContent content = new UrlEncodedContent(tokenRequest); | |
final HttpRequestFactory requestFactory = httpTransport.createRequestFactory(); | |
final HttpRequest request = requestFactory |