...
1 package fosite
2
3 import (
4 "net/http"
5 "net/url"
6 "strings"
7
8 "github.com/ory/x/errorsx"
9 )
10
11 type AudienceMatchingStrategy func(haystack []string, needle []string) error
12
13 func DefaultAudienceMatchingStrategy(haystack []string, needle []string) error {
14 if len(needle) == 0 {
15 return nil
16 }
17
18 for _, n := range needle {
19 nu, err := url.Parse(n)
20 if err != nil {
21 return errorsx.WithStack(ErrInvalidRequest.WithHintf("Unable to parse requested audience '%s'.", n).WithWrap(err).WithDebug(err.Error()))
22 }
23
24 var found bool
25 for _, h := range haystack {
26 hu, err := url.Parse(h)
27 if err != nil {
28 return errorsx.WithStack(ErrInvalidRequest.WithHintf("Unable to parse whitelisted audience '%s'.", h).WithWrap(err).WithDebug(err.Error()))
29 }
30
31 allowedPath := strings.TrimRight(hu.Path, "/")
32 if nu.Scheme == hu.Scheme &&
33 nu.Host == hu.Host &&
34 (nu.Path == hu.Path ||
35 nu.Path == allowedPath ||
36 len(nu.Path) > len(allowedPath) && strings.TrimRight(nu.Path[:len(allowedPath)+1], "/")+"/" == allowedPath+"/") {
37 found = true
38 }
39 }
40
41 if !found {
42 return errorsx.WithStack(ErrInvalidRequest.WithHintf("Requested audience '%s' has not been whitelisted by the OAuth 2.0 Client.", n))
43 }
44 }
45
46 return nil
47 }
48
49
50
51
52
53 func ExactAudienceMatchingStrategy(haystack []string, needle []string) error {
54 if len(needle) == 0 {
55 return nil
56 }
57
58 for _, n := range needle {
59 var found bool
60 for _, h := range haystack {
61 if n == h {
62 found = true
63 }
64 }
65
66 if !found {
67 return errorsx.WithStack(ErrInvalidRequest.WithHintf(`Requested audience "%s" has not been whitelisted by the OAuth 2.0 Client.`, n))
68 }
69 }
70
71 return nil
72 }
73
74
75
76
77
78
79
80 func GetAudiences(form url.Values) []string {
81 audiences := form["audience"]
82 if len(audiences) > 1 {
83 return RemoveEmpty(audiences)
84 } else if len(audiences) == 1 {
85 return RemoveEmpty(strings.Split(audiences[0], " "))
86 } else {
87 return []string{}
88 }
89 }
90
91 func (f *Fosite) validateAuthorizeAudience(r *http.Request, request *AuthorizeRequest) error {
92 audience := GetAudiences(request.Form)
93
94 if err := f.AudienceMatchingStrategy(request.Client.GetAudience(), audience); err != nil {
95 return err
96 }
97
98 request.SetRequestedAudience(Arguments(audience))
99 return nil
100 }
101
View as plain text