1
+ package com .onelogin .saml2 .authn ;
2
+
3
+ import java .net .URL ;
4
+
5
+ import com .onelogin .saml2 .model .AssertionConsumerService ;
6
+ import com .onelogin .saml2 .settings .Saml2Settings ;
7
+
8
+ /**
9
+ * Interfaced used to select the Assertion Consumer Service (ACS) to be
10
+ * specified in an authentication request. An instance of this interface can be
11
+ * passed as an input parameter in a {@link AuthnRequestParams} to be used when
12
+ * initiating a login operation.
13
+ * <p>
14
+ * A set of predefined implementations are provided: they should cover the most
15
+ * common cases.
16
+ */
17
+ @ FunctionalInterface
18
+ public interface AssertionConsumerServiceSelector {
19
+
20
+ /**
21
+ * Simple class holding data used to select an Assertion Consumer Service (ACS)
22
+ * within an authentication request.
23
+ * <p>
24
+ * The index, if specified, has priority over the pair URL/protocol binding.
25
+ */
26
+ static class AssertionConsumerServiceSelection {
27
+ /** Assertion Consumer Service index. */
28
+ public final Integer index ;
29
+ /** Assertion Consumer Service URL. */
30
+ public final URL url ;
31
+ /** Assertion Consumer Service protocol binding. */
32
+ public final String protocolBinding ;
33
+
34
+ /**
35
+ * Creates an Assertion Consumer Service selection by index.
36
+ *
37
+ * @param index
38
+ * the ACS index
39
+ */
40
+ public AssertionConsumerServiceSelection (final int index ) {
41
+ this .index = index ;
42
+ this .url = null ;
43
+ this .protocolBinding = null ;
44
+ }
45
+
46
+ /**
47
+ * Creates an Assertion Consumer Service selection by URL and protocol binding.
48
+ *
49
+ * @param url
50
+ * the ACS URL
51
+ * @param protocolBinding
52
+ * the ACS protocol binding
53
+ */
54
+ public AssertionConsumerServiceSelection (final URL url , final String protocolBinding ) {
55
+ this .index = null ;
56
+ this .url = url ;
57
+ this .protocolBinding = protocolBinding ;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * @return a selector that will cause the authentication request not to specify
63
+ * any Assertion Consumer Service, letting the IdP determine which is
64
+ * the default one; if the agreement between the SP and the IdP to map
65
+ * Assertion Consumer Services is based on metadata, it means that the
66
+ * IdP is expected to select the ACS marked there as being the default
67
+ * one (or the only declared ACS, if just one exists and hopefully not
68
+ * explicitly set as <strong>not</strong> being the default one...);
69
+ * indeed, in sane cases the final selection result is expected to be
70
+ * the same the one provided by
71
+ * {@link AssertionConsumerServiceSelector#useDefaultByIndex(Saml2Settings)}
72
+ * and
73
+ * {@link AssertionConsumerServiceSelector#useDefaultByUrlAndBinding(Saml2Settings)},
74
+ * with those two however causing an explicit indication of the choice
75
+ * being made by the SP in the authentication request, indication that
76
+ * the IdP must then respect
77
+ */
78
+ static AssertionConsumerServiceSelector useImplicitDefault () {
79
+ return () -> null ;
80
+ }
81
+
82
+ /**
83
+ * @param settings
84
+ * the SAML settings, containing the list of the available
85
+ * Assertion Consumer Services (see
86
+ * {@link Saml2Settings#getSpAssertionConsumerServices()})
87
+ * @return a selector that will cause the authentication request to explicitly
88
+ * specify the default Assertion Consumer Service declared in a set of
89
+ * SAML settings, selecting it by index; if no default ACS could be
90
+ * unambiguously detected, this falls back to
91
+ * {@link #useImplicitDefault()}
92
+ * @see Saml2Settings#getSpAssertionConsumerServices()
93
+ * @see Saml2Settings#getSpDefaultAssertionConsumerService()
94
+ */
95
+ static AssertionConsumerServiceSelector useDefaultByIndex (final Saml2Settings settings ) {
96
+ return settings .getSpDefaultAssertionConsumerService ().map (AssertionConsumerServiceSelector ::byIndex )
97
+ .orElse (useImplicitDefault ());
98
+ }
99
+
100
+ /**
101
+ * @param settings
102
+ * the SAML settings, containing the list of the available
103
+ * Assertion Consumer Services (see
104
+ * {@link Saml2Settings#getSpAssertionConsumerServices()})
105
+ * @return a selector that will cause the authentication request to explicitly
106
+ * specify the default Assertion Consumer Service declared in a set of
107
+ * SAML settings, selecting it by URL and protocol binding; if no
108
+ * default ACS could be unambiguously detected, this falls back to
109
+ * {@link #useImplicitDefault()}
110
+ * @see Saml2Settings#getSpAssertionConsumerServices()
111
+ * @see Saml2Settings#getSpDefaultAssertionConsumerService()
112
+ */
113
+ static AssertionConsumerServiceSelector useDefaultByUrlAndBinding (final Saml2Settings settings ) {
114
+ return settings .getSpDefaultAssertionConsumerService ().map (AssertionConsumerServiceSelector ::byUrlAndBinding )
115
+ .orElse (useImplicitDefault ());
116
+ }
117
+
118
+ /**
119
+ * @param assertionConsumerService
120
+ * the Assertion Consumer Service to select
121
+ * @return a selector that chooses the specified Assertion Consumer Service by
122
+ * index
123
+ */
124
+ static AssertionConsumerServiceSelector byIndex (final AssertionConsumerService assertionConsumerService ) {
125
+ return byIndex (assertionConsumerService .getIndex ());
126
+ }
127
+
128
+ /**
129
+ * @param assertionConsumerService
130
+ * the Assertion Consumer Service to select
131
+ * @return a selector that chooses the specified Assertion Consumer Service by
132
+ * location URL and protocol binding
133
+ */
134
+ static AssertionConsumerServiceSelector byUrlAndBinding (final AssertionConsumerService assertionConsumerService ) {
135
+ return () -> new AssertionConsumerServiceSelection (assertionConsumerService .getLocation (),
136
+ assertionConsumerService .getBinding ());
137
+ }
138
+
139
+ /**
140
+ * @param index
141
+ * the index of the Assertion Consumer Service to select
142
+ * @return a selector that chooses the Assertion Consumer Service with the given
143
+ * index
144
+ */
145
+ static AssertionConsumerServiceSelector byIndex (final int index ) {
146
+ return () -> new AssertionConsumerServiceSelection (index );
147
+ }
148
+
149
+ /**
150
+ * @param url
151
+ * the URL of the Assertion Consumer Service to select
152
+ * @param protocolBinding
153
+ * the protocol binding of the Assertion Consumer Service to select
154
+ * @return a selector that chooses the Assertion Consumer Service with the given
155
+ * URL and protocol binding
156
+ */
157
+ static AssertionConsumerServiceSelector byUrlAndBinding (final URL url , final String protocolBinding ) {
158
+ return () -> new AssertionConsumerServiceSelection (url , protocolBinding );
159
+ }
160
+
161
+ /**
162
+ * Returns a description of the selected Assertion Consumer Service.
163
+ *
164
+ * @return the service index, or <code>null</code> if the default one should be
165
+ * selected
166
+ */
167
+ AssertionConsumerServiceSelection getAssertionConsumerServiceSelection ();
168
+ }
0 commit comments