パネル |
---|
titleBGColor | #eeeeee |
---|
title | SampleFilterPerSP.java |
---|
| 下記内容のファイルをダウンロードする(リンク上で右クリックしてリンク先を保存してください) | /* * Copyright (c) 2011, National Institute of Informatics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package plugin.idp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import edu.internet2.middleware.shibboleth.common.attribute.AttributeRequestException;
import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
import edu.internet2.middleware.shibboleth.common.attribute.provider.SAML2AttributeAuthority;
import edu.internet2.middleware.shibboleth.common.profile.AbstractErrorHandler;
import edu.internet2.middleware.shibboleth.common.profile.provider.BaseSAMLProfileRequestContext;
import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
import edu.internet2.middleware.shibboleth.common.relyingparty.provider.SAMLMDRelyingPartyConfigurationManager;
import edu.internet2.middleware.shibboleth.idp.authn.AuthenticationException;
import edu.internet2.middleware.shibboleth.idp.authn.LoginContext;
import edu.internet2.middleware.shibboleth.idp.util.HttpServletHelper;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.opensaml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
public class SampleFilterPerSP implements Filter {
/** web.xmlのパラメータキー */
private static String CONFIGFILES = "Config";
/** ServletContext */
private ServletContext m_servletContext = null;
/** SP毎ののattributeフィルタの値 */
private Map<String, Map> allow_config;
/** 属性のContext */
private SAML2AttributeAuthority m_saml2AttrAuth;
/** RelyingPartyのContext */
private SAMLMDRelyingPartyConfigurationManager m_samlRelyingPartyConfMan;
@Override
public void destroy() {
// TODO 自動生成されたメソッド・スタブ
}
@Override
public void doFilter(
ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// フィルタ条件がない場合は次のフィルタへ
if (allow_config.isEmpty()) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// Shibboleth のログイン情報
// see also: https://wiki.shibboleth.net/confluence/display/SHIB2/IdPAuthUserPass
LoginContext loginCtx = HttpServletHelper.getLoginContext(
HttpServletHelper.getStorageService(m_servletContext), m_servletContext, httpServletRequest);
if (loginCtx == null) {
// まだログインしていない場合はログイン処理へ
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// ログイン結果判定
AuthenticationException authenticationFailure = loginCtx.getAuthenticationFailure();
if (authenticationFailure != null) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// ログインユーザとSPのエンティティID
String spEntityId = loginCtx.getRelyingPartyId();
String userName = loginCtx.getPrincipalName();
// 属性情報リクエスト用の情報
BaseSAMLProfileRequestContext requestCtx = new BaseSAMLProfileRequestContext();
// SPに対応するRelyingParty
RelyingPartyConfiguration relyingPartyConfiguration =
m_samlRelyingPartyConfMan.getRelyingPartyConfiguration(spEntityId);
// メタデータプロバイダ情報
MetadataProvider metadataProvider = m_samlRelyingPartyConfMan.getMetadataProvider();
// IdPのエンティティID
String idpEntityId = relyingPartyConfiguration.getProviderId();
// リクエスト情報設定
try {
requestCtx.setRelyingPartyConfiguration(relyingPartyConfiguration);
requestCtx.setInboundMessageIssuer(spEntityId);
requestCtx.setOutboundMessageIssuer(idpEntityId);
requestCtx.setPrincipalName(userName);
requestCtx.setLocalEntityId(idpEntityId);
requestCtx.setPeerEntityId(spEntityId);
requestCtx.setLocalEntityMetadata(metadataProvider.getEntityDescriptor(idpEntityId));
requestCtx.setPeerEntityMetadata(metadataProvider.getEntityDescriptor(spEntityId));
requestCtx.setMetadataProvider(metadataProvider);
} catch (MetadataProviderException e) {
e.printStackTrace();
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// 属性を取得
Map<String, BaseAttribute> attributes = null;
try {
attributes = m_saml2AttrAuth.getAttributes(requestCtx);
} catch (AttributeRequestException e) {
e.printStackTrace();
}
if (attributes == null) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// コンフィグの設定と比較
System.out.println("SampleFilterPerSP spEntityId = " + spEntityId);
if (allow_config.containsKey(spEntityId)) {
Map filterpersp = allow_config.get(spEntityId);
for (BaseAttribute baseattrval : attributes.values()) {
if (filterpersp.containsKey(baseattrval.getId())) {
Set val = (Set)filterpersp.get(baseattrval.getId());
for (Object obj: baseattrval.getValues()) {
if (obj != null && !obj.toString().trim().equals("")) {
String attrval = obj.toString();
if (val.contains(attrval)) {
// for debug
System.out.println("SampleFilterPerSP checked " + baseattrval.getId() + "=" + attrval);
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
}
}
}
// for debug
System.out.println("SampleFilterPerSP don't match any attributes.");
for (BaseAttribute baseattrval : attributes.values()) {
for (Object obj: baseattrval.getValues()) {
if (obj != null && !obj.toString().trim().equals("")) {
String attrval = obj.toString();
System.out.println("SampleFilterPerSP " + baseattrval.getId() + "=" + attrval);
}
}
}
doError(servletRequest, servletResponse, spEntityId, userName);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
/**
* エラーの場合エラー内容表示
* @param servletResponse
* @param spEntityId
* @param userName
* @throws IOException
*/
private void doError(ServletRequest servletRequest, ServletResponse servletResponse,
String spEntityId, String userName) throws IOException, ServletException {
final String PAGE_ERROR = "/error.jsp";
final String errmsg = "Deny you(" + userName + ") login to Service Provider " + spEntityId;
// エラーメッセージの表示など
Throwable error = new Exception(errmsg);
servletRequest.setAttribute(AbstractErrorHandler.ERROR_KEY, error);
m_servletContext.getRequestDispatcher(PAGE_ERROR).forward(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// web.xmlのコンフィグなど
m_servletContext = filterConfig.getServletContext();
allow_config = new HashMap<String, Map>();
String configfilename = filterConfig.getInitParameter(CONFIGFILES);
if (configfilename != null) {
File conffile = new File(configfilename);
if (conffile.exists()) {
// ファイルの操作など
try {
XMLConfiguration xml_config = new XMLConfiguration(conffile);
for (int i = 0; i < xml_config.getList("EntityDescriptor[@entityID]").size(); i++) {
String spEntityId = xml_config.getString("EntityDescriptor("+i+")[@entityID]");
if (allow_config.containsKey(spEntityId) == true) {
System.out.println("SampleFilterPerSP WARNING: ignore duplicated " + spEntityId
+ " because it is already configured");
continue;
}
Map<String, Set> submap = new HashMap<String, Set>();
String[] attributeID = xml_config.getStringArray("EntityDescriptor("+i+").Attribute[@attributeID]");
String[] attribute = xml_config.getStringArray("EntityDescriptor("+i+").Attribute");
for (int j = 0; j < attributeID.length; j++) {
if (submap.containsKey(attributeID[j]) == false) {
submap.put(attributeID[j], new HashSet<String>());
}
submap.get(attributeID[j]).add(attribute[j]);
}
allow_config.put(spEntityId, submap);
}
} catch (ConfigurationException e) {
throw new ServletException(e);
}
}
System.out.println("SampleFilterPerSP config-key-value:");
for(Map.Entry<String, Map> e : allow_config.entrySet()) {
System.out.println("SampleFilterPerSP "
+ e.getKey() + " : " + e.getValue());
}
}
// 取得した属性情報
m_saml2AttrAuth =
(SAML2AttributeAuthority) filterConfig.getServletContext().getAttribute("shibboleth.SAML2AttributeAuthority");
// relying-partyの情報
m_samlRelyingPartyConfMan =
(SAMLMDRelyingPartyConfigurationManager) filterConfig.getServletContext().getAttribute(
"shibboleth.RelyingPartyConfigurationManager");
}
}
|