序:这里主要对springmvc 项目中用spring-security和shiro两种连接LDAP的配置做说明

用来实现ldap对用户登录及权限的管理 

一:spring security方式

(1)配置web.xml和导jar包:这里用maven 导入(spring-ldap-core  spring-ldap-core-tiger  spring-security-ldap  spring-security-core  spring-security-web spring-security-config  spring-security-taglibs,这些都是1.31版本的jar)
 可能有些包不用,但是我都加了 (礼多人不怪)
 
 
在web.xml里加入如下
   springSecurityFilterChain
   org.springframework.web.filter.DelegatingFilterProxy
  springSecurityFilterChain
  /*
(2).配置spring-security文件
xmlns:s="http://www.springframework.org/schema/security" 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.xsd">
access="IS_AUTHENTICATED_ANONYMOUSLY" />
 
       
group-search-filter="member={0}" group-search-base="ou=groups"
user-search-base="ou=people" user-search-filter="uid={0}" />
class="org.springframework.security.web.access.ExceptionTranslationFilter">
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
class="org.springframework.security.web.session.ConcurrentSessionFilter">
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
 
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
class="org.springframework.security.ldap.authentication.BindAuthenticator">
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
 
(3) 自定义拦截器com.zqgame.util.MySpecialAuthenticationFilter
这个拦截器就是做ldap登录认证的,里面包括了一些用户输入信息正确性判断和验证码判断(所有不能登录情况都是异常捕获)AuthenticationServiceException会根据上面的配置文件中登录错误的配置而跳转
 
package com.zqgame.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
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;
public class MySpecialAuthenticationFilter extends AbstractAuthenticationProcessingFilter{
public MySpecialAuthenticationFilter() {
super("/auth");//这个auth就是外面要访问这个拦截器的入口
}
    public MySpecialAuthenticationFilter(String defaultFilterProcessesUrl) {
super("/auth");
}
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
    private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
    private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
   public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
HttpSession session = request.getSession();
String username = obtainUsername(request);
String password = obtainPassword(request);
String catchImage = request.getParameter("captcha");//验证码
//判断用户名登录密码是否为空
       if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
session.setAttribute("loginError", "请输入用户名或者密码!");
throw new AuthenticationServiceException("j_username or j_password is not null!"); //跳转到login_error下
}
// 从session中获得验证码,与用户输入的验证码做比较
String sessionCaptcha = (String) session.getAttribute(Constant.CAPTCHA);
if (StringUtils.isEmpty(catchImage) || StringUtils.isEmpty(sessionCaptcha)) {
session.setAttribute("loginError", "验证码为空!");
  throw new AuthenticationServiceException("the session captcha is not null!");//跳转到login_error下
  }
session.removeAttribute(Constant.CAPTCHA);// 清空Sesion里的验证码
         //验证码输入校验
        if (!sessionCaptcha.equalsIgnoreCase(catchImage)) {
        session.setAttribute("loginError", "验证码输入错误!");
throw new AuthenticationServiceException("the captcha is error!");//跳转到login_error下
}                
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);
setDetails(request, authRequest);
Authentication authen = null;
      //执行ldap的登录验证
try {
 authen = this.getAuthenticationManager().authenticate(authRequest);
} catch (AuthenticationException failed) {
         session.setAttribute("loginError", "用户名或密码错误!");
  throw new AuthenticationServiceException("the captcha is error!");//跳转到login_error
}
session.setAttribute("managerSession", username);
   return authen;
}
 
   
    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(passwordParameter);
    }
 
   
    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(usernameParameter);
    }
 
   
    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}
 
 
(4)登录Action类
package com.zqgame.controllers.admin;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.zqgame.common.Constant;
import com.zqgame.models.SignIn;
import com.zqgame.services.UserService;
import com.zqgame.util.Digest;
/**
 * 后台登录控制器
 * @author User
*/
@Controller
public class SessionsController{
/**
* 进入登录页面
* @return
*/
@RequestMapping(value = "/sign_in", method = RequestMethod.GET)
public String newForm(Model model) {
return "admin/sessions/new";
}
 
/**
* 登录错误
* @return
*/
@RequestMapping(value = "/login_error", method = RequestMethod.GET)
public String loginError(Model model) {
return "admin/sessions/new";
}
/**
* 退出登录 logout() 销毁会话 
* @param request
* @return
*/
@RequestMapping(value = "signout")
public void signOut(HttpServletRequest request, HttpServletResponse response) {
try {
SecurityContextLogoutHandler securityLogout = new SecurityContextLogoutHandler();
securityLogout.logout(request, response, null);
request.getRequestDispatcher(
"WEB-INF/views/admin/sessions/loginout.jsp").forward(
request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
(5)登录jsp页面form部分
//auth就是那个自定义拦截器的访问路径,而不是去action
//删除session中存储的错误提示
用户:

密码:

验证码:

这个验证码具体怎么生成的这里不做说明
登 录
上面就是整个LDAP与spring-security的配置了,当然这里只是我自己的处理方式,可能还有很多不好的地方,希望拍砖
 
二.Shiro 方式
(1)配置web.xml和导包(shiro-core  shiro-web shiro-spring  cglib-nodep 版本1.2.0)
Web.xml里加入
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
       
            targetFilterLifecycle
            true
       
   
    
   
        shiroFilter
        /*
(2)Shiro配置文件(文档里有注释,这个配置文件基本上不用改啥)
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
 
       
         
       
                /sign_in = anon
                /admin/** = authc
                /sign_up = anon
                /captcha-p_w_picpath = anon
                /sessions/** = anon
     
       
       
     
     
       
       
       
     
   
       
       
   
       
   
       
   
(3)登录action(这里action不用那么麻烦,所以这里就把登录的action和退出的action写上吧)
/*执行登录*/
public String create(@Valid SignIn signIn, BindingResult result, HttpSession session, Model model) {
       if (result.hasErrors()) {
        model.addAttribute("loginError", "请输入内容!");
        model.addAttribute("signIn", signIn);
            return "admin/sessions/new";
        }
    //从session中获得验证码
    String sessionCaptcha = (String) session.getAttribute(Constant.CAPTCHA);
    if(StringUtils.isEmpty(sessionCaptcha)) {
    model.addAttribute("loginError", "session里的验证码为空!");
    return "admin/sessions/new";
    }
    session.removeAttribute(Constant.CAPTCHA);//清空验证码
        if(!sessionCaptcha.equalsIgnoreCase(signIn.getCaptcha())) {
        model.addAttribute("loginError", "验证码输入错误!");
        return "admin/sessions/new";
        } 
       /*shiro执行ldap登录认证*/
        UsernamePasswordToken token = new UsernamePasswordToken(signIn.getUsername(), signIn.getPassword());
        token.setRememberMe(true);
        Subject currentUser = SecurityUtils.getSubject();
        try {
            currentUser.login(token);
            session.setAttribute(Constant.MANAGER_SESSION, signIn.getUsername());
        }catch (Exception ice) {
             result.reject("mismatch.signIn.password"); 
            //password didn't match, try again?
        } 
        if (currentUser.isAuthenticated()) {//登录成功进入主页
            return "redirect:/body/adminmain";
        }
        model.addAttribute("loginError", "您输入的用户名或密码错误!");
        return "admin/sessions/new";
    }
/**
* 退出登录
* logout() 销毁回话
* @return
*/
@RequestMapping(value = "signout", method = RequestMethod.GET)
 public void signOut(HttpServletRequest request, HttpServletResponse response) {
    SecurityUtils.getSubject().logout();
    try {
request.getRequestDispatcher("WEB-INF/views/admin/sessions/loginout.jsp").forward(request, response);
} catch (ServletException e) {
          e.printStackTrace();
} catch (IOException e) {
 e.printStackTrace();
}
}
到此两种方式都可以使用了,至于那个配置文件,可以把他放到web.xml里加载就行,就跟加载spring的文件一样就行
另:ldap本身的性质还在研究,不会哦

转载于:https://blog.51cto.com/3131854/1149082

你可能感兴趣的:(用户登录权限管理LDAP两种配置参考文档(spring-security和shiro))