<resolver:AttributeDefinition xsi:type="PrincipalName" xmlns="urn:mace:shibboleth:2.0:resolver:ad" id="userLogin" > <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="userLogin" /> <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="userLogin" /> </resolver:AttributeDefinition>
<afp:AttributeFilterPolicy id="releaseUserLoginToAnyone"> <afp:PolicyRequirementRule xsi:type="basic:ANY"/> <afp:AttributeRule attributeID="userLogin"> <afp:PermitValueRule xsi:type="basic:ANY"/> </afp:AttributeRule> </afp:AttributeFilterPolicy>
<rp:RelyingParty id="sp.local.ru" provider="https://idp.local.ru/idp/shibboleth" defaultSigningCredentialRef="IdPCredential"> <rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" signResponses="never" signAssertions="never" encryptNameIds="never" encryptAssertions="never" /> </rp:RelyingParty>
<metadata:MetadataProvider id="spMD" xsi:type="metadata:FilesystemMetadataProvider" metadataFile="/opt/shib/metadata/saml-sp-metadata.xml"/>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="sp.local.ru"> <md:SPSSODescriptor AuthnRequestsSigned="false" ID="sp.local.ru" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://sp.local.ru:8443/sso/acs" index="1" isDefault="true"/> </md:SPSSODescriptor> </md:EntityDescriptor>
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLImplementation="edu.internet2.middleware.security.tomcat6.DelegateToApplicationJSSEmplementation" scheme="https" SSLEnabled="true" clientAuth="want" keystoreFile="$shHome/credentials/idp.jks" keystorePass="$shPassword" />
<Context docBase="$shHome/war/idp.war" privileged="true" antiResourceLocking="false" antiJARLocking="false" unpackWAR="false" swallowOutput="true" />
public class RemoteUserValve extends ValveBase{ public RemoteUserValve() { } @Override public void invoke(final Request request, final Response response) throws IOException, ServletException { final String username = "idpuser"; final String credentials = "idppass"; final List<String> roles = new ArrayList<String>(); final Principal principal = new GenericPrincipal(null, username, credentials, roles); request.setUserPrincipal(principal); getNext().invoke(request, response); } }
<source lang="xml"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ru.eastbanctech.web</groupId> <artifactId>saml-sp-filter</artifactId> <name>${project.artifactId}</name> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <jdk.version>1.6</jdk.version> <encoding>UTF-8</encoding> <project.build.sourceEncoding>${encoding}</project.build.sourceEncoding> <project.reporting.outputEncoding>${encoding}</project.reporting.outputEncoding> </properties> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <encoding>${encoding}</encoding> <soure>${jdk.version}</soure> <target>${jdk.version}</target> </configuration> </plugin> </plugins> </pluginManagement> </build> <dependency> <groupId>org.opensaml</groupId> <artifactId>opensaml</artifactId> <version>2.5.1-1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.1</version> </dependency> </dependencies> </project>
public class SAMLSPFilter implements Filter { public static final String SAML_AUTHN_RESPONSE_PARAMETER_NAME = "SAMLResponse"; private static Logger log = LoggerFactory.getLogger(SAMLSPFilter.class); private FilterConfig filterConfig; private SAMLResponseVerifier checkSAMLResponse; private SAMLRequestSender samlRequestSender; @Override public void init(javax.servlet.FilterConfig config) throws ServletException { OpenSamlBootstrap.init(); filterConfig = new FilterConfig(config); checkSAMLResponse = new SAMLResponseVerifier(); samlRequestSender = new SAMLRequestSender(); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; /* 1: , 2: Shibboleth idP, 3: logout, 4: , 5: SAML Shibboleth idP */ } }
public class FilterConfig { /** * The parameters below should be defined in web.xml file of Java Web Application */ public static final String EXCLUDED_URL_PATTERN_PARAMETER = "excludedUrlPattern"; public static final String SP_ACS_URL_PARAMETER = "acsUrl"; public static final String SP_ID_PARAMETER = "spProviderId"; public static final String SP_LOGOUT_URL_PARAMETER = "logoutUrl"; public static final String IDP_SSO_URL_PARAMETER = "idProviderSSOUrl"; private String excludedUrlPattern; private String acsUrl; private String spProviderId; private String logoutUrl; private String idpSSOUrl; public FilterConfig(javax.servlet.FilterConfig config) { excludedUrlPattern = config.getInitParameter(EXCLUDED_URL_PATTERN_PARAMETER); acsUrl = config.getInitParameter(SP_ACS_URL_PARAMETER); spProviderId = config.getInitParameter(SP_ID_PARAMETER); idpSSOUrl = config.getInitParameter(IDP_SSO_URL_PARAMETER); logoutUrl = config.getInitParameter(SP_LOGOUT_URL_PARAMETER); } // getters and should be defined below } OpenSamlBootstrap SAML 2.0 : public class OpenSamlBootstrap extends DefaultBootstrap { private static Logger log = LoggerFactory.getLogger(OpenSamlBootstrap.class); private static boolean initialized; private static String[] xmlToolingConfigs = { "/default-config.xml", "/encryption-validation-config.xml", "/saml2-assertion-config.xml", "/saml2-assertion-delegation-restriction-config.xml", "/saml2-core-validation-config.xml", "/saml2-metadata-config.xml", "/saml2-metadata-idp-discovery-config.xml", "/saml2-metadata-query-config.xml", "/saml2-metadata-validation-config.xml", "/saml2-protocol-config.xml", "/saml2-protocol-thirdparty-config.xml", "/schema-config.xml", "/signature-config.xml", "/signature-validation-config.xml" }; public static synchronized void init() { if (!initialized) { try { initializeXMLTooling(xmlToolingConfigs); } catch (ConfigurationException e) { log.error("Unable to initialize opensaml DefaultBootstrap", e); } initializeGlobalSecurityConfiguration(); initialized = true; } } }
if (!isFilteredRequest(request)) { log.debug("According to {} configuration parameter request is ignored + {}", new Object[]{FilterConfig.EXCLUDED_URL_PATTERN, request.getRequestURI()}); chain.doFilter(servletRequest, servletResponse); return; } // , private boolean isFilteredRequest(HttpServletRequest request) { return !(filterConfig.getExcludedUrlPattern() != null && getCorrectURL(request).matches(filterConfig.getExcludedUrlPattern())); } // URL private String getCorrectURL(HttpServletRequest request) { String contextPath = request.getContextPath(); String requestUri = request.getRequestURI(); int contextBeg = requestUri.indexOf(contextPath); int contextEnd = contextBeg + contextPath.length(); String slash = "/"; String url = (contextBeg < 0 || contextEnd == (requestUri.length() - 1)) ? requestUri : requestUri.substring(contextEnd); if (!url.startsWith(slash)) { url = slash + url; } return url; }
log.debug("Attempt to secure resource is intercepted : {}", ((HttpServletRequest) servletRequest).getRequestURL().toString()); /* Check if response message is received from identity provider; In case of successful response system redirects user to relayState (initial) request */ String responseMessage = servletRequest.getParameter(SAML_AUTHN_RESPONSE_PARAMETER_NAME); if (responseMessage != null) { log.debug("Response from Identity Provider is received"); try { log.debug("Decoding of SAML message"); SAMLMessageContext samlMessageContext = SAMLUtils.decodeSamlMessage((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse); log.debug("SAML message has been decoded successfully"); samlMessageContext.setLocalEntityId(filterConfig.getSpProviderId()); String relayState = getInitialRequestedResource(samlMessageContext); checkSAMLResponse.verify(samlMessageContext); log.debug("Starting and store SAML session.."); SAMLSessionManager.getInstance().createSAMLSession(request.getSession(), samlMessageContext); log.debug("User has been successfully authenticated in idP. Redirect to initial requested resource {}", relayState); response.sendRedirect(relayState); return; } catch (Exception e) { throw new ServletException(e); } }
public class SAMLUtils { public static SAMLMessageContext decodeSamlMessage(HttpServletRequest request, HttpServletResponse response) throws Exception { SAMLMessageContext<SAMLObject, SAMLObject, NameID> samlMessageContext = new BasicSAMLMessageContext<SAMLObject, SAMLObject, NameID>(); HttpServletRequestAdapter httpServletRequestAdapter = new HttpServletRequestAdapter(request); samlMessageContext.setInboundMessageTransport(httpServletRequestAdapter); samlMessageContext.setInboundSAMLProtocol(SAMLConstants.SAML20P_NS); HttpServletResponseAdapter httpServletResponseAdapter = new HttpServletResponseAdapter(response, request.isSecure()); samlMessageContext.setOutboundMessageTransport(httpServletResponseAdapter); samlMessageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME); SecurityPolicyResolver securityPolicyResolver = getSecurityPolicyResolver(request.isSecure()); samlMessageContext.setSecurityPolicyResolver(securityPolicyResolver); HTTPPostDecoder samlMessageDecoder = new HTTPPostDecoder(); samlMessageDecoder.decode(samlMessageContext); return samlMessageContext; } private static SecurityPolicyResolver getSecurityPolicyResolver(boolean isSecured) { SecurityPolicy securityPolicy = new BasicSecurityPolicy(); HTTPRule httpRule = new HTTPRule(null, null, isSecured); MandatoryIssuerRule mandatoryIssuerRule = new MandatoryIssuerRule(); List<SecurityPolicyRule> securityPolicyRules = securityPolicy.getPolicyRules(); securityPolicyRules.add(httpRule); securityPolicyRules.add(mandatoryIssuerRule); return new StaticSecurityPolicyResolver(securityPolicy); } }
public static String SAMLObjectToString(XMLObject samlObject) { try { Marshaller marshaller = org.opensaml.Configuration.getMarshallerFactory().getMarshaller(samlObject); org.w3c.dom.Element authDOM = marshaller.marshall(samlObject); StringWriter rspWrt = new StringWriter(); XMLHelper.writeNode(authDOM, rspWrt); return rspWrt.toString(); } catch (Exception e) { e.printStackTrace(); } return null; }
public class SAMLResponseVerifier { private static Logger log = LoggerFactory.getLogger(SAMLResponseVerifier.class); private SAMLRequestStore samlRequestStore = SAMLRequestStore.getInstance(); public void verify(SAMLMessageContext<Response, SAMLObject, NameID> samlMessageContext) throws SAMLException { Response samlResponse = samlMessageContext.getInboundSAMLMessage(); log.debug("SAML Response message : {}", SAMLUtils.SAMLObjectToString(samlResponse)); verifyInResponseTo(samlResponse); Status status = samlResponse.getStatus(); StatusCode statusCode = status.getStatusCode(); String statusCodeURI = statusCode.getValue(); if (!statusCodeURI.equals(StatusCode.SUCCESS_URI)) { log.warn("Incorrect SAML message code : {} ", statusCode.getStatusCode().getValue()); throw new SAMLException("Incorrect SAML message code : " + statusCode.getValue()); } if (samlResponse.getAssertions().size() == 0) { log.error("Response does not contain any acceptable assertions"); throw new SAMLException("Response does not contain any acceptable assertions"); } Assertion assertion = samlResponse.getAssertions().get(0); NameID nameId = assertion.getSubject().getNameID(); if (nameId == null) { log.error("Name ID not present in subject"); throw new SAMLException("Name ID not present in subject"); } log.debug("SAML authenticated user " + nameId.getValue()); verifyConditions(assertion.getConditions(), samlMessageContext); } private void verifyInResponseTo(Response samlResponse) { String key = samlResponse.getInResponseTo(); if (!samlRequestStore.exists(key)) { { log.error("Response does not match an authentication request"); throw new RuntimeException("Response does not match an authentication request"); } samlRequestStore.removeRequest(samlResponse.getInResponseTo()); } private void verifyConditions(Conditions conditions, SAMLMessageContext samlMessageContext) throws SAMLException{ verifyExpirationConditions(conditions); verifyAudienceRestrictions(conditions.getAudienceRestrictions(), samlMessageContext); } private void verifyExpirationConditions(Conditions conditions) throws SAMLException { log.debug("Verifying conditions"); DateTime currentTime = new DateTime(DateTimeZone.UTC); log.debug("Current time in UTC : " + currentTime); DateTime notBefore = conditions.getNotBefore(); log.debug("Not before condition : " + notBefore); if ((notBefore != null) && currentTime.isBefore(notBefore)) throw new SAMLException("Assertion is not conformed with notBefore condition"); DateTime notOnOrAfter = conditions.getNotOnOrAfter(); log.debug("Not on or after condition : " + notOnOrAfter); if ((notOnOrAfter != null) && currentTime.isAfter(notOnOrAfter)) throw new SAMLException("Assertion is not conformed with notOnOrAfter condition"); } private void verifyAudienceRestrictions( List<AudienceRestriction> audienceRestrictions, SAMLMessageContext<?, ?, ?> samlMessageContext) throws SAMLException{ // TODO: Audience restrictions should be defined below<sup>7</sup> } }
final public class SAMLRequestStore { private Set<String> samlRequestStorage = new HashSet<String>(); private IdentifierGenerator identifierGenerator = new RandomIdentifierGenerator(); private static SAMLRequestStore instance = new SAMLRequestStore(); private SAMLRequestStore() { } public static SAMLRequestStore getInstance() { return instance; } public synchronized void storeRequest(String key) { if (samlRequestStorage.contains(key)) throw new RuntimeException("SAML request storage has already contains key " + key); samlRequestStorage.add(key); } public synchronized String storeRequest(){ String key = null; while (true) { key = identifierGenerator.generateIdentifier(20); if (!samlRequestStorage.contains(key)){ storeRequest(key); break; } } return key; } public synchronized boolean exists(String key) { return samlRequestStorage.contains(key); } public synchronized void removeRequest(String key) { samlRequestStorage.remove(key); } }
public class SAMLSessionInfo { private String nameId; private Map<String, String> attributes; private Date validTo; public SAMLSessionInfo(String nameId, Map<String, String> attributes, Date validTo) { this.nameId = nameId; this.attributes = attributes; this.validTo = validTo; } // getters should be defined below }
<source lang="java"> public class SAMLSessionManager { public static String SAML_SESSION_INFO = "SAML_SESSION_INFO"; private static SAMLSessionManager instance = new SAMLSessionManager(); private SAMLSessionManager() { } public static SAMLSessionManager getInstance() { return instance; } public void createSAMLSession(HttpSession session, SAMLMessageContext<Response, SAMLObject, NameID> samlMessageContext) { List<Assertion> assertions = samlMessageContext.getInboundSAMLMessage().getAssertions(); NameID nameId = (assertions.size() != 0 && assertions.get(0).getSubject() != null) ? assertions.get(0).getSubject().getNameID() : null; String nameValue = nameId == null ? null : nameId.getValue(); SAMLSessionInfo samlSessionInfo = new SAMLSessionInfo(nameValue, getAttributesMap(getSAMLAttributes(assertions)), getSAMLSessionValidTo(assertions)); session.setAttribute(SAML_SESSION_INFO, samlSessionInfo); } public boolean isSAMLSessionValid(HttpSession session) { SAMLSessionInfo samlSessionInfo = (SAMLSessionInfo) session.getAttribute(SAML_SESSION_INFO); if (samlSessionInfo == null) return false; return samlSessionInfo.getValidTo() == null || new Date().before(samlSessionInfo.getValidTo()); } public void destroySAMLSession(HttpSession session) { session.removeAttribute(SAML_SESSION_INFO); } public List<Attribute> getSAMLAttributes(List<Assertion> assertions) { List<Attribute> attributes = new ArrayList<Attribute>(); if (assertions != null) { for (Assertion assertion : assertions) { for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) { for (Attribute attribute : attributeStatement.getAttributes()) { attributes.add(attribute); } } } } return attributes; } public Date getSAMLSessionValidTo(List<Assertion> assertions) { org.joda.time.DateTime sessionNotOnOrAfter = null; if (assertions != null) { for (Assertion assertion : assertions) { for (AuthnStatement statement : assertion.getAuthnStatements()) { sessionNotOnOrAfter = statement.getSessionNotOnOrAfter(); } } } return sessionNotOnOrAfter != null ? sessionNotOnOrAfter.toCalendar(Locale.getDefault()).getTime() : null; } public Map<String, String> getAttributesMap(List<Attribute> attributes) { Map<String, String> result = new HashMap<String, String>(); for (Attribute attribute : attributes) { result.put(attribute.getName(), attribute.getDOM().getTextContent()); } return result; } }
if (getCorrectURL(request).equals(filterConfig.getLogoutUrl())) { log.debug("Logout action: destroying SAML session."); SAMLSessionManager.getInstance().destroySAMLSession(request.getSession()); chain.doFilter(request, response); return; }
if (SAMLSessionManager.getInstance().isSAMLSessionValid(request.getSession())) { log.debug("SAML session exists and valid: grant access to secure resource"); chain.doFilter(request, response); return; }
log.debug("Sending authentication request to idP"); try { samlRequestSender .sendSAMLAuthRequest(request, response, filterConfig.getSpProviderId(), filterConfig.getAcsUrl(), filterConfig.getIdpSSOUrl()); } catch (Exception e) { throw new ServletException(e); }
<source lang="java"> public class SAMLRequestSender { private static Logger log = LoggerFactory.getLogger(SAMLRequestSender.class); private SAMLAuthnRequestBuilder samlAuthnRequestBuilder = new SAMLAuthnRequestBuilder(); private MessageEncoder messageEncoder = new MessageEncoder(); public void sendSAMLAuthRequest(HttpServletRequest request, HttpServletResponse servletResponse, String spId, String acsUrl, String idpSSOUrl) throws Exception { String redirectURL; String idpUrl = idpSSOUrl; AuthnRequest authnRequest = samlAuthnRequestBuilder.buildRequest(spId, acsUrl, idpUrl); // store SAML 2.0 authentication request String key = SAMLRequestStore.getInstance().storeRequest(); authnRequest.setID(key); log.debug("SAML Authentication message : {} ", SAMLUtils.SAMLObjectToString(authnRequest)); redirectURL = messageEncoder.encode(authnRequest, idpUrl, request.getRequestURI()); HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter(servletResponse, request.isSecure()); HTTPTransportUtils.addNoCacheHeaders(responseAdapter); HTTPTransportUtils.setUTF8Encoding(responseAdapter); responseAdapter.sendRedirect(redirectURL); } private static class SAMLAuthnRequestBuilder { public AuthnRequest buildRequest(String spProviderId, String acsUrl, String idpUrl){ /* Building Issuer object */ IssuerBuilder issuerBuilder = new IssuerBuilder(); Issuer issuer = issuerBuilder.buildObject("urn:oasis:names:tc:SAML:2.0:assertion", "Issuer", "saml2p"); issuer.setValue(spProviderId); /* Creation of AuthRequestObject */ DateTime issueInstant = new DateTime(); AuthnRequestBuilder authRequestBuilder = new AuthnRequestBuilder(); AuthnRequest authRequest = authRequestBuilder.buildObject(SAMLConstants.SAML20P_NS, "AuthnRequest", "saml2p"); authRequest.setForceAuthn(false); authRequest.setIssueInstant(issueInstant); authRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI); authRequest.setAssertionConsumerServiceURL(acsUrl); authRequest.setIssuer(issuer); authRequest.setNameIDPolicy(nameIdPolicy); authRequest.setVersion(SAMLVersion.VERSION_20); authRequest.setDestination(idpUrl); return authRequest; } } private static class MessageEncoder extends HTTPRedirectDeflateEncoder { public String encode(SAMLObject message, String endpointURL, String relayState) throws MessageEncodingException { String encodedMessage = deflateAndBase64Encode(message); return buildRedirectURL(endpointURL, relayState, encodedMessage); } public String buildRedirectURL(String endpointURL, String relayState, String message) throws MessageEncodingException { URLBuilder urlBuilder = new URLBuilder(endpointURL); List<Pair<String, String>> queryParams = urlBuilder.getQueryParams(); queryParams.clear(); queryParams.add(new Pair<String, String>("SAMLRequest", message)); if (checkRelayState(relayState)) { queryParams.add(new Pair<String, String>("RelayState", relayState)); } return urlBuilder.buildURL(); } } }
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://sp.local.ru:8443/sso/acs" Destination="https://idp.local.ru:8443/idp/profile/SAML2/Redirect/SSO" ForceAuthn="false" ID="_0ddb303f9500839762eabd30e7b1e3c28b596c69" IssueInstant="2013-09-12T09:46:41.882Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"> <saml2p:Issuer xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:assertion">sp.local.ru</saml2p:Issuer> </saml2p:AuthnRequest>
<source lang="xml"> <saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://sp.local.ru:8443/sso/acs" ID="_9c5e6028df334510cce22409ddbca6ac" InResponseTo="_0ddb303f9500839762eabd30e7b1e3c28b596c69" IssueInstant="2013-09-12T10:13:35.177Z" Version="2.0"> <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"> https://idp.local.ru/idp/shibboleth </saml2:Issuer> <saml2p:Status> <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </saml2p:Status> <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_0a299e86f4b17b5e047735121a880ccb" IssueInstant="2013-09-12T10:13:35.177Z" version="2.0"> <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"> https://idp.local.ru/idp/shibboleth </saml2:Issuer> <saml2:Subject> <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" NameQualifier="https://idp.local.ru/idp/shibboleth"> _f1de09ee54294d4b5ddeb3aa5e6d2aab </saml2:NameID> <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml2:SubjectConfirmationData Address="127.0.0.1" InResponseTo="_0ddb303f9500839762eabd30e7b1e3c28b596c69" NotOnOrAfter="2013-09-12T10:18:35.177Z" Recipient="https://sp.local.ru:8443/sso/acs"/> </saml2:SubjectConfirmation> </saml2:Subject> <saml2:Conditions NotBefore="2013-09-12T10:13:35.177Z" NotOnOrAfter="2013-09-12T10:18:35.177Z"> <saml2:AudienceRestriction> <saml2:Audience>sp.local.ru</saml2:Audience> </saml2:AudienceRestriction> </saml2:Conditions> <saml2:AuthnStatement AuthnInstant="2013-09-12T10:13:35.137Z" SessionIndex="_91826738984ca8bef18a8450135b1821"> <saml2:SubjectLocality Address="127.0.0.1"/> <saml2:AuthnContext> <saml2:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml2:AuthnContextClassRef> </saml2:AuthnContext> </saml2:AuthnStatement> <saml2:AttributeStatement> <saml2:Attribute Name="userLogin" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">idpuser</saml2:AttributeValue> </saml2:Attribute> </saml2:AttributeStatement> </saml2:Assertion> </saml2p:Response>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId> ru.eastbanctech.web</groupId> <artifactId>SimpleSSOApplication</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>SimpleSSOApplication</name> <url>http://maven.apache.org</url> <!-- --> <properties> <sp.id>sp.local.ru</sp.id> <acs.url>https://sp.local.ru:8443/sso/acs</acs.url> <idp.sso.url>https://idp.local.ru:8443/idp/profile/SAML2/Redirect/SSO</idp.sso.url> <logout.url>/logout</logout.url> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId> ru.eastbanctech.web</groupId> <artifactId>saml-sp-filter</artifactId> <version>1.0-SNAPSHOT</version> </dependency><sup>8</sup> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.1</version> </dependency> </dependencies> <build> <finalName>sso</finalName> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <webResources> <resource> <filtering>true</filtering> <directory>src/main/webapp/WEB-INF</directory> <targetPath>WEB-INF</targetPath> <includes> <include>**/*.xml</include> </includes> </resource> </webResources> </configuration> </plugin> </plugins> </build> </project>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Simple SSO Java Web Application</display-name>7. <filter> <filter-name>SSOFilter</filter-name> <filter-class> ru.eastbanctech.java.web.filter.saml.SAMLSPFilter</filter-class> <init-param> <param-name>excludedUrlPattern</param-name> <param-value>.*\.jpg</param-value> </init-param> <init-param> <param-name>idProviderSSOUrl</param-name> <param-value> ${idp.sso.url}</param-value> </init-param> <init-param> <param-name>spProviderId</param-name> <param-value>${sp.id}</param-value> </init-param> <init-param> <param-name>acsUrl</param-name> <param-value>${acs.url}</param-value> </init-param> <init-param> <param-name>logoutUrl</param-name> <param-value>${logout.url}</param-value> </init-param> </filter> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/pages/private/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>${logout.url}</url-pattern> </filter-mapping> <filter-mapping> <filter-name>SSOFilter</filter-name> <url-pattern>/acs</url-pattern> </filter-mapping> </web-app>
<%@ page import=" ru.eastbanctech.java.web.filter.saml.store.SAMLSessionManager" %> <%@ page import=" ru.eastbanctech.java.web.filter.saml.store.SAMLSessionInfo" %> <%@ page import="java.util.Map" %> <html> <body> <h2>Private Resource</h2> <% SAMLSessionInfo info = (SAMLSessionInfo)request.getSession().getAttribute(SAMLSessionManager.SAML_SESSION_INFO); out.println("User id = " + info.getNameId() + " "); out.println("<TABLE> <TR> <TH> Attribute name </TH> <TH> Attribulte value </TH></TR>"); for (Map.Entry entry : info.getAttributes().entrySet()) { out.println("<TR><TD>" + entry.getKey() + "</TD><TD>" + entry.getValue() + "</TD></TR>"); } out.println("</TABLE>"); %> <a href="<%=request.getContextPath()%>/logout">Logout</a> </body> </html>
<Context docBase="$pathToWebApp" privileged="true" antiResourceLocking="false" antiJARLocking="false" unpackWAR="false" swallowOutput="true" />
<!-- Logs IdP, but not OpenSAML, messages --> <logger name="edu.internet2.middleware.shibboleth" level="DEBUG"/>
22:19:49.172 - DEBUG [edu.internet2.middleware.shibboleth.idp.authn.provider.RemoteUserLoginHandler:66] - Redirecting to <a href="https://idp.local.ru:8443/idp/Authn/RemoteUser">https://idp.local.ru:8443/idp/Authn/RemoteUser</a>
Source: https://habr.com/ru/post/193662/
All Articles