Skip to content

Commit 23890e7

Browse files
authored
feat: add ResponseWriter interface with Write method. (#2)
The IdpAuthnRequest.WriteResponse method has been updated with a DefaultResponseWriter and its Write method.
1 parent a32b643 commit 23890e7

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

identity_provider.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ type AssertionMaker interface {
7979
MakeAssertion(req *IdpAuthnRequest, session *Session) error
8080
}
8181

82+
// ResponseWriter is an interface used by IdentityProvider to write
83+
// SAML authentication response. The default implementation is DefaultResponseWriter,
84+
// which is used if ResponseWriter is not specified.
85+
type ResponseWriter interface {
86+
// Write writes HTTP response with a SAML authentication response
87+
// message containing a SAML assertion. The response format depends
88+
// on a SAML response binding configured between IDP and SP.
89+
Write(w http.ResponseWriter, req *IdpAuthnRequest) error
90+
}
91+
8292
// IdentityProvider implements the SAML Identity Provider role (IDP).
8393
//
8494
// An identity provider receives SAML assertion requests and responds
@@ -103,6 +113,7 @@ type IdentityProvider struct {
103113
SSOURL url.URL
104114
LogoutURL url.URL
105115
ServiceProviderProvider ServiceProviderProvider
116+
ResponseWriter ResponseWriter
106117
SessionProvider SessionProvider
107118
AssertionMaker AssertionMaker
108119
SignatureMethod string
@@ -253,7 +264,12 @@ func (idp *IdentityProvider) ServeSSO(w http.ResponseWriter, r *http.Request) {
253264
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
254265
return
255266
}
256-
if err := req.WriteResponse(w); err != nil {
267+
268+
responseWriter := idp.ResponseWriter
269+
if responseWriter == nil {
270+
responseWriter = DefaultResponseWriter{}
271+
}
272+
if err := responseWriter.Write(w, req); err != nil {
257273
idp.Logger.Printf("failed to write response: %s", err)
258274
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
259275
return
@@ -327,7 +343,11 @@ func (idp *IdentityProvider) ServeIDPInitiated(w http.ResponseWriter, r *http.Re
327343
return
328344
}
329345

330-
if err := req.WriteResponse(w); err != nil {
346+
responseWriter := idp.ResponseWriter
347+
if responseWriter == nil {
348+
responseWriter = DefaultResponseWriter{}
349+
}
350+
if err := responseWriter.Write(w, req); err != nil {
331351
idp.Logger.Printf("failed to write response: %s", err)
332352
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
333353
return
@@ -921,9 +941,14 @@ func (req *IdpAuthnRequest) PostBinding() (IdpAuthnRequestForm, error) {
921941
return form, nil
922942
}
923943

924-
// WriteResponse writes the `Response` to the http.ResponseWriter. If
925-
// `Response` is not already set, it calls MakeResponse to produce it.
926-
func (req *IdpAuthnRequest) WriteResponse(w http.ResponseWriter) error {
944+
// DefaultResponseWriter is the default response interface
945+
// for the identity provider.
946+
type DefaultResponseWriter struct {
947+
}
948+
949+
// Write implements DefaultResponseWriter and writes HTTP response with SAML authentication
950+
// response, which is an HTML POST form with a SAML assertion.
951+
func (DefaultResponseWriter) Write(w http.ResponseWriter, req *IdpAuthnRequest) error {
927952
form, err := req.PostBinding()
928953
if err != nil {
929954
return err

identity_provider_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ func NewIdentityProviderTest(t *testing.T, opts ...idpTestOpts) *IdentityProvide
138138
return nil
139139
},
140140
},
141+
ResponseWriter: &DefaultResponseWriter{},
141142
}
142143

143144
// apply the test options
@@ -789,7 +790,7 @@ func TestIDPWriteResponse(t *testing.T) {
789790
assert.Check(t, err)
790791

791792
w := httptest.NewRecorder()
792-
err = req.WriteResponse(w)
793+
err = test.IDP.ResponseWriter.Write(w, &req)
793794
assert.Check(t, err)
794795
assert.Check(t, is.Equal(200, w.Code))
795796
golden.Assert(t, w.Body.String(), t.Name()+"response.html")

0 commit comments

Comments
 (0)