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