Author: echatellier Date: 2012-10-18 16:28:15 +0200 (Thu, 18 Oct 2012) New Revision: 221 Url: http://nuiton.org/repositories/revision/nuiton-web/221 Log: Fix non connected anonymous connected user Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java 2012-10-18 14:27:48 UTC (rev 220) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/SecurityShiroFilter.java 2012-10-18 14:28:15 UTC (rev 221) @@ -12,11 +12,19 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.mgt.SubjectFactory; import org.apache.shiro.realm.Realm; +import org.apache.shiro.session.Session; +import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.SubjectContext; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.AbstractShiroFilter; +import org.apache.shiro.web.subject.WebSubjectContext; +import org.apache.shiro.web.subject.support.WebDelegatingSubject; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaContextFactory; import org.nuiton.topia.TopiaException; @@ -24,40 +32,45 @@ import org.nuiton.util.ApplicationConfig; import org.nuiton.web.SecurityDAOHelper; -public class SecurityShiroFilter extends AbstractShiroFilter { +public class SecurityShiroFilter extends AbstractShiroFilter implements SubjectFactory { private static final Log log = LogFactory.getLog(SecurityShiroFilter.class); + public static final String APP_CONFIG_CONTEXT = SecurityShiroFilter.class.getName() + "#" + ApplicationConfig.class.getName(); + + public static final String ROOT_CONTEXT_CONTEXT = SecurityShiroFilter.class.getName() + "#" + TopiaContext.class.getName(); + protected static final String ANON_LOGIN = "anonymous"; + protected ApplicationConfig config; + + protected TopiaContext rootContext; + @Override public void init() throws Exception { // get config from context - ApplicationConfig config = (ApplicationConfig)getServletContext().getAttribute("ApplicationConfig"); + config = (ApplicationConfig)getServletContext().getAttribute(APP_CONFIG_CONTEXT); if (config == null) { - throw new IllegalArgumentException("No ApplicationConfig attribute found in servlet context"); + throw new IllegalArgumentException("No APP_CONFIG_CONTEXT attribute found in servlet context"); } // get topia root context config.setOption(TopiaContextFactory.CONFIG_PERSISTENCE_CLASSES, SecurityDAOHelper.getImplementationClassesAsString()); Properties props = config.getFlatOptions(); - TopiaContext rootContext = TopiaContextFactory.getContext(props); + rootContext = TopiaContextFactory.getContext(props); initSchema(rootContext); - getServletContext().setAttribute("rootContext", rootContext); + getServletContext().setAttribute(ROOT_CONTEXT_CONTEXT, rootContext); // see http://shiro.apache.org/configuration.html#Configuration-ProgrammaticConfigu... if (log.isInfoEnabled()) { log.info("Overriding shiro realms"); } - //DefaultWebEnvironment env = new DefaultWebEnvironment(); Realm realm = new TopiaSecurityRealm(rootContext, config); DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm); setSecurityManager(securityManager); - /*FilterChainResolver resolver = getFilterChainResolver(); - if (resolver != null) { - setFilterChainResolver(resolver); - }*/ + securityManager.setSubjectFactory(this); + SecurityUtils.setSecurityManager(securityManager); } protected static void initSchema(TopiaContext rootContext) throws TopiaException { @@ -103,6 +116,10 @@ // get permission String uri = ((HttpServletRequest)servletRequest).getRequestURI(); String perm = "url" + uri.replace('/', ':'); + // cas de la permission url: qui est equivalente a url:* + if (perm.endsWith(":")) { + perm += "/"; + } if (subjectUser.isPermitted(perm)) { if (log.isDebugEnabled()) { @@ -114,10 +131,50 @@ log.debug("User is NOT permitted to access " + perm); } if (ANON_LOGIN.equals(subjectUser.getPrincipal())) { - ((HttpServletResponse)servletResponse).sendRedirect("/security/login.action"); + ((HttpServletResponse)servletResponse).sendRedirect(config.getOption("topia.security.loginurl")); } else { ((HttpServletResponse)servletResponse).sendError(401, "Not authorized to access " + uri); } } } + + @Override + public void destroy() { + super.destroy(); + + if (rootContext != null) { + try { + rootContext.closeContext(); + } catch (TopiaException ex) { + if (log.isErrorEnabled()) { + log.error("Can't close root context", ex); + } + } + } + } + + @Override + public Subject createSubject(SubjectContext context) { + /*if (!(context instanceof WebSubjectContext)) { + return super.createSubject(context); + }*/ + WebSubjectContext wsc = (WebSubjectContext) context; + SecurityManager securityManager = wsc.resolveSecurityManager(); + Session session = wsc.resolveSession(); + boolean sessionEnabled = wsc.isSessionCreationEnabled(); + PrincipalCollection principals = wsc.resolvePrincipals(); + boolean authenticated = wsc.resolveAuthenticated(); + + // dans le cas du module securité, on va dire que non + if (authenticated && ANON_LOGIN.equals(principals.getPrimaryPrincipal())) { + authenticated = false; + } + + String host = wsc.resolveHost(); + ServletRequest request = wsc.resolveServletRequest(); + ServletResponse response = wsc.resolveServletResponse(); + + return new WebDelegatingSubject(principals, authenticated, host, session, sessionEnabled, + request, response, securityManager); + } } Modified: branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java =================================================================== --- branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java 2012-10-18 14:27:48 UTC (rev 220) +++ branches/nuiton-web-1.11-security/nuiton-security/src/main/java/org/nuiton/web/security/TopiaSecurityRealm.java 2012-10-18 14:28:15 UTC (rev 221) @@ -1,8 +1,5 @@ package org.nuiton.web.security; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.Properties; import org.apache.commons.lang3.StringUtils; @@ -94,8 +91,8 @@ } // ajout de l'url de login et logout quand meme !!! - result.addStringPermission("url:security:login.action"); - result.addStringPermission("url:security:logout.action"); + result.addStringPermission("url" + config.getOption("topia.security.loginurl").replace('/', ':')); + result.addStringPermission("url" + config.getOption("topia.security.logouturl").replace('/', ':')); } catch (Exception ex) {