@@ -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
0 commit comments