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
58
59
60
61
62
63
64
65 public Saml2LoginContext(String relyingParty, String state, AuthnRequest request) throws MarshallingException {
66 super();
67
68 if (relyingParty == null || request == null) {
69 throw new IllegalArgumentException("SAML 2 authentication request and relying party ID may not be null");
70 }
71 setRelyingParty(relyingParty);
72 relayState = state;
73 serialAuthnRequest = serializeRequest(request);
74
75 setForceAuthRequired(request.isForceAuthn());
76 setPassiveAuthRequired(request.isPassive());
77 getRequestedAuthenticationMethods().addAll(extractRequestedAuthenticationMethods(request));
78 }
79
80
81
82
83
84
85
86
87 public synchronized String getAuthenticationRequest() throws UnmarshallingException {
88 return serialAuthnRequest;
89 }
90
91
92
93
94
95
96 public synchronized String getRelayState(){
97 return relayState;
98 }
99
100
101
102
103
104
105
106
107
108
109 protected String serializeRequest(AuthnRequest request) throws MarshallingException {
110 Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(request);
111 Element requestElem = marshaller.marshall(request);
112 StringWriter writer = new StringWriter();
113 XMLHelper.writeNode(requestElem, writer);
114 return writer.toString();
115 }
116
117
118
119
120
121
122
123
124
125 protected List<String> extractRequestedAuthenticationMethods(AuthnRequest request){
126 LazyList<String> requestedMethods = new LazyList<String>();
127
128 RequestedAuthnContext authnContext = request.getRequestedAuthnContext();
129 if (authnContext == null) {
130 return requestedMethods;
131 }
132
133
134 AuthnContextComparisonTypeEnumeration comparator = authnContext.getComparison();
135 if (comparator != null && comparator != AuthnContextComparisonTypeEnumeration.EXACT) {
136 Logger log = LoggerFactory.getLogger(Saml2LoginContext.class);
137 log.warn("Unsupported comparision operator ( " + comparator
138 + ") in RequestedAuthnContext. Only exact comparisions are supported.");
139 return requestedMethods;
140 }
141
142
143 List<AuthnContextClassRef> authnClasses = authnContext.getAuthnContextClassRefs();
144 if (authnClasses != null) {
145 for (AuthnContextClassRef classRef : authnClasses) {
146 if (classRef != null && !DatatypeHelper.isEmpty(classRef.getAuthnContextClassRef())) {
147 requestedMethods.add(classRef.getAuthnContextClassRef());
148 }
149 }
150 }
151
152 List<AuthnContextDeclRef> authnDeclRefs = authnContext.getAuthnContextDeclRefs();
153 if (authnDeclRefs != null) {
154 for (AuthnContextDeclRef declRef : authnDeclRefs) {
155 if (declRef != null&& !DatatypeHelper.isEmpty(declRef.getAuthnContextDeclRef())) {
156 requestedMethods.add(declRef.getAuthnContextDeclRef());
157 }
158 }
159 }
160
161 if(requestedMethods.contains(AuthnContext.UNSPECIFIED_AUTHN_CTX)){
162 requestedMethods.clear();
163 }
164
165 return requestedMethods;
166 }
167 }