本帖最后由 大蓝鲸Java 于 2017-12-27 16:39 编辑
一、Shiro介绍
1、Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。
2、使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
二、Shiro体系结构
1、 Authentication 认证 ---- 用户登录,身份识别
2、 Authorization 授权 --- 用户具有哪些权限、角色
3、 Cryptography 安全数据加密
4、 Session Management 会话管理
5、 Web Integration web 系统集成
6、 Integrations 集成其它应用, spring、缓存框架
三、Shiro主要运行流程
应用程序 --- Subject --- SecurityManager --- Realm --- 安全数据(数据库)
Subject介绍:
1、Subject 是与程序进行交互的对象,可以是人也可以是服务或者其他,通常就理解为用户。
2、所有 Subject 实例都被绑定到(且这是必须的)一个 SecurityManager 上。当你与一个Subject 交互时,那些交互作用转化为与 SecurityManager 交互的特定 subject 的交互作用。
SecurityManager介绍:
1、SecurityManager 是 Shiro的核心,初始化时协调各个模块运行。然而,一旦 SecurityManager协调完毕,SecurityManager 会被单独留下,且我们只需要去操作Subject即可,无需操作SecurityManager 。
2、当我们正与一个 Subject 进行交互时,实质上是 SecurityManager在处理 Subject 安全操作。
Realm介绍:
1、Realms 担当 Shiro 和你的应用程序的安全数据之间的“桥梁”或“连接器”。当它实际上与安全相
关的数据如用来执行身份验证(登录)及授权(访问控制)的用户帐户交互时, Shiro 从一个或多个为应用程序配置的 Realm 中寻找许多这样的东西。
2、在这个意义上说, Realm 本质上是一个特定安全的 DAO:它封装了数据源的连接详细信息,使 Shiro 所需的相关的数据可用。当配置 Shiro 时,你必须指定至少一个 Realm 用来进行身份验证和/或授权。 SecurityManager可能配置多个 Realms,但至少有一个是必须的。
四、Shiro的使用
1、 配置 web.xml,增加shiro的Filter
[Java] 纯文本查看 复制代码 <!-- shiro的Filter -->
<filter>
<!-- 去spring配置文件中寻找同名bean -->
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、在spring配置文件中,增加shiro的相关配置
[Java] 纯文本查看 复制代码 <!-- 配置Shiro核心Filter -->
<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 安全管理器 -->
<property name="securityManager" ref="securityManager" />
<!-- 未认证,跳转到哪个页面 -->
<property name="loginUrl" value="/login.html" />
<!-- 登录页面页面 -->
<property name="successUrl" value="/index.html" />
<!-- 认证后,没有权限跳转页面 -->
<property name="unauthorizedUrl" value="/unauthorized.html" />
<!-- shiro URL控制过滤器规则 -->
<property name="filterChainDefinitions">
<value>
/login.html* = anon
/user_login.action* = anon
/validatecode.jsp* = anon
/css/** = anon
/js/** = anon
/images/** = anon
/services/** = anon
<!-- 访问courier.html页面需要有courier:list-->
/pages/base/courier.html* = perms[courier:list]
/pages/base/area.html* = roles[base]
/** = authc
</value>
</property>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="bosRealm" /><!-- 安全管理器调用realm-->
</bean>
3、编写realm
[Java] 纯文本查看 复制代码 public class BosRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
private PermissionService permissionService;
@Override
// 授权...
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
System.out.println("shiro 授权管理...");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 根据当前登录用户 查询对应角色和权限
Subject subject = SecurityUtils.getSubject();
User user = (User) subject.getPrincipal();
// 调用业务层,查询角色
List<Role> roles = roleService.findByUser(user);
for (Role role : roles) {
authorizationInfo.addRole(role.getKeyword());
}
// 调用业务层,查询权限
List<Permission> permissions = permissionService.findByUser(user);
for (Permission permission : permissions) {
authorizationInfo.addStringPermission(permission.getKeyword());
}
return authorizationInfo;
}
@Override
// 认证...
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("shiro 认证管理... ");
// 转换token
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
// 根据用户名 查询 用户信息
User user = userService.findByUsername(usernamePasswordToken
.getUsername());
if (user == null) {
// 用户名不存在
// 参数一: 期望登录后,保存在Subject中信息
// 参数二: 如果返回为null 说明用户不存在,报用户名
// 参数三 :realm名称
return null;
} else {
// 用户名存在
// 当返回用户密码时,securityManager安全管理器,自动比较返回密码和用户输入密码是否一致
// 如果密码一致 登录成功, 如果密码不一致 报密码错误异常
return new SimpleAuthenticationInfo(user, user.getPassword(),
getName());
}
}
}
五、权限控制表结构
|