博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Shiro整合SSO单点登录系统
阅读量:3529 次
发布时间:2019-05-20

本文共 7821 字,大约阅读时间需要 26 分钟。

前言

shiro是一个非常强大的权限管理框架,关于shiro与cas整合的示例有很多,但是我们平时开发的时候,很多公司并不是使用cas来做SSO的,而是自己公司会用自己开发的。本文就主要针对这种方式的整合。

新增SSO相关的properties

#sso服务器登录地址,service参数表示登录成功后要跳转的地址ssoServiceUrl=http://www.authserver.com/auth/login?service=http://www.client.com/user/login#sso的token的校验地址tokenValidateUrl=http://www.authserver.com:9999/auth/validatetoken#应用名称标识microServiceId=app#redis相关信息JedisUrl=198.168.1.101JedisPort=6379JedisPassword=666666
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

修改spring-shiro.xml

/kaptcha.jpg=anon /assets/** = anon /images/** = anon /javascripts/** = anon /stylesheets/** = anon /user/login = anon /httpserver/* = anon /** = authc
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

自定义ssoFilter

/** * sso自定义过滤器 */public class SSOFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; String token = request.getParameter("token"); PropertiesTool propertiesTool = PropertiesTool.getInstance(); String ssoServiceUrl = propertiesTool.getValue("ssoServiceUrl"); String tokenValidateUrl = propertiesTool.getValue("tokenValidateUrl"); if(null == token) { Cookie cookie = CookieUtil.getCookieByName(request, "token"); if(null != cookie) { token = cookie.getValue(); } } if(null == token) { //没有token,重定向至sso server登录页 response.sendRedirect(ssoServiceUrl); }else { String urlString = request.getRequestURI(); if(urlString.endsWith("/logout")) { String JedisUrl = propertiesTool.getValue("JedisUrl"); String JedisPort = propertiesTool.getValue("JedisPort"); Jedis jedis = new Jedis(JedisUrl, Integer.parseInt(JedisPort)); jedis.del(token.getBytes()); jedis.close(); SecurityUtils.getSubject().logout(); response.sendRedirect(ssoServiceUrl);//重定向至sso server登录页 return; } //有token,去sso server验证token的有效性 Map
map = new HashMap<>(); map.put("token", token); String result = HttpClientUtil.doGet(tokenValidateUrl, map); if(StringUtils.isNotBlank(result)){
//验证成功,跳转至首页,并从redis中获取权限 SystemSession.setUser(SSOTokenUtil.getToken(request));//设置系统session(把用户信息保存在ThreadLocal中) Cookie cookie = new Cookie("token", token); cookie.setPath("/"); response.addCookie(cookie); filterChain.doFilter(request, response); } else{ response.sendRedirect(ssoServiceUrl);//验证失败,重定向至sso server登录页 } } } } public void destroy() { }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

自定义shiro的realm

在spring-shiro.xml中添加:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

realm类:

public class MyRealm extends AuthorizingRealm{
public MyRealm() { setName("myRealm"); HashedCredentialsMatcher hcm = new HashedCredentialsMatcher(); //使用SHA-512 加密 hcm.setHashAlgorithmName(Sha512Hash.ALGORITHM_NAME); setCredentialsMatcher(hcm); } @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { SysUser user = SystemSession.getUser(); if (user != null) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); List
list = user.getRoles().get(0).getMenuList(); for (Menu menu : list){ if (StringUtils.isNotBlank(menu.getPermission())) { // 添加基于Permission的权限信息 for (String permission : StringUtils.split(menu.getPermission(),",")){ info.addStringPermission(permission); } } } // 添加用户权限 info.addStringPermission("user"); // 添加用户角色信息 for (SysRole role : user.getRoles()) { info.addRole(role.getEnglishName()); } return info; } else { return null; } } @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { //获取user信息 SysUser user = SystemSession.getUser(); if (user != null) { if (user.getIsEnable()!=1) { throw new AuthenticationException("msg:该帐号已禁止登录."); } return new SimpleAuthenticationInfo(new Principal(user), Constants.CREDENTIALS, getName()); } return null; } public static class Principal implements Serializable {
private static final long serialVersionUID = 1L; private String id; // 编号 private String loginName; // 登录名 private String name; // 姓名 private List
roleIdList; public List
getRoleIdList() { return roleIdList; } public void setRoleIdList(List
roleIdList) { this.roleIdList = roleIdList; } public Principal(SysUser user) { this.id = user.getId(); this.loginName = user.getUsername(); this.name = user.getCharacterName(); this.roleIdList=user.getRoleIdList(); } public String getId() { return id; } public String getLoginName() { return loginName; } public String getName() { return name; } @Override public String toString() { return id; } }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

由于shrio权限要做登录校验,但我们的登录已交给sso处理,这里只需要保证shiro的前后校验能通过就行,把password改成常量,并取消原来的加盐。CREDENTIALS=”6bf968f0c7b39ddbb7c8aa836b74d092060ed9b85b620a7fb088ecc48c6b3efd696bbd820f74c14f66c80c86c557c4bfda51b8a3743d3d568cc5c08410b7bb6a”;

修改index

@RequestMapping("index")public String index(ModelMap model, String mainFrame, HttpServletRequest request) {       SysUser currentUser = SSOTokenUtil.getToken(request);   List
menus = currentUser.getRoles().get(0).getMenuList(); List
sysMenus = new ArrayList<>(); for(Menu menu : menus){ if(currentUser.getRemarks().equals(menu.getSysCode())){ sysMenus.add(menu); } } //设置用户登录信息 UsernamePasswordToken token = new UsernamePasswordToken( currentUser.getUsername(), Constants.PASSWORD); SecurityUtils.getSubject().login(token); model.addAttribute("menus", sysMenus); model.addAttribute("currentUser", currentUser); return "index";}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

PASSWORD= “lvadmin”,是CREDENTIALS对应的明文。

文中所用到的一些SSOFilter,SystemSession,SSOTokenUtil等原码,以附件的形式提供下载。 

转载地址:http://zwuhj.baihongyu.com/

你可能感兴趣的文章
java中对象的类型转换
查看>>
java基础入门 String
查看>>
Java基础入门 StringBuffer类
查看>>
Java基础入门 currentTimeMillis方法
查看>>
Java基础入门 arraycopy方法
查看>>
Java基础入门 Math类
查看>>
Java基础入门 Random类
查看>>
Java基础入门 Date类
查看>>
Java基础入门 Calendar类
查看>>
Java基础入门 DateFormat类
查看>>
Java基础入门 Window类及Panel类
查看>>
Java基础入门 AWT事件处理
查看>>
Java基础入门 鼠标事件
查看>>
Java基础入门 键盘事件
查看>>
Java基础入门 GridLayout
查看>>
JavaEE Bean的两种常用作用域 singleton(单例)和prototype(原型)
查看>>
MySQL 数据库索引
查看>>
JavaEE Spring与MyBatis的整合之传统DAO方式整合(教材学习笔记)
查看>>
JavaEE MyBatis与Spring的整合——基于mapper接口方式开发(教材学习笔记)
查看>>
JavaWeb 使用Cookie实现——显示用户上次访问时间(教材学习笔记)
查看>>