首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

spring security 3.x LDAP 应验

2012-09-13 
spring security 3.xLDAP 验证首先修改web.xml?context-paramparam-namecontextConfigLocation/param

spring security 3.x LDAP 验证

首先修改web.xml

?

<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml,classpath:spring-security.xml</param-value></context-param><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping><listener><listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class></listener><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>Security</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath*:security-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>Security</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
?

?

?

security-servlet.xml配置文件:

?

<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd           http://www.springframework.org/schema/security           http://www.springframework.org/schema/security/spring-security-3.0.xsd"><http><intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" /><intercept-url pattern="/*" access="ROLE_VOICE_USER,ROLE_SMS_USER,ROLE_DOWNLOAD_USER,ROLE_CONTENT_USER" /><form-loginlogin-page="/login.jsp"authentication-failure-url="/login.jsp?error=true"default-target-url="/index.jsp" always-use-default-target="true"/><anonymous /><logout /><session-management><concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/></session-management></http><authentication-manager><authentication-provider ref="ldapProvider"></authentication-provider></authentication-manager><beans:bean id="contextSource" /><beans:property name="userDn" value="CN=readonly,ou=ldapaccounts,ou=netm,ou=people,o=netmldap" /><beans:property name="password" value="$$23-ssoU" /></beans:bean><beans:bean id="ldapProvider"/><beans:property name="userSearch"><beans:bean id="userSearch"value="ou=accounts" /><beans:constructor-arg index="1" value="(uid={0})" /><beans:constructor-arg index="2" ref="contextSource" /></beans:bean></beans:property></beans:bean></beans:constructor-arg><beans:constructor-arg><beans:beanref="contextSource" /><beans:constructor-arg index="1" value="ou=voice.rp,ou=olrp,ou=applications,ou=acl,ou=groups" /><beans:constructor-arg index="2" value="ou=sms.rp,ou=olrp,ou=applications,ou=acl,ou=groups" /><beans:constructor-arg index="3" value="ou=download.rp,ou=olrp,ou=applications,ou=acl,ou=groups" /><beans:constructor-arg index="4" value="ou=content.rp,ou=olrp,ou=applications,ou=acl,ou=groups" /><beans:property name="groupRoleAttribute" value="description" /><beans:property name="groupSearchFilter" value="(uniqueMember={0})" /><beans:property name="rolePrefix" value="ROLE_" /><beans:property name="searchSubtree" value="true" /><beans:property name="convertToUpperCase" value="true" /></beans:bean></beans:constructor-arg></beans:bean></beans:beans>

?

1. security 的配置文件.

2. 重写DefaultLdapAuthoritiesPopulator类.

?

 private String smsRolePrefix = "ROLE_SMS_";    private String voiceRolePrefix = "ROLE_VOICE_";    private String downloadRolePrefix = "ROLE_DOWNLOAD_";    private String contentRolePrefix = "ROLE_CONTENT_";    private String defaultRoleName = "USER";    private String voiceGroupSearchBase;private String smsGroupSearchBase;    private String downloadGroupSearchBase;    private String contentGroupSearchBase;
?

?

根据不同的业务加入不同的属性.对应每个DN.

?

3.?删除旧的构造函数.创建自适应的构造函数.

?

?

 public MyLdapAuthoritiesPopulator(ContextSource contextSource, String voiceGroupSearchBase,String smsGroupSearchBase,String downloadGroupSearchBase,String contentGroupSearchBase) {        Assert.notNull(contextSource, "contextSource must not be null");        ldapTemplate = new SpringSecurityLdapTemplate(contextSource);        ldapTemplate.setSearchControls(searchControls);        setVoiceGroupSearchBase(voiceGroupSearchBase);        setSmsGroupSearchBase(smsGroupSearchBase);        setDownloadGroupSearchBase(downloadGroupSearchBase);        setContentGroupSearchBase(contentGroupSearchBase);    }
?

?

4.?重构getGroupMembershipRoles方法.?

?

?

 public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {        if (getVoiceGroupSearchBase() == null || getSmsGroupSearchBase()==null || getDownloadGroupSearchBase()==null || getContentGroupSearchBase()==null) {            return Collections.emptySet();        }        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();        if (logger.isDebugEnabled()) {            logger.debug("Searching for roles for user '" + username + "', DN = " + "'" + userDn + "', with filter "                    + groupSearchFilter + " in search base '" + getGroupSearchBase() + "'");        }        //get role for voice        Set<String> voiceUserRoles = ldapTemplate.searchForSingleAttributeValues(getVoiceGroupSearchBase(), groupSearchFilter,                new String[]{userDn, username}, groupRoleAttribute);                if(SetUtils.isEqualSet(voiceUserRoles, SetUtils.EMPTY_SET)==false){        authorities.add(new GrantedAuthorityImpl(voiceRolePrefix + defaultRoleName));        }                if (logger.isDebugEnabled()) {            logger.debug("voiceUserRoles from search: " + voiceUserRoles);        }        for (String role : voiceUserRoles) {            if (convertToUpperCase) {                role = role.toUpperCase();            }            authorities.add(new GrantedAuthorityImpl(voiceRolePrefix + role));        }                //get role for sms        Set<String> smsUserRoles = ldapTemplate.searchForSingleAttributeValues(getSmsGroupSearchBase(), groupSearchFilter,                new String[]{userDn, username}, groupRoleAttribute);                if(SetUtils.isEqualSet(smsUserRoles, SetUtils.EMPTY_SET)==false){        authorities.add(new GrantedAuthorityImpl(smsRolePrefix + defaultRoleName));        }                if (logger.isDebugEnabled()) {            logger.debug("smsUserRoles from search: " + smsUserRoles);        }        for (String role : smsUserRoles) {            if (convertToUpperCase) {                role = role.toUpperCase();            }            authorities.add(new GrantedAuthorityImpl(smsRolePrefix + role));        }                //get role for download        Set<String> downloadUserRoles = ldapTemplate.searchForSingleAttributeValues(getDownloadGroupSearchBase(), groupSearchFilter,                new String[]{userDn, username}, groupRoleAttribute);                if(SetUtils.isEqualSet(downloadUserRoles, SetUtils.EMPTY_SET)==false){        authorities.add(new GrantedAuthorityImpl(downloadRolePrefix + defaultRoleName));        }                if (logger.isDebugEnabled()) {            logger.debug("downloadUserRoles from search: " + downloadUserRoles);        }        for (String role : downloadUserRoles) {            if (convertToUpperCase) {                role = role.toUpperCase();            }            authorities.add(new GrantedAuthorityImpl(downloadRolePrefix + role));        }                //get role for content        Set<String> contentUserRoles = ldapTemplate.searchForSingleAttributeValues(getContentGroupSearchBase(), groupSearchFilter,                new String[]{userDn, username}, groupRoleAttribute);                if(SetUtils.isEqualSet(contentUserRoles, SetUtils.EMPTY_SET)==false){        authorities.add(new GrantedAuthorityImpl(contentRolePrefix + defaultRoleName));        }                if (logger.isDebugEnabled()) {            logger.debug("contentUserRoles from search: " + contentUserRoles);        }        for (String role : contentUserRoles) {            if (convertToUpperCase) {                role = role.toUpperCase();            }            authorities.add(new GrantedAuthorityImpl(contentRolePrefix + role));        }        SetUtils.orderedSet(authorities);        return authorities;    }

?

5. 登陆成功后跳入loginAfter.do ?此类中构建一个Account对象放在session中.

构建方法见WebUtil.java

?

?

?

package ethan.security;import java.util.Collection;import java.util.HashSet;import java.util.Set;import org.apache.commons.lang.StringUtils;import org.apache.log4j.Logger;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.context.SecurityContextImpl;import org.springframework.security.core.userdetails.UserDetails;import ethan.model.Account;/** * WebUtil acts as a helper class for xxx *  * @Author:Ethan Dai * @Date:11-Jan-2011 *  */public class WebUtil {private static final Logger logger = Logger.getLogger(WebUtil.class.getName());/** * Form user account from session *  * @param request *            Http Servlet Request */public static Account getAccount() {SecurityContextImpl obj = (SecurityContextImpl) SecurityContextHolder.getContext();Account account = new Account();account.setUid(obj.getAuthentication().getName());logger.debug("setUid="+obj.getAuthentication().getName());Object principal=obj.getAuthentication().getPrincipal();if(principal instanceof UserDetails){logger.debug("((UserDetails) principal).getUsername():"+((UserDetails) principal).getUsername());//logger.debug("((UserDetails) principal).getPassword():"+((UserDetails) principal).getPassword());}Collection<GrantedAuthority> authorities  = SecurityContextHolder.getContext().getAuthentication().getAuthorities();if (isInternalUser(authorities)) {account.setAdmin(true);} else {account.setAdmin(false);account.setCustomers(allCustomerId(authorities));}logger.debug("isAdmin:"+account.isAdmin());if(isContentInternalUser(authorities)){account.setContentAdmin(true);}else{account.setContentAdmin(false);                                                                                account.setContentCustomers(allContentCustomerId(authorities));}if(isVoiceInternalUser(authorities)){account.setVoiceAdmin(true);}else{account.setVoiceAdmin(false);account.setVoiceCustomers(allVoiceCustomerId(authorities));}if(isSMSInternalUser(authorities)){account.setSMSAdmin(true);}else{account.setSMSAdmin(false);account.setSMSCustomers(allSMSCustomerId(authorities));}if(isDownloadInternalUser(authorities)){account.setDownloadAdmin(true);}else{account.setDownloadAdmin(false);account.setDownloadCustomers(allDownloadCustomerId(authorities));}return account;}private static String[] allDownloadCustomerId(Collection<GrantedAuthority> authorities) {if (authorities == null || authorities.size() == 0) {return null;}Set<String> customer = new HashSet<String>();for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();if(!StringUtils.contains(roleName, "USER") && StringUtils.contains(roleName, "ROLE_DOWNLOAD_")){String downloadCustomerId = StringUtils.substring(roleName, roleName.lastIndexOf('_') + 1);if(logger.isDebugEnabled()){logger.debug("From webutil download customer is:" + downloadCustomerId);}customer.add(downloadCustomerId);}}return (String[]) customer.toArray(new String[customer.size()]);}private static boolean isDownloadInternalUser(Collection<GrantedAuthority> authorities) {if(authorities == null || authorities.size() == 0){return false;}for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();logger.debug("Checking for download role name:" + roleName);if(StringUtils.contains(roleName, "DOWNLOAD_ALL")){logger.debug("Role name contains 'DOWNLOAD_ALL':" + roleName);return true;}}return false;}private static boolean isSMSInternalUser(Collection<GrantedAuthority> authorities) {if(authorities == null || authorities.size() == 0){return false;}for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();logger.debug("Checking for sms role name:" + roleName);if(StringUtils.contains(roleName, "SMS_ALL")){logger.debug("Role name contains 'SMS_ALL':" + roleName);return true;}}return false;}/** * Try to determine if user is internal user. Internal user will has role * "ROLE_XXX_ALL" */public static boolean isInternalUser(Collection<GrantedAuthority> authorities) {if (authorities == null || authorities.size() == 0) {return false;}for (GrantedAuthority grantedAuthority : authorities) {String roleName=grantedAuthority.getAuthority();if (StringUtils.contains(roleName, "ALL")) {logger.debug("Role name contains 'ALL':"+roleName);return true;}}return false;}/** * Try to determine if user is internal user under Content report. Content Internal * user will has role "ROLE_CONTENT_ALL"; * @param authorities * @return */public static boolean isContentInternalUser(Collection<GrantedAuthority> authorities){if(authorities == null || authorities.size() == 0){return false;}for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();logger.debug("Checking for content role name:"+roleName);if(StringUtils.contains(roleName, "CONTENT_ALL")){logger.debug("Role name contains 'CONTENT_ALL':"+roleName);return true;}}return false;}private static boolean isVoiceInternalUser(Collection<GrantedAuthority> authorities) {if(authorities == null || authorities.size() == 0){return false;}for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();logger.debug("Checking for voice role name:" + roleName);if(StringUtils.contains(roleName, "VOICE_ALL")){logger.debug("Role name contains 'VOICE_ALL':" + roleName);return true;}}return false;}/** * Get all customer ids for user *  * @return String array *  */public static String[] allCustomerId(Collection<GrantedAuthority> authorities) {if (authorities == null || authorities.size() == 0) {return null;}Set<String> customer = new HashSet<String>();for (GrantedAuthority grantedAuthority : authorities) {String roleName=grantedAuthority.getAuthority();if (!StringUtils.contains(roleName, "USER")) {String customerId = StringUtils.substring(roleName, roleName.lastIndexOf('_') + 1);if (logger.isDebugEnabled()) {logger.debug("From webutil customer is:" + customerId);}customer.add(customerId);}}return (String[]) customer.toArray(new String[customer.size()]);}private static String[] allContentCustomerId(Collection<GrantedAuthority> authorities) {if (authorities == null || authorities.size() == 0) {return null;}Set<String> customer = new HashSet<String>();for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();if(!StringUtils.contains(roleName, "USER") && StringUtils.contains(roleName, "ROLE_CONTENT_")){String contentCustomerId = StringUtils.substring(roleName, roleName.lastIndexOf('_') + 1);if(logger.isDebugEnabled()){logger.debug("From webutil content customer is:" + contentCustomerId);}customer.add(contentCustomerId);}}return (String[]) customer.toArray(new String[customer.size()]);}private static String[] allVoiceCustomerId(Collection<GrantedAuthority> authorities) {if (authorities == null || authorities.size() == 0) {return null;}Set<String> customer = new HashSet<String>();for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();if(!StringUtils.contains(roleName, "USER") && StringUtils.contains(roleName, "ROLE_VOICE_")){String voiceCustomerId = StringUtils.substring(roleName, roleName.lastIndexOf('_') + 1);if(logger.isDebugEnabled()){logger.debug("From webutil voice customer is:" + voiceCustomerId);}customer.add(voiceCustomerId);}}return (String[]) customer.toArray(new String[customer.size()]);}private static String[] allSMSCustomerId(Collection<GrantedAuthority> authorities) {if (authorities == null || authorities.size() == 0) {return null;}Set<String> customer = new HashSet<String>();for (GrantedAuthority grantedAuthority : authorities) {String roleName = grantedAuthority.getAuthority();if(!StringUtils.contains(roleName, "USER") && StringUtils.contains(roleName, "ROLE_SMS_")){String smsCustomerId = StringUtils.substring(roleName, roleName.lastIndexOf('_') + 1);if(logger.isDebugEnabled()){logger.debug("From webutil sms customer is:" + smsCustomerId);}customer.add(smsCustomerId);}}return (String[]) customer.toArray(new String[customer.size()]);}}
?

?

已经步骤完成后,功能和数据权限都已经得到.直接调转到项目页面即可..

?

?

?

----------------------------------------------------------------

?

在以上的基础上改进为extjs 登陆验证的模式..

?

1.修改 spring-security.xml

?

<http><intercept-url pattern="/login2.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" /><intercept-url pattern="/js/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /><intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /><intercept-url pattern="/**"access="ROLE_VOICE_USER,ROLE_SMS_USER,ROLE_DOWNLOAD_USER,ROLE_CONTENT_USER" /><form-login login-page="/login2.jsp"authentication-failure-handler-ref="myAuthFailureHandler" default-target-url="/loginController.do" always-use-default-target="true" /><anonymous /><logout /><session-management><concurrency-control max-sessions="1"error-if-maximum-exceeded="true" /></session-management></http><beans:bean id="myAuthFailureHandler" name="code">package ethan.security;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.AuthenticationFailureHandler;public class myAuthFailureHandler implements AuthenticationFailureHandler {public void onAuthenticationFailure(HttpServletRequest request,HttpServletResponse response, AuthenticationException exception)throws IOException, ServletException {String json = "{status:'"+exception.getMessage()+"'}";response.setContentType("application/json;charset=UTF-8");response.getWriter().write(json);}}
?

?

3.extjs 源码:

?

?

Ext.onReady(function() {Ext.QuickTips.init();// create a formPanelvar loginPanel = new Ext.FormPanel({labelWidth : 75, // label settings here cascade unless// overriddenurl : 'j_spring_security_check',frame : true,title : 'Simple Form',bodyStyle : 'padding:5px 5px 0',width : 350,defaults : {width : 230},defaultType : 'textfield',items : [{id : 'j_username',name : 'j_username',fieldLabel : '用户名',allowBlank : false}, {inputType : 'password',id : 'j_password',name : 'j_password',fieldLabel : '密&nbsp;&nbsp;&nbsp;码',allowBlank : false}],buttons : [{text : '确认',formBind : true,handler : function() {if (loginPanel.getForm().isValid()) {loginPanel.getForm().submit({method : "post",success : function(form, action) {var obj = Ext.util.JSON.decode(action.response.responseText);alert('success:'+obj.status);if (obj.status == 'success') {window.location = 'welcomeController.do';} else {alert('failure reason:'+obj.status);loginPanel.getForm().reset();}},failure : function(form, action) {var obj = Ext.util.JSON.decode(action.response.responseText);alert('failure:'+obj.status);if (obj.status == 'success') {window.location = 'welcomeController.do';} else {alert('failure reason:'+obj.status);loginPanel.getForm().reset();}}// ,waitMsg : '正在保存数据,稍后...'});} else {Ext.Msg.alert('信息', '请填写完成再提交!');}},width : 60,border : true}]// ,renderTo : 'loginwindow'});loginPanel.render(document.body);});
?

4.LoginController 源码:

?

?

package ethan.controller;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;import org.springframework.web.servlet.ModelAndView;import ethan.model.Account;import ethan.security.WebUtil;public class LoginController extends BaseController {private Logger logger = Logger.getLogger(LoginController.class);@Overridepublic ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {logger.debug("come in LoginController..");response.setContentType("application/json;charset=UTF-8");Account account = WebUtil.getAccount();request.getSession().setAttribute("ACCOUNT", account);String json = "{status:'success'}";response.getWriter().write(json);// return new ModelAndView("index");return null;}}

?

?

5.WelcomeController源码:

?

?

?

package ethan.controller;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;public class WelcomeController extends BaseController {@Overridepublic ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { return new ModelAndView("index");}}

热点排行