首页 > 代码库 > 模拟springmvc 内部登陆,跳过spring filter

模拟springmvc 内部登陆,跳过spring filter

说明,因为我们的一个项目B使用spring mvc配置的登陆框架,所以对登陆控制全部交给了spring,导致我们如果想通过另一个项目A登陆到项目B就不太容易,具体是项目A登陆了,我们通过一个连接直接跳转到项目B,

前提,项目A用户名密码和项目B的用户名密码必须是一样的

难点:1.项目A用密文登陆,即前端JS对密码加密后传递给后天,但是项目B是明文直接传递给spring框架

思路:我开始通过debug往spring的代码里面寻求突破点,但是找了好长时间,发现跳转太多,不好找。后来,仔细想想,spring能通过什么来保存数据呢,当然是session啦

于是,就有下面的代码:

Set keySet = (Set)session.keySet();
        Object val = null;
        SecurityContextImpl securityContext = null;
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = null;
        for(Object key : keySet){
            val = session.get(key);
            if(val != null){
                securityContext = (SecurityContextImpl) val; //1. SecurityContextImpl
                System.out.println(securityContext.getAuthentication());
                usernamePasswordAuthenticationToken  = (UsernamePasswordAuthenticationToken) securityContext.getAuthentication();//2. UsernamePasswordAuthenticationToken

                System.out.println(JSONUtils.toJSONString(usernamePasswordAuthenticationToken));
                String credentials = usernamePasswordAuthenticationToken.getCredentials()+""; //3.Credentials
                if(credentials != null){
                    System.out.println("credentials============"+credentials);//通过直接打印可以发现该对象对应的实体
                    System.out.println(credentials);
                }
                Object principal = usernamePasswordAuthenticationToken.getPrincipal();
                if(principal != null){
                    System.out.println("principal============"+principal);//通过直接打印可以发现该对象对应的实体
                    System.out.println(JSONUtils.toJSONString(principal));//通过json输出可以查看该对象中的具体属性值
                }
                List<GrantedAuthority> grantedAuthorities = (List<GrantedAuthority>)usernamePasswordAuthenticationToken.getAuthorities();
                if(grantedAuthorities != null){
                    System.out.println("List<GrantedAuthority>============"+grantedAuthorities);//通过直接打印可以发现该对象对应的实体
                    System.out.println(JSONUtils.toJSONString(grantedAuthorities));
                }
            }
        }

通过查看所有的get方法,找到所有内部实体,然后在新模拟的登陆方法中生成这些对象

package com.rainsoft.services.index.action;

import com.rainsoft.common.utils.JSONUtils;
import com.rainsoft.framework.web.struts2.SimpleActionSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class ThirdLoginAction extends SimpleActionSupport {

    private static final Log logger = LogFactory.getLog(ThirdLoginAction.class);

    @Resource
    private DaoAuthenticationProvider daoAuthenticationProvider;
    @Resource
    private UserDetailsService userDetailServiceImpl;

    private SecurityContextImpl securityContextImpl;
    /**
     *
     * 方法功能说明:第三方登陆接口
     * @throws IOException
     * @date 2017/01/06 10:54:54
     */
    public void login() throws Exception {
        String userName = request.getParameter("username");
        String password = request.getParameter("password");
        /*Users user = new Users();
        user.setName(userName);
        user.setPassword(password);*/

        //认证信息,即明文密码,
        String credentials = password; //3.Credentials
        if(credentials != null){
            System.out.println("credentials============");
            System.out.println(credentials);
        }
        //

        //用户对象 principal============com.rainsoft.framework.entity.Users@a8833b7b
        UserDetails principal = userDetailServiceImpl.loadUserByUsername(userName);
        if(principal != null){
            System.out.println("principal============");
            System.out.println(JSONUtils.toJSONString(principal));
        }
        //用户角色
        List<GrantedAuthority> grantedAuthorities =new ArrayList<GrantedAuthority>();
        if(grantedAuthorities != null){
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USERS");
            grantedAuthorities.add(grantedAuthority);
        }

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(principal,password,grantedAuthorities);
        securityContextImpl = (SecurityContextImpl) SecurityContextHolder.getContext();
        securityContextImpl.setAuthentication(usernamePasswordAuthenticationToken);

        session.put("SPRING_SECURITY_CONTEXT",securityContextImpl);

        response.sendRedirect(request.getContextPath()+"/main!fmpg.do");

    }
}

通过上面的代码,我们就可以直接进入系统B,然后操作相应的菜单,以上只是我的个人理解,如果路过的童鞋们有更好的方法,希望不吝赐教

 

模拟springmvc 内部登陆,跳过spring filter