如果一个系统分为前台用户和后台用户那么就不能使用spring-security的默认配置了。 需要自己来分开配置两种用户的登录方式。
首先创建spring-disuser-security.xml 与 spring-etuser-security.xml 两个配置文件,分别来配置两种用户登录的权限与验证方式
spring-disuser-security.xml的内容如下
接下来编写DisUsernamePasswordAuthenticationFilter.java文件,处理用户登录。
spring-security默认的处理登录的类是org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter,可以将其中的代码复制到自己写的DisUsernamePasswordAuthenticationFilter.java文件中。
然后在进行自己的修改,达到验证验证码,与公司登录id的验证。
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* 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 com.tuanfang.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.util.Assert;
/**
* Processes an authentication form submission. Called {@code AuthenticationProcessingFilter} prior to Spring Security
* 3.0.
*
* Login forms must present two parameters to this filter: a username and
* password. The default parameter names to use are contained in the
* static fields {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}.
* The parameter names can also be changed by setting the {@code usernameParameter} and {@code passwordParameter}
* properties.
*
* This filter by default responds to the URL {@code /j_spring_security_check}.
*
* @author Ben Alex
* @author Colin Sampaleanu
* @author Luke Taylor
* @since 3.0
*/
public class DisUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
//~ Static fields/initializers =====================================================================================
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_FORM_YZM_KEY = "yzm";
public static final String SPRING_SECURITY_FORM_LOGINID_KEY = "loginid";
public static final String USERNAME_LOGINID_SPLIT = "/";
/**
* @deprecated If you want to retain the username, cache it in a customized {@code AuthenticationFailureHandler}
*/
@Deprecated
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private String yzm = SPRING_SECURITY_FORM_YZM_KEY;
private String loginid = SPRING_SECURITY_FORM_LOGINID_KEY;
private boolean postOnly = true;
//~ Constructors ===================================================================================================
public DisUsernamePasswordAuthenticationFilter() {
super("/j_spring_security_check");
}
//~ Methods ========================================================================================================
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
String loginid = obtainLoginid(request);
String yzm = obtainYzm(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
if (loginid == null) {
loginid = "";
}
if (yzm == null) {
yzm = "";
}
username = username.trim();
password = password.trim();
loginid = loginid.trim();
yzm = yzm.trim();
username = loginid + USERNAME_LOGINID_SPLIT + username ; //将公司登录id与登录用户名使用 / 连接起来
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
/**
* Enables subclasses to override the composition of the password, such as by including additional values
* and a separator.
This might be used for example if a postcode/zipcode was required in addition to the
* password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
* AuthenticationDao
will need to generate the expected password in a corresponding manner.
*
* @param request so that request attributes can be retrieved
*
* @return the password that will be presented in the Authentication
request token to the
* AuthenticationManager
*/
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
//获取验证码
protected String obtainYzm(HttpServletRequest request){
return request.getParameter(yzm);
}
//获取公司id
protected String obtainLoginid(HttpServletRequest request){
return request.getParameter(loginid);
}
/**
* Enables subclasses to override the composition of the username, such as by including additional values
* and a separator.
*
* @param request so that request attributes can be retrieved
*
* @return the username that will be presented in the Authentication
request token to the
* AuthenticationManager
*/
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
/**
* Provided so that subclasses may configure what is put into the authentication request's details
* property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details set
*/
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
/**
* Sets the parameter name which will be used to obtain the username from the login request.
*
* @param usernameParameter the parameter name. Defaults to "j_username".
*/
public void setUsernameParameter(String usernameParameter) {
Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
this.usernameParameter = usernameParameter;
}
/**
* Sets the parameter name which will be used to obtain the password from the login request..
*
* @param passwordParameter the parameter name. Defaults to "j_password".
*/
public void setPasswordParameter(String passwordParameter) {
Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
this.passwordParameter = passwordParameter;
}
/**
* Defines whether only HTTP POST requests will be allowed by this filter.
* If set to true, and an authentication request is received which is not a POST request, an exception will
* be raised immediately and authentication will not be attempted. The unsuccessfulAuthentication() method
* will be called as if handling a failed authentication.
*
* Defaults to true but may be overridden by subclasses.
*/
public void setPostOnly(boolean postOnly) {
this.postOnly = postOnly;
}
public final String getUsernameParameter() {
return usernameParameter;
}
public final String getPasswordParameter() {
return passwordParameter;
}
public String getYzm() {
return yzm;
}
public void setYzm(String yzm) {
this.yzm = yzm;
}
public String getLoginid() {
return loginid;
}
public void setLoginid(String loginid) {
this.loginid = loginid;
}
}
接下来编写提供Disuser的UserDetailsService类
package com.tuanfang.service;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;
import com.tuanfang.dao.impl.DisuserDaoImpl;
import com.tuanfang.dao.impl.SysPowrDaoImpl;
import com.tuanfang.pojo.Disuser;
import com.tuanfang.pojo.SysPower;
@Repository("DisuserserDetailService")
public class DisuserserDetailService implements UserDetailsService{
@Resource(name="DisuserDaoImpl")
private DisuserDaoImpl disuserDao ;
@Resource(name="SysPowrDaoImpl")
private SysPowrDaoImpl sysPowrDao ;
@Override
public UserDetails loadUserByUsername(String usernameAndloginId)
throws UsernameNotFoundException {
//将公司登录id与登录用户名使用/分开
String args[] = usernameAndloginId.split(DisUsernamePasswordAuthenticationFilter.USERNAME_LOGINID_SPLIT);
String loginid = args[0];
String username = args[1];
Disuser disuser = disuserDao.findByLoginIdAndUserName(loginid , username);
UserDetails userDetail = null ;
if(disuser != null){
userDetail = new User(username, disuser.getPassword(),disuser.getStatus() ==Disuser.ENABLE ,
true, true, true, obtainUserPowers(disuser.getId()));
}
return userDetail;
}
public Collection obtainUserPowers(BigInteger userId){
Collection gas = new ArrayList();
List powers = sysPowrDao.findDisuserPowers(userId);
if(powers != null && powers.size() > 0){
for (SysPower sysPower : powers) {
gas.add(new SimpleGrantedAuthority(sysPower.getCode()));
}
}
gas.add(new SimpleGrantedAuthority("HAVE_LOGIN")); //登录
return gas ;
}
}
登录页面disuserlogin.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
DisuserLogin
这样就配置好了Disuser的login
接下来配置EtdsUser的login。只需要username与password
spring-etuser-security.xml文件内容如下(使用spring-security默认的方式配置):
package com.tuanfang.service;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;
import com.tuanfang.dao.impl.EtdsuserDaoImpl;
import com.tuanfang.dao.impl.SysPowrDaoImpl;
import com.tuanfang.pojo.EtdsUser;
import com.tuanfang.pojo.SysPower;
@Repository("EtuserDetailService")
public class EtuserDetailService implements UserDetailsService{
@Resource(name="EtdsuserDaoImpl")
private EtdsuserDaoImpl etdsuserDao ;
@Resource(name="SysPowrDaoImpl")
private SysPowrDaoImpl sysPowrDao ;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
EtdsUser etuser = etdsuserDao.findUserByLoginName(username);
UserDetails userDetail = null ;
if(etuser != null){
userDetail = new User(username, etuser.getPassword(),etuser.getStatus() ==EtdsUser.ENABLE ,
true, true, true, obtainUserPowers(etuser.getId()));
}
return userDetail;
}
public Collection obtainUserPowers(BigInteger userId){
Collection gas = new ArrayList();
List powers = sysPowrDao.findEtuserPowers(userId);
if(powers != null && powers.size() > 0){
for (SysPower sysPower : powers) {
gas.add(new SimpleGrantedAuthority(sysPower.getCode()));
}
}
gas.add(new SimpleGrantedAuthority("HAVE_LOGIN")); //登录
return gas ;
}
}