1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package edu.internet2.middleware.shibboleth.idp.authn;
19
20 import java.io.Serializable;
21 import java.io.StringWriter;
22 import java.util.List;
23
24 import org.opensaml.Configuration;
25 import org.opensaml.saml2.core.AuthnContext;
26 import org.opensaml.saml2.core.AuthnContextClassRef;
27 import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
28 import org.opensaml.saml2.core.AuthnContextDeclRef;
29 import org.opensaml.saml2.core.AuthnRequest;
30 import org.opensaml.saml2.core.RequestedAuthnContext;
31 import org.opensaml.xml.io.Marshaller;
32 import org.opensaml.xml.io.MarshallingException;
33 import org.opensaml.xml.io.UnmarshallingException;
34 import org.opensaml.xml.util.DatatypeHelper;
35 import org.opensaml.xml.util.LazyList;
36 import org.opensaml.xml.util.XMLHelper;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.w3c.dom.Element;
40
41
42
43
44
45
46 public class Saml2LoginContext extends LoginContext implements Serializable {
47
48
49 private static final long serialVersionUID = -7117092606828289070L;
50
51
52 private String relayState;
53
54
55 private String serialAuthnRequest;
56
57
58 private boolean unsolicited;
59
60
61
62
63
64
65
66
67
68
69 public Saml2LoginContext(String relyingParty, String state, AuthnRequest request) throws MarshallingException {
70 super();
71
72 if (relyingParty == null || request == null) {
73 throw new IllegalArgumentException("SAML 2 authentication request and relying party ID may not be null");
74 }
75 setRelyingParty(relyingParty);
76 relayState = state;
77 serialAuthnRequest = serializeRequest(request);
78
79 setForceAuthRequired(request.isForceAuthn());
80 setPassiveAuthRequired(request.isPassive());
81 getRequestedAuthenticationMethods().addAll(extractRequestedAuthenticationMethods(request));
82 }
83
84
85
86
87
88
89
90
91 public synchronized String getAuthenticationRequest() throws UnmarshallingException {
92 return serialAuthnRequest;
93 }
94
95
96
97
98
99
100 public synchronized String getRelayState(){
101 return relayState;
102 }
103
104
105
106
107
108
109 public boolean isUnsolicited() {
110 return unsolicited;
111 }
112
113
114
115
116
117
118 public void setUnsolicited(boolean unsolicited) {
119 this.unsolicited = unsolicited;
120 }
121
122
123
124
125
126
127
128
129
130
131 protected String serializeRequest(AuthnRequest request) throws MarshallingException {
132 Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(request);
133 Element requestElem = marshaller.marshall(request);
134 StringWriter writer = new StringWriter();
135 XMLHelper.writeNode(requestElem, writer);
136 return writer.toString();
137 }
138
139
140
141
142
143
144
145
146
147 protected List<String> extractRequestedAuthenticationMethods(AuthnRequest request){
148 LazyList<String> requestedMethods = new LazyList<String>();
149
150 RequestedAuthnContext authnContext = request.getRequestedAuthnContext();
151 if (authnContext == null) {
152 return requestedMethods;
153 }
154
155
156 AuthnContextComparisonTypeEnumeration comparator = authnContext.getComparison();
157 if (comparator != null && comparator != AuthnContextComparisonTypeEnumeration.EXACT) {
158 Logger log = LoggerFactory.getLogger(Saml2LoginContext.class);
159 log.warn("Unsupported comparision operator ( " + comparator
160 + ") in RequestedAuthnContext. Only exact comparisions are supported.");
161 return requestedMethods;
162 }
163
164
165 List<AuthnContextClassRef> authnClasses = authnContext.getAuthnContextClassRefs();
166 if (authnClasses != null) {
167 for (AuthnContextClassRef classRef : authnClasses) {
168 if (classRef != null && !DatatypeHelper.isEmpty(classRef.getAuthnContextClassRef())) {
169 requestedMethods.add(classRef.getAuthnContextClassRef());
170 }
171 }
172 }
173
174 List<AuthnContextDeclRef> authnDeclRefs = authnContext.getAuthnContextDeclRefs();
175 if (authnDeclRefs != null) {
176 for (AuthnContextDeclRef declRef : authnDeclRefs) {
177 if (declRef != null&& !DatatypeHelper.isEmpty(declRef.getAuthnContextDeclRef())) {
178 requestedMethods.add(declRef.getAuthnContextDeclRef());
179 }
180 }
181 }
182
183 if(requestedMethods.contains(AuthnContext.UNSPECIFIED_AUTHN_CTX)){
184 requestedMethods.clear();
185 }
186
187 return requestedMethods;
188 }
189 }