标签:文件 style pts [] bsp hook code password cep
优秀的平台必然松耦合、易扩展 -- 王昕
<?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd"> <hook> <portal-properties>portal.properties</portal-properties> </hook>
如果是liferay7则不需要这一步,只需要注解:
@Component(
immediate = true, property = {"key=auth.pipeline.pre"},
service = Authenticator.class
)
auth.pipeline.pre=com.proliferay.YourAuthenticator
配置auth.pipeline.post 还将进行密码检查,liferay的内部机制是2级检查,一级是身份认证,二级是密码检查,实际上可以通过SKIP_LIFERAY_CHECK来统一处理
import java.util.Map; import com.liferay.portal.security.auth.AuthException; import com.liferay.portal.security.auth.Authenticator; public class YourAuthenticator implements Authenticator { @Override public int authenticateByEmailAddress(long companyId, String emailAddress, String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { /** * 这里是认证的逻辑 */ return SKIP_LIFERAY_CHECK; } @Override public int authenticateByScreenName(long companyId, String screenName, String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { return DNE; } @Override public int authenticateByUserId(long companyId, long userId, String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { return DNE; } }
常数定义:
要注意SKIP_LIFERAY_CHECK和SUCCESS的区别,通过SKIP_LIFERAY_CHECK来统一处理身份认证,跳过门户的密码检查,如果返回SUCCESS,则必须配合auth.pipeline.post来进行密码检查。
通过图来说明:
一个具体的例子:
import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.security.auth.AuthException; import com.liferay.portal.kernel.security.auth.Authenticator; import java.util.Map; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @Component( immediate = true, property = {"key=auth.pipeline.pre"}, service = Authenticator.class ) public class ShiroAuthenticatorPre implements Authenticator { @Activate public void activate() { Factory<SecurityManager> factory = new IniSecurityManagerFactory( "classpath:userauth.ini"); //shiro配置文件 SecurityUtils.setSecurityManager(factory.getInstance()); if (_log.isInfoEnabled()) { _log.info("activate"); } } @Override public int authenticateByEmailAddress( long companyId, String emailAddress, String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { if (_log.isInfoEnabled()) { _log.info("authenticateByEmailAddress"); } UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken( emailAddress, password); Subject currentUser = SecurityUtils.getSubject(); try { //shiro的代理登陆 currentUser.login(usernamePasswordToken); boolean authenticated = currentUser.isAuthenticated(); if (authenticated) { if (_log.isInfoEnabled()) { _log.info("authenticated"); } return SKIP_LIFERAY_CHECK; //认证通过 } else { return FAILURE; } } catch (AuthenticationException ae) { _log.error(ae.getMessage(), ae); throw new AuthException(ae.getMessage(), ae); } } @Override public int authenticateByScreenName( long companyId, String screenName, String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { if (_log.isInfoEnabled()) { _log.info("authenticateByScreenName - not implemented "); } return SUCCESS; } @Override public int authenticateByUserId( long companyId, long userId, String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { if (_log.isInfoEnabled()) { _log.info("authenticateByScreenName - not implemented "); } return SUCCESS; } private static final Log _log = LogFactoryUtil.getLog( ShiroAuthenticatorPre.class); }
apache shiro框架结构
apache shiro是一套非常著名的安全框架,提供了认证、授权、加密和会话管理功能
了解更多apache shiro的知识:http://www.infoq.com/cn/articles/apache-shiro
Authentication的Token令牌机制
了解更多Authentication Token:https://web.liferay.com/zh/community/wiki/-/wiki/Main/Authentication+Token
Token令牌是为了避免CSRF跨站伪造。
了解更多CSRF:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.security.auth.AuthException; import com.liferay.portal.kernel.security.auth.AuthFailure; import com.liferay.portal.kernel.service.UserLocalServiceUtil; import java.util.Map; import org.osgi.service.component.annotations.Component; @Component( immediate = true, property = {"key=auth.failure"}, service = AuthFailure.class ) public class LogAuthFailure implements AuthFailure { @Override public void onFailureByEmailAddress( long companyId, String emailAddress, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { try { User user = UserLocalServiceUtil.getUserByEmailAddress( companyId, emailAddress); int failures = user.getFailedLoginAttempts(); if (_log.isInfoEnabled()) { _log.info( "onFailureByEmailAddress: " + emailAddress + " has failed to login " + failures + " times"); } } catch (PortalException pe) { } } @Override public void onFailureByScreenName( long companyId, String screenName, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { try { User user = UserLocalServiceUtil.getUserByScreenName( companyId, screenName); int failures = user.getFailedLoginAttempts(); if (_log.isInfoEnabled()) { _log.info( "onFailureByScreenName: " + screenName + " has failed to login " + failures + " times"); } } catch (PortalException pe) { } } @Override public void onFailureByUserId( long companyId, long userId, Map<String, String[]> headerMap, Map<String, String[]> parameterMap) throws AuthException { try { User user = UserLocalServiceUtil.getUserById(userId); int failures = user.getFailedLoginAttempts(); if (_log.isInfoEnabled()) { _log.info( "onFailureByUserId: userId " + userId + " has failed to login " + failures + " times"); } } catch (PortalException pe) { } } private static final Log _log = LogFactoryUtil.getLog(LogAuthFailure.class); }
Liferay7 BPM门户开发之32: 实现自定义认证登陆(定制Authentication Hook)
标签:文件 style pts [] bsp hook code password cep
原文地址:http://www.cnblogs.com/starcrm/p/6055113.html