(1)加密工具的抽取

import org.apache.shiro.crypto.hash.SimpleHash;
public class MD5Util {//加密方式public static final String ALGORITHMNAME = "MD5";//盐值public static final String SALT  ="source";//加密次数public static final int HASHITERATIONS  = 10;//把密码传进来进行加密public static String  createMD5(String password){SimpleHash hash = new SimpleHash(ALGORITHMNAME,password,SALT,HASHITERATIONS);return hash.toString();}
}

(2)自定义一个类实现AuthorizingRealm,它有两个方法,doGetAuthenticationInfo身份验证和doGetAuthorizationInfo授权
我们需要从写里面的逻辑

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
public class MyRealm extends AuthorizingRealm {@Autowiredprivate IEmployeeService employeeService ;@Override//授权protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}@Override//身份认证protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//判断当前登录用户账号是否存在String username = (String)token.getPrincipal();
//从数据根据名字取查询有没有这个人物Employee employee  =employeeService.findByUsername(username);if(employee==null){return null ;}//判断密码是否正确//加盐ByteSource source = ByteSource.Util.bytes(MD5Util.SALT);//第一个参数用户的身份,第二个是数据库查询的密码,第三个加盐,第四个当前realm的名字SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(employee, employee.getPassword(), source, getName());return info ;}
}

(3)applicationContext-shiro的配置,注意在applicationContext中引用这个配置,还有shiro的监听器要和web.xml中配置的名字相同

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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.xsd"><!-- 安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="myRealm"/></bean><bean id="myRealm" class="cn.yhh.realm.MyRealm"><property name="name" value="myRealm"/><!-- 配置密码匹配器 --><property name="credentialsMatcher">
//自定义的验证器,第三方登录中需要跳过密码的验证<bean class="cn.yhh.realm.RetryLimitHashedCredentialsMatcher"><!--认证方式--><property name="hashAlgorithmName" value="MD5"/><!--加密次数--><property name="hashIterations" value="10"/></bean></property></bean><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager"/><!--如果没有认证,都跳到loginUrl对应的路径--><property name="loginUrl" value="/login"/><!--如果认证通过之后,就跳到successUrl对应的路径--><property name="successUrl" value="/s/success.jsp"/><!--如果你访问某个资源,没有权限,就跳到unauthorizedUrl对应的路径中--><property name="unauthorizedUrl" value="/s/unauthorized.jsp"/><property name="filterChainDefinitions"><value>/login.jsp = anon/code.html = anon/logout = logout/wechat/callback=anon//微信跳转需要的路径/static/** = anon/** = user //表示携带User对象的用户可以访问所有资源</value></property></bean>
</beans>

4)微信登录

  • 因为三方登录是不要进行密码的验证的,所有我们自定义一个类去继承HashedCredentialsMatcher(在shiro.xml中配置),我们只需要用户授权就可以,不需要进行验证密码,
    但是我们用shiro 登录需要拿到一个token的令牌,所以我们又要自定义一个类去覆写UsernamePasswordToken,为了方便可以定义一个枚举表示当前的登录类型
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {@Overridepublic boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {EasyTypeToken tk = (EasyTypeToken) authcToken;//如果是免密登录直接返回trueif(tk.getType().equals(LoginType.NOPASSWD)){return true;}//不是免密登录,调用父类的方法return super.doCredentialsMatch(tk, info);}
}
import org.apache.shiro.authc.UsernamePasswordToken;
public class EasyTypeToken extends UsernamePasswordToken {//这随便写的吧应该都可以private static final long serialVersionUID = -2564928913725078138L;private LoginType type;//表示当前登录的类型public EasyTypeToken() {super();}public EasyTypeToken(String username, String password, LoginType type, boolean rememberMe,  String host) {super(username, password, rememberMe,  host);this.type = type;}/**免密登录*/public EasyTypeToken(String username) {super(username, "", false, null);this.type = LoginType.NOPASSWD;}/**账号密码登录*/public EasyTypeToken(String username, String password) {super(username, password, false, null);this.type = LoginType.PASSWORD;}public LoginType getType() {return type;}public void setType(LoginType type) {this.type = type;}
}
public enum LoginType {PASSWORD("password"), // 密码登录NOPASSWD("nopassword"); // 免密登录private String code;// 状态值private LoginType(String code) {this.code = code;}public String getCode () {return code;}
}
  • 微信登录需要去微信卡发着平台申请拿到最主要的appid和secret
    在页面我们需要引入他的js文件
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
<!--定义一个容器装二维码-->
<div id="login_container">
</div>
</body>
<script>var obj = new WxLogin({self_redirect:false,id:"login_container",/*容器的id*/appid: "你自己申请的",scope: "snsapi_login",redirect_uri: "",//响应授权码的地址-第一部分是申请下来的地址,第二部分是跳转后台的路径state: "xxx",----状态,多用于判断当前登录的状态是否安全style: "white", ---二维码的颜色href: ""});
</script>
  • 导入jar包
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version></dependency>

跳转后台的controller

import com.alibaba.fastjson.JSON;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.Map;
@Controller
public class WxCharController {@Autowiredprivate IEmployeeService employeeService ;@RequestMapping("/wechat/callback")public String callback(String code , String state){//这里可以判断state是否改变判断此次请求是否安全//得到code换取token的地址String getTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" +"appid=你自己申请的&secret=和appid一样&code="+code+"&grant_type=authorization_code";//得到地址后通过工具类得到tokenString tokenResult = HttpClientUtil.doGet(getTokenUrl);System.out.println(tokenResult);//得到的token是json格式,将他转成map,得到换取用户资源的openid和access_tokenMap<String,String> tokenResultMap = JSON.parseObject(tokenResult,Map.class);//拿到token之后,换取用户资源String tokenString = tokenResultMap.get("access_token");String openId = tokenResultMap.get("openid");String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token="+tokenString+"&openid="+openId;//拿到了用户的基本信息String userResultStr = HttpClientUtil.doGet(userInfoUrl);System.out.println(userResultStr);
//根据opoenId去数据库获取user对象Employee employee  =employeeService.findByOpenid(openId);//如果user不为空 ,代码里面直接调用shiro的登录 -> 直接跳转主页if(employee!=null){String username = employee.getUsername();//这里用的就是我覆写的,并且通过自定义的拦截器,跳过密码的验证EasyTypeToken token = new EasyTypeToken(username);Subject subject = SecurityUtils.getSubject();subject.login(token);
//从session中拿到用户对象UserContext.setUserInSession(employee);return "main";}else {//如果user为空,说明这个openid没有绑定过,那么久要跳转到绑定页面}//绑定页面显示两种情况 : 绑定已有账号 ; 绑定新注册账号 ,把openId传入到页面//如果提交的是已有账号绑定 用户名 ,密码 ,openId//带着用户名和密码去数据库中查询 ,如果查到了User  ,就修改User.openId 设置进去 ,update.user//如果是提交注册 :用户名 ,密码 ,验证码 ,手机号  , openId//先做注册操作 insert.user  ,把openId和user信息一并保存return null ;

抽取通过地址获得token的工具

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;public class HttpClientUtil {// http://bugtracker.itsource.cn/wechat/callback?code=222&state=99// http://bugtracker.itsource.cn/wechat/callback    code=222&state=99public static String doGet(String uri) {//1:创建一个HttpClient的实例CloseableHttpClient httpclient = HttpClients.createDefault();//2:创建一个get请求实例HttpGet httpGet = new HttpGet(uri);//请求的响应:CloseableHttpResponse response1 = null;try {//3:使用HttpClient的实例执行get请求response1 = httpclient.execute(httpGet);//http请求的状态:404 500 200System.out.println(response1.getStatusLine());int statusCode = response1.getStatusLine().getStatusCode();if (statusCode == 200) {//请求成功:HttpEntity entity1 = response1.getEntity();String result = EntityUtils.toString(entity1, "utf-8");System.out.println(result);return result;} else {//请求失败:自己做自己的业务逻辑System.out.println("请求失败......:"+statusCode);}} catch (Exception ex) {ex.printStackTrace();}return null;}
}

shiro+微信登录整合相关推荐

  1. 微信登录整合——app、小程序、公众号、扫码

    慢慢的你会发现除了获取参数的地方不一样,登录流程都差不多,可能是接口路径啥的不太一致 但是获取用户信息,出奇的一至:https://api.weixin.qq.com/sns/userinfo 获取o ...

  2. Shiro与Springboot整合:配置依赖改造登录方法

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  3. SpringBoot整合Shiro实现登录认证和授权CHCache

    文章目录 一. springboot实现普通登录 1 添加依赖 2 编写配置文件 3 新建实体类和mapper 4 编写业务层代码 5 编写控制器 6 编写启动类 7 编写登录页面和主页面 二. sp ...

  4. springboot系列(十)springboot整合shiro实现登录认证

    关于shiro的概念和知识本篇不做详细介绍,但是shiro的概念还是需要做做功课的要不无法理解它的运作原理就无法理解使用shiro: 本篇主要讲解如何使用shiro实现登录认证,下篇讲解使用shiro ...

  5. Shiro与SpringBoot整合,实现登录拦截、用户认证、用户授权等。实战demo

    文章目录 开篇必读: 一.开发环境 二.项目搭建 三.配置 shiro 配置类 1.自定义 Realm 类. 2.创建shiro配置类. 四.创建页面.Controller. Service等. 五. ...

  6. SpringBoot整合小程序微信登录功能

    一.SpringBoot整合微信登录 ​ 小程序的使用已经是一个普遍的现象,对于刚学习SpringBoot的我们来说完全的写好一套微信登录的案例有一定的难度,这里结合自己的一些学习经验,把微信登录这一 ...

  7. 尚硅谷谷粒学院学习笔记9--前台用户登录,注册,整合jwt,微信登录

    用户登录业务 单点登录(Single Sign On),简称SSO. 用户只需要登陆一次就可以访问所有相互信任的应用系统 单点登录三种常见方式 session广播机制实现 使用redis+cookie ...

  8. JustAuth发布1.10.0版本,集成华为和企业微信登录,更加灵活的state缓存

    JustAuth发布1.10.0版本,集成华为和企业微信登录,更加灵活的state缓存 更新内容 新增 增加AuthCache配置类AuthCacheConfig.java,可以自定义缓存有效期以及是 ...

  9. shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决

    shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决 from :http://blog.csdn.net/babys/article/ ...

  10. shiro分布式控制登录状态_Shiro——强大且易用的Java安全框架(四)

    [Shiro] 十五.Thymeleaf整合shiro 1.添加依赖 2.修改index.html 访问页面后会发现"有角色"不显示,"有权限"显示. 3.修改 ...

最新文章

  1. 问题解决java.lang.IllegalArgumentException at org.springframework.asm.ClassReader
  2. 中科罗伯特工业机器人_「聚焦中日韩产业博览会」丈夫看机器人,妻子忙采购...
  3. 加载geojson面数据_地理数据可视化
  4. 超级楼梯[HDU2041]
  5. java语言中实现键盘输入_Java程序设计中的键盘输入数据的方法分析
  6. Vue项目部署到服务器上路由无法访问的问题
  7. 疯狂java 李刚 pdf_Java开发教程 – 《疯狂Java讲义第4版》PDF及代码+李刚
  8. 2016年计算机一级excel试题及答案,2016年计算机一级试题加答案
  9. 新版掌上阅读小说源码+支持公众号/分站/封装APP
  10. 关于GitHub如何转为中文问题——Google举例
  11. 哔哩哔哩APP导出缓存视频并合并成MP4
  12. 业务流程图设计-Visio设计
  13. form表单提交方式
  14. fluent二维叶型仿真_公开课 l 基于SCORG的双螺杆压缩机流体仿真分析应用
  15. Android项目CJM9之新闻浏览模块的实现
  16. PO、VO、DO、TO、DTO、 BO、 QO、DAO、POJO
  17. OneDrive登录问题
  18. flutter 仿网易云音乐(3)
  19. 数据分析应学习逻辑思维及分析方法
  20. HTML绘制七巧板,canvas绘制七巧板

热门文章

  1. 支配节点树及其构建算法 Dominator-tree and its Construction Algorithms
  2. php精华之独孤九剑
  3. 小游戏——满天小星星
  4. 职场最高级的聪明是靠谱,到底一个人怎样才算真正靠谱?
  5. OAS的使用——Python SDK
  6. 稳压、调压、监控、DC/DC电路大全2
  7. ios 获取沙盒文件名_iOS之沙盒路径
  8. Global.asax 文件是什么
  9. 常见数据收集网站-数学建模(二十二)
  10. Banner打造广告自动轮播图