Example #1
0
func redirectWithError(ctx *app.AuthorizeLoginContext, knownReferer string, errorString string) error {
	ctx.ResponseData.Header().Set("Location", knownReferer+"?error="+errorString)
	return ctx.TemporaryRedirect()
}
Example #2
0
// Perform performs authenticatin
func (keycloak *KeycloakOAuthProvider) Perform(ctx *app.AuthorizeLoginContext) error {
	state := ctx.Params.Get("state")
	code := ctx.Params.Get("code")
	referer := ctx.RequestData.Header.Get("Referer")

	if code != "" {
		// After redirect from oauth provider

		// validate known state
		var knownReferer string
		defer func() {
			delete(stateReferer, state)
		}()

		knownReferer = stateReferer[state]
		if state == "" || knownReferer == "" {
			log.Error(ctx, map[string]interface{}{
				"state":   state,
				"referer": knownReferer,
			}, "state or known referer was empty")

			jerrors, _ := jsonapi.ErrorToJSONAPIErrors(goa.ErrUnauthorized("State or known referer was empty"))
			return ctx.Unauthorized(jerrors)
		}

		keycloakToken, err := keycloak.config.Exchange(ctx, code)
		if err != nil || keycloakToken.AccessToken == "" {
			log.Error(ctx, map[string]interface{}{
				"code": code,
				"err":  err,
			}, "keycloak exchange operation failed")
			return redirectWithError(ctx, knownReferer, InvalidCodeError)
		}

		_, _, err = keycloak.CreateKeycloakUser(keycloakToken.AccessToken, ctx)
		if err != nil {
			log.Error(ctx, map[string]interface{}{
				"token": keycloakToken.AccessToken,
				"err":   err,
			}, "failed to create a user and KeyCloak identity using the access token")
			return redirectWithError(ctx, knownReferer, err.Error())

		}

		referelURL, err := url.Parse(knownReferer)
		if err != nil {
			return redirectWithError(ctx, knownReferer, err.Error())
		}

		err = encodeToken(referelURL, keycloakToken)
		if err != nil {
			return redirectWithError(ctx, knownReferer, err.Error())
		}
		ctx.ResponseData.Header().Set("Location", referelURL.String())
		return ctx.TemporaryRedirect()
	}

	// First time access, redirect to oauth provider

	// store referer id to state for redirect later
	log.Info(ctx, map[string]interface{}{
		"pkg":     "login",
		"referer": referer,
	}, "Got Request from!")

	state = uuid.NewV4().String()

	mapLock.Lock()
	defer mapLock.Unlock()

	stateReferer[state] = referer

	keycloak.config.RedirectURL = rest.AbsoluteURL(ctx.RequestData, "/api/login/authorize")

	redirectURL := keycloak.config.AuthCodeURL(state, oauth2.AccessTypeOnline)

	ctx.ResponseData.Header().Set("Location", redirectURL)
	return ctx.TemporaryRedirect()
}
Example #3
0
func (t TestLoginService) Perform(ctx *app.AuthorizeLoginContext) error {
	return ctx.TemporaryRedirect()
}