
org.nuiton.web.security.TopiaSecurityRealm Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-security Show documentation
Show all versions of nuiton-security Show documentation
Security module based on ToPIA
/*
* #%L
* Nuiton Web :: Nuiton Security
* %%
* Copyright (C) 2012 - 2013 CodeLutin, Chatellier Eric
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.web.security;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.nuiton.config.ApplicationConfig;
import org.nuiton.util.StringUtil;
import org.nuiton.web.SecurityTopiaApplicationContext;
import org.nuiton.web.SecurityTopiaPersistenceContext;
/**
* Topia shiro realm finding user in database.
*
* @author Eric Chatellier
*/
public class TopiaSecurityRealm extends AuthorizingRealm implements CredentialsMatcher {
private static final Log log = LogFactory.getLog(TopiaSecurityRealm.class);
protected SecurityTopiaApplicationContext rootContext;
protected ApplicationConfig config;
/** Authorization cache (invalidated at login). */
protected transient Map authorizationCache;
public TopiaSecurityRealm(SecurityTopiaApplicationContext rootContext, ApplicationConfig config) {
this.rootContext = rootContext;
this.config = config;
authorizationCache = new HashMap();
setCredentialsMatcher(this);
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
char[] tokenCredentials = (char[]) token.getCredentials();
String submittedPassword = String.valueOf(tokenCredentials);
String submittedHashedPassword = StringUtil.encodeMD5(submittedPassword);
String expectedHashedPassword = (String) info.getCredentials();
return expectedHashedPassword.equals(submittedHashedPassword);
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String login = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo result = authorizationCache.get(login);
if (result == null) {
Properties props = config.getFlatOptions();
SecurityTopiaPersistenceContext transaction = null;
try {
transaction = rootContext.newPersistenceContext();
SecurityUserTopiaDao securityUserDAO = transaction.getSecurityUserDao();
if (log.isDebugEnabled()) {
log.debug("Build autorisation list for user : " + login);
}
SecurityUser securityUser = securityUserDAO.findByLogin(login);
result = new SimpleAuthorizationInfo();
for (SecurityRole role : securityUser.getSecurityRole()) {
for (String permission : role.getPermissions()) {
//result.addStringPermission(permission);
if (log.isDebugEnabled()) {
log.debug("- add permission : " + permission);
}
for (String prop : props.stringPropertyNames()) {
if (prop.startsWith("topia.security.permission.")) {
String endProp = StringUtils.removeStart(prop, "topia.security.permission.");
String[] subs = endProp.split("\\.");
if (subs.length == 3) {
if (subs[2].equals("perm")) {
if (subs[1].equals(permission)) {
String perms = props.getProperty(prop);
// use ; separator because shiro use ,
String[] permTab = perms.split("\\s*\\;\\s*");
for (String perm : permTab) {
result.addStringPermission(perm);
if (log.isDebugEnabled()) {
log.debug(" string permission : " + perm);
}
}
}
}
}
}
}
}
}
// si seul l'utilisateur anon existe
// on lui offre une promotion
if (login.equals(SecurityShiroFilter.ANON_LOGIN) && securityUserDAO.count() == 1) {
result.addStringPermission("*");
if (log.isDebugEnabled()) {
log.debug("Grant all right (*) because no user exists");
}
}
// si la securité est desactivee,
if (config.getOptionAsBoolean("topia.security.disable")) {
result.addStringPermission("*");
}
// ajout de l'url de login et logout quand meme !!!
result.addStringPermission("url" + SecurityUtil.convertToShiroPerm(config.getOption("topia.security.loginurl"),
config.getOption("topia.security.separators")));
result.addStringPermission("url" + SecurityUtil.convertToShiroPerm(config.getOption("topia.security.logouturl"),
config.getOption("topia.security.separators")));
// cache authorization
authorizationCache.put(login, result);
} catch (Exception ex) {
if (log.isErrorEnabled()) {
log.error("Can't get user permission", ex);
}
} finally {
if (transaction != null) {
transaction.close();
}
}
} else {
if (log.isTraceEnabled()) {
log.trace("Using autorisation from cache for " + login);
}
}
return result;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String login = usernamePasswordToken.getUsername();
//char[] password = usernamePasswordToken.getPassword();
if (log.isDebugEnabled()) {
log.debug("doGetAuthenticationInfo for login : " + login);
}
AuthenticationInfo result = null;
SecurityTopiaPersistenceContext transaction = null;
try {
transaction = rootContext.newPersistenceContext();
SecurityUserTopiaDao securityUserDAO = transaction.getSecurityUserDao();
SecurityUser securityUser = securityUserDAO.forLoginEquals(login).findUniqueOrNull();
if (securityUser != null) {
if (login.equals(SecurityShiroFilter.ANON_LOGIN)) {
result = new SimpleAuthenticationInfo(securityUser.getLogin(),
StringUtil.encodeMD5(""), getName());
} else {
result = new SimpleAuthenticationInfo(securityUser.getLogin(),
securityUser.getPassword(), getName());
}
// invalidate cache for login
authorizationCache.remove(login);
}
} finally {
if (transaction != null) {
transaction.close();
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy