Skip to content
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

API GW phase 0 (depends on PR #544) #551

Closed
wants to merge 0 commits into from
Closed

Conversation

amiryesh
Copy link

@amiryesh amiryesh commented May 7, 2017

First operational version of API GW

@@ -108,7 +131,7 @@ func main() {
Logger.Fatal(err)
}

// override the default so we can use self-signed certs on our microservices
// Override the default so we can use self-signed certs on our microservices
// and use a self-signed cert in this server
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is understandable for debug, but it should be a config, and default to false. No one should ever skip cert verification in production.


rule := s.matchRule(req)
if rule == nil {
http.Error(w, "Not found", http.StatusNotFound)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Not found" should be http.StatusText(http.StatusNotFound) to avoid magic strings.

func rejectNoToken(handler http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusForbidden)
func (rule *FwdRule) authorize(w http.ResponseWriter, req *http.Request) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As-written this is acceptable but misleading. But, comments elsewhere suggest the ultimate goal is to deprecate internal TO authorization and rely exclusively on the proxy/auth service/other microservices. That would not be acceptable.

Authorization MUST check the database. If it doesn't, it's not possible to revoke tokens. For example, if an employee is fired, or if an attacker is discovered after gaining an authorization token. It must be possible to revoke access.

Copy link
Author

@amiryesh amiryesh May 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By design, authorization does not check the database to avoid congestion. We use short lived access tokens.

The general approach for doing authentication in the API layer was discussed and agreed upon.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general approach for doing authentication in the API layer was discussed and agreed upon.

"We already agreed" is not an argument for implementing security vulnerabilities.

Moving this to the mailing list.

body, err := ioutil.ReadAll(r.Body)
if err != nil {
Logger.Println("Error reading body: ", err.Error())
http.Error(w, "Error reading body: "+err.Error(), http.StatusBadRequest)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should log, but the error MUST NOT be returned to the client, for security. Especially SQL errors. Clients should be given an appropriate response code, and no more information.

err = json.Unmarshal(body, &login)
if err != nil {
Logger.Println("Invalid JSON: ", err.Error())
http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment: errors must not be returned to client.


if err != nil {
Logger.Printf("%v %v Token error: %s", req.Method, req.URL.RequestURI(), err)
http.Error(w, "Forbidden", http.StatusForbidden)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Forbidden" should be http.StatusText(http.StatusForbidden)

route := rule.matchRoute(req)
if route == nil {
Logger.Printf("%v %v Route not found", req.Method, req.URL.RequestURI())
http.Error(w, "Not found", http.StatusNotFound)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Not found" should be http.StatusText(http.StatusNotFound)

claims, ok := token.Claims.(*Claims)
if !ok {
Logger.Printf("%v %v Token valid but cannot parse claims", req.Method, req.URL.RequestURI())
http.Error(w, "Forbidden", http.StatusForbidden)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Forbidden" should be http.StatusText(http.StatusForbidden)

method := route.Auth[req.Method]
if method == nil {
Logger.Printf("%v %v Route found but method forbidden", req.Method, req.URL.RequestURI())
http.Error(w, "Forbidden", http.StatusForbidden)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Forbidden" should be http.StatusText(http.StatusForbidden)

if (satisfied > 0) {
Logger.Printf("%v %v Route found but required capabilitoes not satisfied. HAS %v, NEED %v",
req.Method, req.URL.RequestURI(), claims.Capabilities, method)
http.Error(w, "Forbidden", http.StatusForbidden)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Forbidden" should be http.StatusText(http.StatusForbidden)

#### Legacy TO support

Legacy TO authorization code requires any API call to pass a mojolicios access token in its access control headers.
Untill this code is deprecated, the Auth server and the API GW handle legacy authorization in hte following way:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo, "in the"

@@ -1,6 +1,13 @@

A simple authentication server written in go that authenticates user agains the `tm_user` table and returns a jwt representing the user, incl. its API access capabilities, derived from the user's role.

#### Legacy TO support

Legacy TO authorization code requires any API call to pass a mojolicios access token in its access control headers.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo, "mojolicious"


Legacy TO authorization code requires any API call to pass a mojolicios access token in its access control headers.
Untill this code is deprecated, the Auth server and the API GW handle legacy authorization in hte following way:
Upon every sucessful login the auth server performs additional login against legacy TO (mojolicious app) and recieves a lagacy TO authentication token.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo, "legacy"

Copy link
Member

@rob05c rob05c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be merged. The remaining comments are not critical, or apply to future architecture not this code.

@amiryesh
Copy link
Author

Closed by mistake. Created PR #567.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants