分享在SSM框架中用第三方登录怎么绕过shiro的认证

问题描述:

用ssm框架整合shiro管理系统,然后想实现第三方登录功能,比如(qq,微信等),但是遇到了一个棘手的问题,用第三方登录,我们怎么去实现对用户的授权,这个问题困扰了我很久,网上找了很多相关的资料,都没有一个很好答案,然后自己摸索了许久,终于搞定了,所以想很你们分享一哈,哈哈哈。(如果密码不用md5不可逆加密,那就非常好实现了

效果演示:

分享在SSM框架中用第三方登录怎么绕过shiro的认证_第1张图片

分享在SSM框架中用第三方登录怎么绕过shiro的认证_第2张图片

我们看一下后台具体情况:

分享在SSM框架中用第三方登录怎么绕过shiro的认证_第3张图片

然后我们可以拿到QQ用户信息,将需要的信息保存到我们系统的数据库中,我们可以根据openid来判断该用户信息是否完整,如果openid为空,说明该用户是第一次登陆,我们要让用户完善信息,反之,让用户登录。


那问题来了,我该怎么在ssm+shiro框架中进行修改,才能用第三方登录成功通过shiro认证,并实现登录

1.重写HashedCredentialsMatcher(spring-shiro.xml)


         
            
  
package com.demo.core.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

/**
 * @Author: cxx
 * @Date: 2018/3/14 11:30
 */
public class CybHashedCredentialsMatcher extends HashedCredentialsMatcher {
    @Override
    public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
        UsernamePasswordLoginTypeToken token = (UsernamePasswordLoginTypeToken) authcToken;
//      UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        Object accountCredentials = getCredentials(info);
        String pwd = String.valueOf(token.getPassword());
        System.out.println("*************密码"+pwd+":::"+pwd.length());
        System.out.println("accountCredentials:"+accountCredentials);
        if(pwd.length() == 32){
            System.out.println("进来了,对加密密码进行比较");
            return true;
            //return equals(pwd, accountCredentials);
        }
        //将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
        return super.doCredentialsMatch(token, info) ;
    }
}
2.重写UsernamePasswordToken

package com.demo.core.shiro;

import org.apache.shiro.authc.UsernamePasswordToken;

public class UsernamePasswordLoginTypeToken extends UsernamePasswordToken {
    public UsernamePasswordLoginTypeToken(){
        super();
    }

    public String getUphoneNum() {
        return uphoneNum;
    }
    public void setUphoneNum(String uphoneNum) {
        this.uphoneNum = uphoneNum;
    }
    public String getLoginType() {
        return loginType;
    }
    public void setLoginType(String loginType) {
        this.loginType = loginType;
    }
    public String getUtoken() {
        return utoken;
    }
    public void setUtoken(String utoken) {
        this.utoken = utoken;
    }

    private String loginType = "0";// 0为用户密码登录,1为第三方登录登录
    private String utoken;
    private String uphoneNum;

    public UsernamePasswordLoginTypeToken(final String username, final String password,
                                          final boolean rememberMe, String loginType, String utoken) {
        super(username, password, rememberMe);
        this.loginType = loginType;
        this.utoken = utoken;
        this.uphoneNum = uphoneNum;
    }
}

我们判断是那种登录的时候,我们只需要改变loginType的值就ok了。

用户名和密码:

 @RequestMapping(value = "/login",method = RequestMethod.POST,produces = "text/html;charset=UTF-8")
    @ResponseBody
    public String CheckLogin(HttpServletRequest request, HttpServletResponse response) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String remberme = request.getParameter("remberme");
        Boolean isRemberme=false;
        if (!StringUtils.isBlank(remberme)){
            isRemberme=true;
            //记住用户
            BASE64Encoder base64Encoder = new BASE64Encoder();
            Cookie nameCookie = new Cookie("name",username);
            Cookie pwdCookie = new Cookie("pwd",base64Encoder.encode(password.getBytes()));
            //3天
            nameCookie.setMaxAge(3*24*60*60);
            pwdCookie.setMaxAge(3*24*60*60);
            response.addCookie(nameCookie);
            response.addCookie(pwdCookie);
        }else{//清除cookie
            Cookie[] cookies = request.getCookies();
            for(Cookie cookie:cookies ){
                if (cookie.getName().equals("name")||cookie.getName().equals("pwd")) {
                    cookie.setValue(null);
                    cookie.setMaxAge(0);// 立即销毁cookie
                    System.out.println("被删除的cookie名字为:" + cookie.getName());
                    response.addCookie(cookie);
                }
            }
        }
        Subject currentUser = SecurityUtils.getSubject();
        HttpSession session = request.getSession();
        session.setAttribute("username",username);
        AjaxJson ajaxJson = new AjaxJson();
        ajaxJson.setRet(200);
        ajaxJson.setMsg("登录成功");
        //UsernamePasswordToken token =new UsernamePasswordToken(username,password);
        UsernamePasswordLoginTypeToken token = new UsernamePasswordLoginTypeToken(username,password,true,"0",password);
        try{
            if(!currentUser.isAuthenticated()){
                System.out.println("验证角色和权限");
                token.setRememberMe(isRemberme);
                currentUser.login(token);//验证角色和权限
                ajaxJson.setRet(200);
                ajaxJson.setMsg("登录成功");
            }
        }catch(UnknownAccountException e){
            System.out.println(e.getMessage());
            ajaxJson.setRet(400);
            ajaxJson.setMsg(e.getMessage());
        }catch (LockedAccountException e){
            System.out.println(e.getMessage());
            ajaxJson.setRet(400);
            ajaxJson.setMsg(e.getMessage());
        }catch(IncorrectCredentialsException e){
            //用户名/密码错误
            System.out.println(e.getMessage());
            ajaxJson.setRet(400);
            ajaxJson.setMsg("用户密码错误,请重试");
        }catch (AuthenticationException e) {
            String emsg = "其他异常:"+e.getMessage();
            System.out.println(emsg);
            ajaxJson.setRet(400);
            ajaxJson.setMsg("服务器开小差了");
        }
    return JSONObject.toJSONString(ajaxJson);
    }

QQ扫码登录:

@RequestMapping(value = "/afterQQlogin",method = RequestMethod.GET)
    public String QQsuccess(HttpServletRequest request, HttpServletResponse response){
        response.setContentType("text/html;charset=utf-8");
        try {
            AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
            String accessToken = null, openID = null;
            long tokenExpireIn = 0L;
            if (accessTokenObj.getAccessToken().equals("")) {
                System.out.println("没有获取到响应参数");
                try {
                    response.sendRedirect("QQlogin");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }else{
                accessToken = accessTokenObj.getAccessToken();
                tokenExpireIn = accessTokenObj.getExpireIn();
                // 利用获取到的accessToken 去获取当前用的openid -------- start
                OpenID openIDObj =  new OpenID(accessToken);
                openID = openIDObj.getUserOpenID();
                List users = userService.findByqqOpenId(openID);
                String touser = users.get(0).getUsername();
                String topwd = users.get(0).getPassword();
                if (users.size()>0){
                    System.out.println("直接登录"+users.get(0).getUsername()+topwd);
                    UsernamePasswordLoginTypeToken token = new UsernamePasswordLoginTypeToken(touser,topwd,false,"1",topwd);
                    HttpSession session = request.getSession();
                    session.setAttribute("username",users.get(0).getUsername());
                    Subject currentUser = SecurityUtils.getSubject();
                    if(!currentUser.isAuthenticated()) {
                        System.out.println("验证角色和权限");
                        currentUser.login(token);//验证角色和权限
                    }
                    System.out.println("admin/index----->");
                    return "redirect:/admin/index";
                }
                System.out.println("openid:" + openID);
                request.getSession().setAttribute("qqOpenid", openID);
                // 利用获取到的accessToken 去获取当前用户的openid --------- end
                UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);
                UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
                if (userInfoBean.getRet() == 0) {
                    System.out.println(userInfoBean.getNickname());
                    System.out.println("
"); } else { System.out.println("很抱歉,没能正确获取到您的信息,原因是: " + userInfoBean.getMsg()); } } } catch (QQConnectException e) { e.printStackTrace(); } return "modules/qqLogin/index"; }


你可能感兴趣的:(工具使用)