Basic but complete authentication flow

This commit is contained in:
2020-05-20 11:13:14 +02:00
parent 81778121fb
commit 61aae078b5
32 changed files with 626 additions and 442 deletions

View File

@ -41,8 +41,8 @@ func (c *Client) LoginRequest(challenge string) (*LoginResponse, error) {
return loginRes, nil
}
func (c *Client) AcceptRequest(challenge string, req *AcceptRequest) (*AcceptResponse, error) {
u := fromURL(*c.baseURL, "/oauth2/auth/requests/accept", url.Values{
func (c *Client) AcceptLoginRequest(challenge string, req *AcceptLoginRequest) (*AcceptResponse, error) {
u := fromURL(*c.baseURL, "/oauth2/auth/requests/login/accept", url.Values{
"login_challenge": []string{challenge},
})
@ -55,8 +55,8 @@ func (c *Client) AcceptRequest(challenge string, req *AcceptRequest) (*AcceptRes
return res, nil
}
func (c *Client) RejectRequest(challenge string, req *RejectRequest) (*RejectResponse, error) {
u := fromURL(*c.baseURL, "/oauth2/auth/requests/reject", url.Values{
func (c *Client) RejectLoginRequest(challenge string, req *RejectRequest) (*RejectResponse, error) {
u := fromURL(*c.baseURL, "/oauth2/auth/requests/login/reject", url.Values{
"login_challenge": []string{challenge},
})
@ -74,7 +74,57 @@ func (c *Client) LogoutRequest(challenge string) (*LogoutResponse, error) {
}
func (c *Client) ConsentRequest(challenge string) (*ConsentResponse, error) {
return nil, nil
u := fromURL(*c.baseURL, "/oauth2/auth/requests/consent", url.Values{
"consent_challenge": []string{challenge},
})
res, err := c.http.Get(u)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve login response")
}
if res.StatusCode < http.StatusOK || res.StatusCode >= http.StatusBadRequest {
return nil, errors.Wrapf(ErrUnexpectedHydraResponse, "hydra responded with status code '%d'", res.StatusCode)
}
defer res.Body.Close()
decoder := json.NewDecoder(res.Body)
consentRes := &ConsentResponse{}
if err := decoder.Decode(consentRes); err != nil {
return nil, errors.Wrap(err, "could not decode json response")
}
return consentRes, nil
}
func (c *Client) AcceptConsentRequest(challenge string, req *AcceptConsentRequest) (*AcceptResponse, error) {
u := fromURL(*c.baseURL, "/oauth2/auth/requests/consent/accept", url.Values{
"consent_challenge": []string{challenge},
})
res := &AcceptResponse{}
if err := c.putJSON(u, req, res); err != nil {
return nil, err
}
return res, nil
}
func (c *Client) RejectConsentRequest(challenge string, req *RejectRequest) (*RejectResponse, error) {
u := fromURL(*c.baseURL, "/oauth2/auth/requests/consent/reject", url.Values{
"consent_challenge": []string{challenge},
})
res := &RejectResponse{}
if err := c.putJSON(u, req, res); err != nil {
return nil, err
}
return res, nil
}
func (c *Client) LoginChallenge(r *http.Request) (string, error) {

View File

@ -1,12 +1,25 @@
package hydra
type AcceptRequest struct {
type AcceptLoginRequest struct {
Subject string `json:"subject"`
Remember bool `json:"remember"`
RememberFor int `json:"remember_for"`
ACR string `json:"acr"`
}
type AcceptConsentRequest struct {
GrantScope []string `json:"grant_scope"`
GrantAccessTokenAudience []string `json:"grant_access_token_audience"`
Remember bool `json:"remember"`
RememberFor int `json:"remember_for"`
Session AcceptConsentSession `json:"session"`
}
type AcceptConsentSession struct {
AccessToken map[string]interface{} `json:"access_token"`
IDToken map[string]interface{} `json:"id_token"`
}
type RejectRequest struct {
Error string `json:"error"`
ErrorDescription string `json:"error_description"`

View File

@ -55,11 +55,12 @@ type LoginResponse struct {
RequestURL string `json:"request_url"`
RequestedScope []string `json:"requested_scope"`
OidcContext OidcContextResponseFragment `json:"oidc_context"`
RequestedAccessTokenAudience string `json:"requested_access_token_audience"`
RequestedAccessTokenAudience []string `json:"requested_access_token_audience"`
SessionID string `json:"session_id"`
}
type AcceptResponse struct {
RedirectTo string `json:"redirect_to"`
}
type RejectResponse struct {
@ -70,4 +71,13 @@ type LogoutResponse struct {
}
type ConsentResponse struct {
Challenge string `json:"challenge"`
Skip bool `json:"skip"`
Subject string `json:"subject"`
Client ClientResponseFragment `json:"client"`
RequestURL string `json:"request_url"`
RequestedScope []string `json:"requested_scope"`
OidcContext OidcContextResponseFragment `json:"oidc_context"`
RequestedAccessTokenAudience []string `json:"requested_access_token_audience"`
SessionID string `json:"session_id"`
}