(注:初始登录账号:admin 密码:123456)
简介:本篇博客讲解了关于Shiro的四个部分
一:Shiro的基本介绍
二:Shiro的项目搭建
三:Shiro代码下载参考(项目+sql文件)
四:关于Shrio的问题分析
五:数据库表设计
一:Shiro的基本介绍
1:什么是Shiro、有什么用、什么时候使用?
shiro是一个安全框架,可以集成spring框架,
主要功能:认证、授权、加密、回话管理
一般在进行权限分配的项目中使用(总监、经理、员工...)
2:三大核心组件(缺一不可)
subject:用户
SecurityManager:安全管理
Realm:充当Shiro与安全数据间的桥梁(最少配置一个)
二:Shiro的项目搭建
项目流程介绍
web.xml中配置 ----> applicationContext-shiro.xml ----> 相应类
流程详解:
1:在web.xml中配置两处
1.1:过滤器代理(不配置则Shiro不生效)
<filter>
<!-- 此处的name 要和配置文件中 filter工厂的id一样 -->
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 让shiro过滤器的生命周期 交给web容器管理 -->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.2:在配置懒加载和监听器(已配置就不要重复配置)
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*.xml</param-value>
org.springframework.web.context.ContextLoaderListener
2:在pom.xml导入相应jar
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>
3:新建applicationContext-shiro.xml,并进行相关配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 以下5个bean分别对应功能 -->
<!-- 1. 安全管理器
2. Realm
3. 自定义的加密匹配器
4. 权限认证的观察器
5. Shiro过滤工厂 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="authRealm"></property>
</bean>
<bean id="authRealm" class="cn.tarena.ht.shiro.AuthRealm">
<property name="credentialsMatcher" ref="authCredentialMatcher"></property>
</bean>
<bean id="authCredentialMatcher" class="cn.tarena.ht.shiro.AuthCredentialMatcher"></bean>
<bean id="advisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
<property name="securityManager" ref="securityManager"></property>
<!-- 设置登录地址:当用户没有登录,访问非登录页面时指定的请求地址 此地址会自动放行 -->
<property name="loginUrl" value="/tologin.action"></property>
<property name="filterChainDefinitions">
<value>
<!-- anon:放行 authc拦截 -->
/login.action=anon
<!-- 放行所有的静态资源文件 -->
/staticfile/** = anon
<!-- /*代表拦截所有的请求 /**代表拦截所有请求和所有静态文件 -->
<!-- 要是只拦截项目的一部分在这里修改拦截路径即可 -->
/**=authc
</value>
</property>
</bean>
</beans>
4:根据上面配置的五个bean进行相应功能处理(后台部分)。
4.1:类AuthCredentialMatcher
package cn.tarena.ht.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.SimpleCredentialsMatcher;
import cn.tarena.ht.tool.Md5Utils;
//SimpleAuthorizationInfo
public class AuthCredentialMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
// TODO Auto-generated method stub
//把用户输入的密码 进行加密
UsernamePasswordToken loginToken = (UsernamePasswordToken) token;
//把用户输入的密码取出 char[] 转成 String
String password = String.valueOf(loginToken.getPassword());
password = Md5Utils.getMd5(password, loginToken.getUsername());
//修改令牌中的密码
loginToken.setPassword(password.toCharArray());
return super.doCredentialsMatch(token, info);
}
}
4.2:类AuthRealm
package cn.tarena.ht.shiro;
import java.util.List;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.tarena.ht.pojo.User;
import cn.tarena.ht.service.UserService;
@Component
public class AuthRealm extends SimpleAccountRealm{
@Autowired
private UserService userService;
//登录证明
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//得到用户名
UsernamePasswordToken loginToken = (UsernamePasswordToken) token;
//给Info准备数据
//得到正确的用户信息
User user = userService.findOneByUsername(loginToken.getUsername());
/**
* principal:代表正确的对象
* credentials:代表正确的密码
* realmName:原材料对象的名称
*/
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return info;
}
//权限认证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//准备当前登录用户的权限列表
// List<String> privileges = new ArrayList<>();
// privileges.add("货运管理");
// privileges.add("基础信息");
// privileges.add("系统管理");
//得到当前登录的用户信息
User user = (User) principals.getPrimaryPrincipal();
//根据用户Id管理查询出当前用户对应的模块--货运、基础、系统
List<String> privileges = userService.findModuleNamesBy(user.getUserId());
System.out.println("privileges="+privileges);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//将当前用户的权限存入当前Shiro框架中的Realm中的SimpleAuthorizationInfo中
info.addStringPermissions(privileges);
return info;
}
}
4.3:类Md5Utils
package cn.tarena.ht.tool;
import org.apache.shiro.crypto.hash.Md5Hash;
public class Md5Utils {
public static String getMd5(String password,String salt) {
//source 加密源
//salt 盐(这里是将用户名作为盐处理)
//hashIterations 和稀泥的次数
Md5Hash mh = new Md5Hash(password, salt, 2);
return mh.toString();
}
}
4.4:Login
@RequestMapping("login")
public String login(String username,String password,Model model,HttpSession session){
//代表当前用户
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
//得到登录成功的user
User user = (User) subject.getPrincipal();
session.setAttribute("_CURRENT_USER", user);
return "redirect:/home";
} catch (AuthenticationException e) {
e.printStackTrace();
model.addAttribute("errorInfo","用户名或密码不正确!");
return "/sysadmin/login/login";
}
}
5:前台部分
1:在根标签中导入shiro标签
<%@ taglib uri=“http://shiro.apache.org/tags” prefix=“shiro” %>
2:根据当前模块(权限)是否存在进行判断
<shiro:hasPermission name="部门管理">
<li><a href="${ctx}/sysadmin/dept/list" onclick="linkHighlighted(this)" target="main" id="aa_1">部门管理</a></li>
</shiro:hasPermission>
<shiro:hasPermission name="用户管理">
<li><a href="${ctx}/sysadmin/user/list" onclick="linkHighlighted(this)" target="main" id="aa_1">用户管理</a></li></shiro:hasPermission>
3:前台根据拿到的模块进行排版
6:数据库设计思想
一个模板对应一个功能
一个权限对应多个模板
一个用户对应多项权限
用户登录---通过---三表关联查询所有权限模板,封装成List发送至前台,
前台接受,进行相应判断,进行排版显示
三:Shiro项目代码下载参考(项目+sql文件)
项目框架:SSM+Shiro
四:关于Shrio的开发问题分析
1:登录
最开始的想法是用ajax登录,研究了一些资料发现在shiro中,路径全部拦截了
个人在spring-shiro.xml中配置的拦截路径
/SpringMVC/Admin/**=authc
之前尝试多种方法都被拦截,最后个人匹配的路径是
@RequestMapping("admin_login1")
在带入登录名,密码,问题解决
public String login(String Username,String Password,Model model,HttpSession session){}
2:在AuthRealm中doGetAuthorizationInfo没有执行
2.1:个人首先在网上查找资料,大多数都是说是要在
springmvc.xml中和pom中配置文件 --->结果报错
2.2:知道想到一个问题程序在什么时候执行doGetAuthorizationInfo
doGetAuthorizationInfo执行时机有三个,如下:
2.2.1、subject.hasRole(“admin”) 或 subject.isPermitted(“admin”):
自己去调用这个是否有什么角色或者是否有什么权限的时候;
2.2.2、@RequiresRoles("admin") :在方法上加注解的时候;
2.2.3、[@shiro.hasPermission name = "admin"][/@shiro.hasPermission]:
在页面上加shiro标签的时候,即进这个页面的时候扫描到有这个标签的时候。
五:数据库表设计:
经典5张表结构:
1.sys_users用户表
2.sys_roles角色表
3.sys_permissions权限表(或资源表)
4.sys_users_roles用户-角色关联表
5.sys_roles_permissions角色-权限关联表
如果业务中权限很多很复杂,发现经典结构不再适用,那就考虑以下结构
1.sys_users用户表
2.sys_roles角色表
3.sys_permissions权限表(或资源表)
4.sys_users_roles用户-角色关联表
5.sys_roles_permissions用户-权限关联表
7677



被折叠的 条评论
为什么被折叠?



