Example #1
0
func (handler *queryHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	decoder := xml.NewDecoder(request.Body)
	var attributeEnv attributes.AttributeQueryEnv
	err := decoder.Decode(&attributeEnv)
	// TODO determine if this is the appropriate error response
	if err != nil {
		http.Error(writer, err.Error(), 500)
		return
	}
	// TODO validate attributeEnv before proceeding
	query := attributeEnv.Body.Query
	name := query.Subject.NameID.Value
	format := query.Subject.NameID.Format
	user := &protocol.AuthenticatedUser{Name: name, Format: format}
	atts, err := handler.retriever.Retrieve(user)
	// TODO determine if this is the appropriate error response
	if err != nil {
		http.Error(writer, err.Error(), 500)
		return
	}
	var attrResp attributes.AttributeRespEnv
	resp := &attrResp.Body.Response
	resp.ID = protocol.NewID()
	resp.InResponseTo = query.ID
	resp.Version = "2.0"
	now := time.Now()
	resp.IssueInstant = now
	resp.Issuer = saml.NewIssuer(handler.entityId)
	a := &saml.Assertion{}
	a.Issuer = resp.Issuer
	a.IssueInstant = now
	a.ID = protocol.NewID()
	a.Version = "2.0"
	a.Subject = &saml.Subject{}
	a.Subject.NameID = query.Subject.NameID
	a.AttributeStatement = saml.NewAttributeStatement(atts)
	a.Conditions = &saml.Conditions{}
	a.Conditions.NotBefore = now
	fiveMinutes, _ := time.ParseDuration("5m")
	fiveFromNow := now.Add(fiveMinutes)
	a.Conditions.NotOnOrAfter = fiveFromNow
	a.Conditions.AudienceRestriction = &saml.AudienceRestriction{Audience: query.Issuer}
	resp.Status = protocol.NewStatus(true)
	resp.Assertion = a

	signature, err := handler.signer.Sign(a)
	// TODO determine if this is the appropriate error response
	if err != nil {
		http.Error(writer, err.Error(), 500)
		return
	}
	a.Signature = signature
	// TODO handle these errors. Probably can't do anything besides log, as we've already started to write the
	// response.
	_, err = writer.Write([]byte(xml.Header))
	encoder := xml.NewEncoder(writer)
	err = encoder.Encode(attrResp)
	err = encoder.Flush()
}
Example #2
0
func (generator *defaultGenerator) Generate(user *AuthenticatedUser, authnRequest *AuthnRequest, attributes map[string][]string) *Response {
	s := &Response{}
	s.Version = "2.0"
	s.ID = NewID()
	now := time.Now()
	fiveMinutes, _ := time.ParseDuration("5m")
	fiveFromNow := now.Add(fiveMinutes)
	s.IssueInstant = now
	s.Status = NewStatus(true)
	s.InResponseTo = authnRequest.ID
	s.Issuer = saml.NewIssuer(generator.entityId)
	assertion := &saml.Assertion{}
	assertion.ID = NewID()
	assertion.IssueInstant = now
	assertion.Version = "2.0"
	assertion.Issuer = s.Issuer
	nameId := &saml.NameID{}
	nameId.Format = user.Format
	nameId.NameQualifier = generator.entityId
	nameId.SPNameQualifier = authnRequest.Issuer
	nameId.Value = user.Name
	confirmation := &saml.SubjectConfirmation{}
	confirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
	confData := &saml.SubjectConfirmationData{}
	confData.Address = user.IP
	confData.InResponseTo = authnRequest.ID
	confData.Recipient = authnRequest.AssertionConsumerServiceURL
	confData.NotOnOrAfter = fiveFromNow
	confirmation.SubjectConfirmationData = confData
	subject := &saml.Subject{NameID: nameId, SubjectConfirmation: confirmation}
	assertion.Subject = subject
	conditions := &saml.Conditions{}
	conditions.NotOnOrAfter = fiveFromNow
	conditions.NotBefore = now
	audRestriction := &saml.AudienceRestriction{Audience: authnRequest.Issuer}
	conditions.AudienceRestriction = audRestriction
	assertion.Conditions = conditions
	authnStatement := &saml.AuthnStatement{}
	authnStatement.AuthnInstant = now
	authnStatement.SessionIndex = uuid.NewV4().String()
	subLoc := &saml.SubjectLocality{Address: confData.Address}
	authnStatement.SubjectLocality = subLoc
	authContext := &saml.AuthnContext{AuthnContextClassRef: user.Context}
	authnStatement.AuthnContext = authContext
	assertion.AuthnStatement = authnStatement
	assertion.AttributeStatement = saml.NewAttributeStatement(attributes)
	s.Assertion = assertion
	return s
}