360SDN.COM

首页/Java/列表

基于Shiro的统一用户中心

来源:本木技术团队  2017-09-11 12:22:51    评论:0点击:

1
背景

随着公司业务高速发展,出现了许多新的业务系统,每个新的业务系统都需要重新开发一套账户和权限模块,不仅浪费开发资源,给用户造成多套账户密码的困扰,还无法关联各应用业务数据,难以在多个业务系统之间建立用户画像。

业务发展到一定规模的时候,一个提供单点登录和账户权限管理的中间系统必不可少,所以,公司统一用户中心uniuser应运而生,并提供基于Shiro的uniuser-client接入方案。

对于不同的业务系统,通常来说有不同的用户权限需求,uniuser对Shiro做了一层封装,采用装饰者模式将uniuser-client的上下文和shiro的上下文关联起来,为业务系统提供默认的RBAC权限管理策略,并且基于Shiro框架扩展接口,业务系统可以对权限验证、Session存储、缓存作自定义实现。

Apache Shiro* is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications .

2
简介

uniuser中间系统独立部署,存储账户和用户信息,管理session(登录会话)和ticket(登录凭证),对外提供单点登录服务。提供http、dubbo接口,提供基于Shiro的uniuser-client接入框架。

实现目标

* 统一各个业务系统的账户

* 对外提供身份验证服务,包括单点登录,session&ticket管理,账户操作接口
* 为应用系统提供默认的权限验证服务
* 提供uniuser-client接入框架,底层采用dubbo通信,封装dubbo配置细节,并对shiro作代理。
* 提供扩展接口,支持业务系统自定义实现,包括权限验证、Session管理,缓存管理等。

3
实现

uniuser-client采用装饰者模式的思想对Shiro进行了封装,隐藏了复杂的session(登录会话)、ticket(登录凭证)、身份验证、权限验证等实现,提供默认的登录策略及权限策略,因为是对Shiro的封装,所以在使用方式上和Shiro一样简单方便,并且风格类似,但是uniuser在其基础上增加了一些更适用于本木的接口和特性,方便应用系统接入,并提供扩展策略。

下面是一个web系统接入uniuser的demo,包含了从应用上下文中获取当前用户,如果当前用户未初始化,则新建一个用户并和应用上下文关联,判断当前用户是否登录,发起账户密码登录之后可以获取到用户UID和登录ticket,登录后的用户自动关联上角色和权限属性,复杂的底层完全封装,应用只用关心业务,简单易用的接入方式涵盖了80%的业务场景。

用户上下文UNIContext

uniuser的入口是从应用上下文中获取当前用户,即UNIContext#getUser(),Shiro中用户的定义为Subject.class,取当前用户的意思,Subject包含了Shiro的api和用户属性   

uniuser中用户定义为UNIUser.class,装饰了Subject,增加了UID和ticket属性,并支持一些Shiro没有实现的业务接口。

UNIUser的继承关系为
* Subject:shiro中用户接口,暴露shiro对外的api
* UUser:业务属性扩展接口,对用户增加了UID和ticket属性
* UNISubjectDelegate:装饰者模式类,装饰了Subject,对shiro接口做了二次封装
* UNIFunction:扩展业务接口,如生成验证码,账户注册等
* UNIUserFunction:扩展业务接口的具体实现,调用底层的Dubbo或者Http接口
* UNIUser:实际的用户bean

从上下文中获取用户
1. 从ThreadContext中取,这里的ThreadContext本质上是ThreadLocal,在UNIListenner#requestDestroyed中释放
2. 从当前http请求中拿到ticket,分别从header、cookie、param中取,业务系统前端可以把ticket存在其中一个地方。然后用ticket到缓存或uniuser-server换取登录用户session
3. 如果当前没有登录用户,则创建一个未登录的用户,并关联shiro上下文。
4. 将当前用户绑定到ThreadCon
text

用ticket换取user流程为

前端将用户登陆后的ticket带到http请求中,可以是header、cookie或者参数中,uniuser-client会先去缓存中找到ticket对应的用户,这里的缓存可以自定义具体的缓存实现,可以是redis或者memcache等,如果缓存中没有,则会通过AccountRPC这个Dubbo接口,到uniuser-server端验证ticket的有效性,并且返回当前登录用户。

身份验证Authentication

身份验证是登录的过程——即证明一个用户实际上是不是他们所说的他们是谁。对于一个用户证明自己的身份来说,他们需要提供一些身份识别信息,以及某些你的系统能够理解和信任的身份证明。

一个简单的登录demo如下,使用user.uLogin登录,分别支持账户密码登录,验证码登录,微信授权登录。

登录之后会在UNIUser中回写uid和ticket,user.isAuthenticated()可以获得当前用户的登录状态。

底层调用dubbo接口和uniuser-server交互

dubbo接口的注册在UNIContext的初始化方法afterPropertiesSet()中执行,对于不同的环境,从配置中心获取到不同的配置,然后注册dubbo consumer

实际的登录验证行为发生在dubbo接口的provider端,也就是uniuser-server,在server提供了三种登录方式的验证,为当前登录session生成ticket,返回给业务系统,业务系统前端将ticket缓存下来,这里不作详细阐述。

权限验证

权限验证,又称作为访问控制,是对资源的访问管理的过程。换句话说,控制谁有权限在应用程序中做什么。

授权检查的例子是:该用户是否被允许访问这个网页,编辑此数据,查看此按钮,或打印到这台打印机?这些都是决定哪些是用户能够访问的。

在web系统中,权限通常指的http接口路径,如/user/login,uniuser提供了默认的rbac权限验证策略。

1. Suject:以当前用户为入口,验证用户是否拥有相应的角色或者是否有访问目标url的权限
2. Security Managershiro安全管理框架,整合了身份验证,权限验证,session,cache等模块
3.Authorizer:SecurityManager会调用它内部的

org.apache.shiro.authz.Authorizer,由authorizer调用实际的hasRole*, checkRole*, isPermitted*, 或者checkPermissions*方法。默认情况下,authorizer 实例是一个ModularRealmAuthorizer 实例,它支持协调任何授权操作过程中的一个或多个Realm 实例
4. Realm:为权限校验提供配置数据源和验证策略的配置,uniuser-client默认实现了DefaultRbacRealm

首先在权限拦截器中触发了权限校验

user.isPermitted()经过shiro框架内部的处理,最终由Realm实现中的doGetAuthorizationInfo()方法返回用户拥有的权限,Permission.implies对用户拥有的权限作校验

uniuser-client提供了默认的UrlPermission和DefaultRbacRealm,应用如果要自定义权限策略,可以自己实现realm,然后传给UNIContext

DefaultRbacRealm主要实现了isPermitted和doGetAuthorizationInfo方法

doGetAuthorizationInfo()方法根据当前登录的用户UID,去数据表里查询为用户配置的角色,再通过角色查询配置的权限,这里的数据表由user-client默认定义好,并提供配置用户权限的界面。业务系统只需要配置用户权限即可。

4
结语

uniuser为公司提供了统一账户和权限管理的服务,提供基于shiro的uniuser-client接入api,本文主要对uniuser-client如何实现shiro封装和扩展作了大致介绍,且目前还只是第一个版本,在设计和实现上还有很多需要优化的地方。但是从设计上来说,uniuser结合了开源框架Shiro,为业务系统自定义实现策略提供了非常灵活的扩展接口,也为uniuser以后的优化和高级功能作了良好的铺垫。

阅读原文

为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权