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

How to use deep linking #359

Open
afdecastro879 opened this issue Jun 14, 2021 · 1 comment
Open

How to use deep linking #359

afdecastro879 opened this issue Jun 14, 2021 · 1 comment

Comments

@afdecastro879
Copy link

HI All!

According to SAML documentation usually RelayState is used to allow IdPs to redirect to an specific URL after the whole SAML roundtrip has been completed. However, with crewjam/saml implementation I have not been able to get this right as seems that RelayState is usually a random generated value (This following the example in the Readme.md)

Can please someone point me on how to achieve deep linking using this library? I suspect, instead of using the Middleware I'll need to implement the whole authentication flow using methods like MakeRedirectAuthenticationRequest Is this correct?
If so, what should I do after the first redirection?

Thank you

@McGregsen
Copy link

McGregsen commented Jun 16, 2021

Hello,
it has been a while since I was actively developing something that used this library so my memory might not be accurate but I don't think you need to implement the auth flow yourself and this should work more or less out of the box.

If you take a look at TrackRequest in request_tracker_cookie.go it stores the original request URL in the tracked request.

func (t CookieRequestTracker) TrackRequest(w http.ResponseWriter, r *http.Request, samlRequestID string) (string, error) {
	trackedRequest := TrackedRequest{
		Index:         base64.RawURLEncoding.EncodeToString(randomBytes(42)),
		SAMLRequestID: samlRequestID,
		URI:           r.URL.String(),
	}
//...
}

After the auth flow completes the middleware (middleware.go) loads the trackedRequest in CreateSessionFromAssertion and redirects to the original URL.

func (m *Middleware) CreateSessionFromAssertion(w http.ResponseWriter, r *http.Request, assertion *saml.Assertion) {
        redirectURI := "/"
	if trackedRequestIndex := r.Form.Get("RelayState"); trackedRequestIndex != "" {
		trackedRequest, err := m.RequestTracker.GetTrackedRequest(r, trackedRequestIndex)
		if err != nil {
			m.OnError(w, r, err)	
		return
		}
		m.RequestTracker.StopTrackingRequest(w, r, trackedRequestIndex)
		redirectURI = trackedRequest.URI
	}
	if err := m.Session.CreateSession(w, r, assertion); err != nil {
		m.OnError(w, r, err)
		return
	}
	http.Redirect(w, r, redirectURI, http.StatusFound)
}

This means that the relayState does not contain the URL but rather a key that allows the SP to lookup the initial request URL.

If you want to redirect somewhere else you could modify the code to either store a different url or redirect to something else after the auth flow completes.
Or do you need to let the IDP decide where to redirect the user?

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

No branches or pull requests

2 participants