func redirectWithError(ctx *app.AuthorizeLoginContext, knownReferer string, errorString string) error { ctx.ResponseData.Header().Set("Location", knownReferer+"?error="+errorString) return ctx.TemporaryRedirect() }
// 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() }
func (t TestLoginService) Perform(ctx *app.AuthorizeLoginContext) error { return ctx.TemporaryRedirect() }