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

basic auth service #2262

Merged
merged 7 commits into from
Jan 29, 2019
Merged

basic auth service #2262

merged 7 commits into from
Jan 29, 2019

Conversation

kunmingg
Copy link
Contributor

@kunmingg kunmingg commented Jan 12, 2019

Backend part.
And Frontend Part is: #2316

Test passed, ready to merge.

fix #2147
fix #2148
fix #2149


This change is Reviewable

@kunmingg
Copy link
Contributor Author

/assign @kkasravi
/assign @jlewi

@kunmingg
Copy link
Contributor Author

/hold
Will manual test when ready.

@kunmingg kunmingg changed the title [WIP] basic auth service basic auth service Jan 23, 2019
@kunmingg
Copy link
Contributor Author

/hold cancel

func (s *authServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Infof("Path check, url: %v, path: %v", r.URL, r.URL.Path)
// login page open to everyone; all other path requires auth with Password or cookie
if strings.HasPrefix(r.URL.Path, "/" + LoginPagePath) || s.authCookie(r) == true {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be doing an exact match here to path
r.URL.Path, "/" + LoginPagePath

What if by some coincedence we have a path for which this is a prefix but is not an exact match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Browser need access resources like "/LoginPagePath/static/..." as well.
How about do exact match "/LoginPagePath" or prefix match "/LoginPagePath/"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should be safe to assume any thing behind "/LoginPagePath/" is public?

Copy link
Contributor

Choose a reason for hiding this comment

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

I see. Maybe we could file an issue to follow up on this. My concern is what if some app randomly adds some prefix like

/LoginPagePath/mynotebook

Then we would match it.

Can we be more restrictive e.g.

  • Exact match /LoginPagePath
  • Prefix match /LoginPagePath/static

Also maybe we can add in some nonsense e.g. make

  • /LoginPagePath-a12c

This way its less likely an app would have it as a prefix.

// login page open to everyone; all other path requires auth with Password or cookie
if strings.HasPrefix(r.URL.Path, "/" + LoginPagePath) || s.authCookie(r) == true {
// Handle request from login page
if r.Header.Get(LoginPageHeader) != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain what this if block is doing? Is it modifying the request to indicate that it should be allowed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This part take care of user's re-login
They already have cookie in browser, so "StatusResetContent" bring them to kubeflow central dashboard.


// Default auth check service
func (s *authServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Infof("Path check, url: %v, path: %v", r.URL, r.URL.Path)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we reject non https traffic?

We don't want user logging in if they aren't using https because that would send username/password in the clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can we only access https at gclb?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think there's any way to force GCLB to only accept https traffic. You can look at what we do in click to deploy. Basically we'd want to check if the protocol is http and then redirect to https

if len(namepw) != 2 {
return false
}
err = bcrypt.CompareHashAndPassword([]byte(s.pwhash), []byte(namepw[1]))
Copy link
Contributor

Choose a reason for hiding this comment

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

So CompareHashAndPassword returns error if they don't match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

// auth with cookie
func (s *authServer) authCookie(r *http.Request) bool {
if cookie, err := r.Cookie(CookieName); err == nil {
if val, ok := s.cookies[cookie.Value]; ok {
Copy link
Contributor

Choose a reason for hiding this comment

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

What prevents someone from spoofing a cookie?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SameSite: http.SameSiteStrictMode
We restrict the cookie so can only be used for same site.
Should we encrypt value as well?

Copy link
Contributor

Choose a reason for hiding this comment

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

You mean with bcrypt? So we only keep track of the encrypted value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, server side only keep encrypted password hash.

Copy link
Contributor

Choose a reason for hiding this comment

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

If its not too difficult I think that would be valuable; for the same reason its valuable with the password.

defer s.serverMux.Unlock()
// Cookie expire after 12 hours
log.Info("cookie set: set new cookie value!")
s.cookies[cookieVal] = time.Now().Add(12 * time.Hour)
Copy link
Contributor

Choose a reason for hiding this comment

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

So the cookie is stored in memory, so if the pod is restarted the cookie will no longer be valid. Will we automatically redirect user to log back in?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, all unauth access end up redirect to login.

Copy link
Contributor

Choose a reason for hiding this comment

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

Might be worth a P2 issue to fix in a follow up.

@jlewi
Copy link
Contributor

jlewi commented Jan 24, 2019

Thanks this looks great.

@jlewi
Copy link
Contributor

jlewi commented Jan 24, 2019

Will LetsEncrypt be an issue? Do we need to allow for the ACME challenge?

On GCP one option would be to migrate to Managed Certificates.


},
spec: {
replicas: 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a comment here explaining this should always be 1 because the cookie is stored in memory so if we use more than 1 replica we will have problems because not all replicas will have the cookie.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comments updated

@jlewi
Copy link
Contributor

jlewi commented Jan 25, 2019

On second thought I don't think LetsEncrypt is an issue because it adds a separate path to the ingress.

I had one more comment about adding a comment about number of replicas; otherwise this is good to go.

Copy link
Contributor

@jlewi jlewi left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 5 files at r1, 1 of 5 files at r2, 4 of 8 files at r3, 1 of 2 files at r4, 2 of 2 files at r5, 1 of 1 files at r6.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @abhi-g, @ellis-bigelow, and @kunmingg)


components/gatekeeper/auth/AuthServer.go, line 122 at r4 (raw file):

Previously, jlewi (Jeremy Lewi) wrote…

If its not too difficult I think that would be valuable; for the same reason its valuable with the password.

Created #2341 for this

@jlewi
Copy link
Contributor

jlewi commented Jan 28, 2019

/lgtm
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jlewi

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kunmingg
Copy link
Contributor Author

/retest

@k8s-ci-robot k8s-ci-robot merged commit d73e830 into kubeflow:master Jan 29, 2019
kkasravi pushed a commit to kkasravi/kubeflow that referenced this pull request Feb 8, 2019
* [WIP] basic auth service

* complete cookie setting and auth logic

* fmt

* add ksonnet lib; fix bugs

* corrent redirect; update image

* address review feedbacks

* update comments
saffaalvi pushed a commit to StatCan/kubeflow that referenced this pull request Feb 11, 2021
* [WIP] basic auth service

* complete cookie setting and auth logic

* fmt

* add ksonnet lib; fix bugs

* corrent redirect; update image

* address review feedbacks

* update comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants