Пример #1
0
Файл: main.go Проект: polvi/rolo
func getJWT(c *oidc.Client, listenAddr string) (*oauth2.Client, chan *oauth2.TokenResponse, error) {
	jwtChan := make(chan *oauth2.TokenResponse)
	l, err := net.Listen("tcp", listenAddr)
	if err != nil {
		return nil, nil, err
	}
	oac, err := c.OAuthClient()
	if err != nil {
		return nil, nil, err
	}
	f := func(w http.ResponseWriter, r *http.Request) {
		code := r.URL.Query().Get("code")
		if code == "" {
			return
		}
		token, err := oac.RequestToken(oauth2.GrantTypeAuthCode, code)
		if err != nil {
			fmt.Fprintf(w, "error: %s", err)
			return
		}
		jwtChan <- &token
		fmt.Fprintf(w, "Success! You can now close this window and go back to the CLI")
		l.Close()
	}
	go http.Serve(l, http.HandlerFunc(f))
	return oac, jwtChan, err
}
Пример #2
0
func handleCallbackFunc(c *oidc.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		code := r.URL.Query().Get("code")
		if code == "" {
			phttp.WriteError(w, http.StatusBadRequest, "code query param must be set")
			return
		}

		tok, err := c.ExchangeAuthCode(code)
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify auth code with issuer: %v", err))
			return
		}

		claims, err := tok.Claims()
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to construct claims: %v", err))
			return
		}

		s := fmt.Sprintf(`<html><body><p>Token: %v</p><p>Claims: %v </p>
        <a href="/resend?jwt=%s">Resend Verification Email</a>
</body></html>`, tok.Encode(), claims, tok.Encode())
		w.Write([]byte(s))
	}
}
Пример #3
0
// Reads the OIDC JWT passed in the context and verifies it using the given OIDC client.
// Returns the verified identity on success, error otherwise.
func VerifiedIdentityFromContext(client *gooidc.Client, ctx context.Context) (*gooidc.Identity, error) {
	md, ok := metadata.FromContext(ctx)
	if !ok {
		return nil, errors.New("missing RPC credentials")
	}
	rawJWT, ok := md["jwt"]
	if !ok {
		return nil, errors.New("missing OIDC credentials")
	}
	if len(rawJWT) != 1 {
		return nil, errors.New("incorrect JWT data sent")
	}
	jwt, err := jose.ParseJWT(rawJWT[0])
	if err != nil {
		return nil, err
	}
	if err := client.VerifyJWT(jwt); err != nil {
		return nil, err
	}
	claims, err := jwt.Claims()
	if err != nil {
		return nil, err
	}
	return gooidc.IdentityFromClaims(claims)
}
Пример #4
0
func oidcCallback(c *oidc.Client, listenAddr string) (string, chan jose.JWT, error) {
	tokenChan := make(chan jose.JWT)
	l, err := net.Listen("tcp", listenAddr)
	if err != nil {
		return "", nil, err
	}
	oac, err := c.OAuthClient()
	if err != nil {
		return "", nil, err
	}
	f := func(w http.ResponseWriter, r *http.Request) {
		code := r.URL.Query().Get("code")
		if code == "" {
			return
		}
		token, err := c.ExchangeAuthCode(code)
		if err != nil {
			fmt.Fprintf(w, "error: %s", err)
			return
		}
		tokenChan <- token
		close(tokenChan)
		fmt.Fprintf(w, "Success! You can now close this window and go back to the CLI")
		l.Close()
	}
	go http.Serve(l, http.HandlerFunc(f))
	return oac.AuthCodeURL("", "", ""), tokenChan, err
}
Пример #5
0
// Parses and validates a JWT token, based on the client definition provided.
func ValidateJWT(idToken string, client *oidc.Client) (jose.JWT, error) {

	jwt, err := jose.ParseJWT(idToken)
	if err != nil {
		return jose.JWT{}, err
	}

	return jwt, client.VerifyJWT(jwt)
}
Пример #6
0
func exchangeAuthCode(c *oidc.Client, code string) (oauth2.TokenResponse, error) {
	oac, err := c.OAuthClient()
	if err != nil {
		return oauth2.TokenResponse{}, err
	}

	t, err := oac.RequestToken(oauth2.GrantTypeAuthCode, code)
	if err != nil {
		return oauth2.TokenResponse{}, err
	}

	return t, nil

}
Пример #7
0
func handleLoginFunc(c *oidc.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		oac, err := c.OAuthClient()
		if err != nil {
			panic("unable to proceed")
		}

		u, err := url.Parse(oac.AuthCodeURL("", "", ""))
		if err != nil {
			panic("unable to proceed")
		}
		http.Redirect(w, r, u.String(), http.StatusFound)
	}
}
Пример #8
0
func handleRegisterFunc(c *oidc.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		oac, err := c.OAuthClient()
		if err != nil {
			panic("unable to proceed")
		}

		u, err := url.Parse(oac.AuthCodeURL("", "", ""))
		q := u.Query()
		q.Set("register", "1")
		if err != nil {
			panic("unable to proceed")
		}
		u.RawQuery = q.Encode()
		log.Infof("URL: %v", u.String())
		http.Redirect(w, r, u.String(), http.StatusFound)
	}
}
Пример #9
0
func handleCallbackFunc(c *oidc.Client, claims *jose.Claims, refresh *string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		code := r.URL.Query().Get("code")
		if code == "" {
			phttp.WriteError(w, http.StatusBadRequest, "code query param must be set")
			return
		}

		oac, err := c.OAuthClient()
		if err != nil {
			phttp.WriteError(w, http.StatusInternalServerError, fmt.Sprintf("unable to create oauth client: %v", err))
			return
		}

		t, err := oac.RequestToken(oauth2.GrantTypeAuthCode, code)
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify auth code with issuer: %v", err))
			return
		}

		// Get id token and claims.
		tok, err := jose.ParseJWT(t.IDToken)
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to parse id_token: %v", err))
			return
		}

		if err := c.VerifyJWT(tok); err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify the JWT: %v", err))
			return
		}

		if *claims, err = tok.Claims(); err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to construct claims: %v", err))
			return
		}

		// Get refresh token.
		*refresh = t.RefreshToken

		w.WriteHeader(http.StatusOK)
	}
}
Пример #10
0
func handleLoginFunc(c *oidc.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		err := r.ParseForm()
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest,
				fmt.Sprintf("Could not parse request: %v", err))
		}

		oac, err := c.OAuthClient()
		if err != nil {
			panic("unable to proceed")
		}

		u, err := url.Parse(oac.AuthCodeURL("", "", ""))
		if err != nil {
			panic("unable to proceed")
		}

		var scopes []string
		q := u.Query()
		if scope := q.Get("scope"); scope != "" {
			scopes = strings.Split(scope, " ")
		}

		if xClient := r.Form.Get("cross_client"); xClient != "" {
			xClients := strings.Split(xClient, ",")
			for _, x := range xClients {
				scopes = append(scopes, scope.ScopeGoogleCrossClient+x)
			}
		}

		if extraScopes := r.Form.Get("extra_scopes"); extraScopes != "" {
			scopes = append(scopes, strings.Split(extraScopes, ",")...)
		}

		if scopes != nil {
			q.Set("scope", strings.Join(scopes, " "))
			u.RawQuery = q.Encode()
		}

		http.Redirect(w, r, u.String(), http.StatusFound)
	}
}
Пример #11
0
func handleCallbackFunc(c *oidc.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		code := r.URL.Query().Get("code")
		if code == "" {
			writeError(w, http.StatusBadRequest, "code query param must be set")
			return
		}

		tok, err := c.ExchangeAuthCode(code)
		if err != nil {
			writeError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify auth code with issuer: %v", err))
			return
		}

		claims, err := tok.Claims()
		if err != nil {
			writeError(w, http.StatusBadRequest, fmt.Sprintf("unable to construct claims: %v", err))
			return
		}

		s := fmt.Sprintf("claims: %v", claims)
		w.Write([]byte(s))
	}
}
Пример #12
0
func handleCallbackFunc(c *oidc.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		refreshToken := r.URL.Query().Get("refresh_token")
		code := r.URL.Query().Get("code")

		oac, err := c.OAuthClient()
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to create OAuth2 client: %v", err))
			return
		}

		var token oauth2.TokenResponse

		switch {
		case code != "":
			if token, err = oac.RequestToken(oauth2.GrantTypeAuthCode, code); err != nil {
				phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify auth code with issuer: %v", err))
				return
			}
		case refreshToken != "":
			if token, err = oac.RequestToken(oauth2.GrantTypeRefreshToken, refreshToken); err != nil {
				phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to refresh token: %v", err))
				return
			}
			if token.RefreshToken == "" {
				token.RefreshToken = refreshToken
			}
		default:
			phttp.WriteError(w, http.StatusBadRequest, "code query param must be set")
			return
		}

		tok, err := jose.ParseJWT(token.IDToken)
		if err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to parse JWT: %v", err))
			return
		}

		claims := new(bytes.Buffer)
		if err := json.Indent(claims, tok.Payload, "", "  "); err != nil {
			phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to construct claims: %v", err))
			return
		}
		s := fmt.Sprintf(`
<html>
  <head>
    <style>
/* make pre wrap */
pre {
 white-space: pre-wrap;       /* css-3 */
 white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
 white-space: -pre-wrap;      /* Opera 4-6 */
 white-space: -o-pre-wrap;    /* Opera 7 */
 word-wrap: break-word;       /* Internet Explorer 5.5+ */
} 
    </style>
  </head>
  <body>
    <p> Token: <pre><code>%v</code></pre></p>
    <p> Claims: <pre><code>%v</code></pre></p>
    <p> Refresh Token: <pre><code>%v</code></pre></p>
    <p><a href="%s?refresh_token=%s">Redeem refresh token</a><p>
    <p><a href="/resend?jwt=%s">Resend Verification Email</a></p>
  </body>
</html>`, tok.Encode(), claims.String(), token.RefreshToken, r.URL.Path, token.RefreshToken, tok.Encode())
		w.Write([]byte(s))
	}
}