【易学day07】shiro安全框架
SSM
Commons-fileupload
Poi:
搜索"导出excel java"
能够完成excel读写,jxl和poi
一般情况下,读至少3个网站或博客,对比那种实现方案更合适
jxl读写速度优于poi,但是,不能对office 2007以后的版本进行读写
只能选择poi
搜做poi java 找到poi的官方网站
1.下载jar包
2.寻找实现方案或代码,构建简单demo
3.跑通demo后再去寻找更复杂实现
4.去博客或专业网站csdn,iteye,cnblog,51cto…等
做excel的步骤:
导入jar包
手工:
maven:
<!-- 微软的office组件 excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.13</version>
</dependency>
根据需求写好导出到excel的工具类
通过response对象,把excel文件下载
@RequestMapping(value="/exportuser",method=RequestMethod.GET)
public void exportUser(HttpServletRequest request,
HttpServletResponse response){
Result result=null;
try {
byte[] data=this.userService.exportUser();
//下载data数组为excel文件
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;fileName=alluser.xls");
response.setContentLength(data.length);
OutputStream os=response.getOutputStream();
os.write(data);
os.flush();
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
shiro安全框架
类似的产品:spring secrety 学习成本高,过于复杂
shiro相对简单一些
spring mvc 拦截器 也可以做到安全管理
安全的目标:
访问web资源的时候,没有正常登陆,是不能访问项目的任何的敏感资源
shiro框架都能做什么:
主要的:
登陆认证:
通过shiro做登陆操作,如果没登陆成功,就跳转到登录页面
如果登录成功,就跳转指定主页,而且还可以访问其他任何资源
其实,只有通过shiro认证的登录,才可以正常访问项目资源
授权认证:
根据不同用户的权限,登录的时候显示不同主页菜单
shiro的全模块功能:
Primary:
Autentication:登录认证
Authorization:授权认证
Session Management :session 管理
Cryptographt:加密管理
Supporting:
web support:shiro支持web项目
caching:在shiro可以做部分数据缓存管理
testing /run as:shiro支持java项目
shoiro工作流程图:
appliction code:应用程序的代码,最终对应一个方法,此方法中启动shiro
subject(主题,科目)/user:shiro框架可以创建很多个subject,每个subject
可以看成一个用户在操作一个主题
shiro securityManager:shiro的安全管理器,是shiro的核心,可以管理所有
主题,所有安全认证,都是此安全管理器中认证
realm(领域,范围):shiro的领域是数据库中的数据tesdb t_user
简单介绍shiro的登录认证流程:
用户名和密码是用户在页面输入的,通过shiro的api启动shiro,把页面的
用户名的密码存储subject,再把subject传递给shiro securityManager,
shiro securityManager,负责调用realm(获取数据源的数据),把数据返回
给安全中心,
此时的安全中心有用户的subject 还有realm,安全中心负责对subject和
realm中的数据做对比,如果对比成功就跳转到指定页面,然后本项目其余
所有 的资源都可以访问
对于所有请求,都要经过shiro来判断是否是登录用户,过滤器只是负责拦截请求
所以在shiro的web项目中的web.xml中要添加过滤器
通过拦截进入shiro,在执行某个方法的时候,"得提前检测是否是登录用户"
shiro的底层用到了动态代理
//环绕通知
public Object around(ProceedJoinPoint pjp){
Object returnObj=null;
try{
//前置通知
if(登录过){
returnObj=pjp.proceed();
}else{
//跳转到指定的登录页面上,
//登录页面是从spring_shiro.xml中获取
}
//后置通知
}catch(Exception e){
//异常通知
}finally{
// 最终通知
}
}
shiro的使用步骤:
导入shiro的jar包
手工:
maven:
<!-- Apache Shiro 权限依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>
<!-- spring aop 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
shirio的配置文件:
web.xml:shiro的入口
spring_shiro.xml:shiro的所有的对象要给spring容器
<!--将Shiro的组件以bean的形式交给Spring管理 -->
<bean id="lifeCycleBeanProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
<!--Spring为shiro的bean创建代理对象
代理的方式:
1.jdk
2.cglib
-->
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifeCycleBeanProcessor">
<!--表示强制使用cglib为其创建代理对象 -->
<property name="proxyTargetClass" value="true"></property>
</bean>
<!--切面中需要的对象,也使用cglib来创建代理对象 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--Shiro的安全中心 其中需要提供真实的用户信息. 需要加载realm -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="AuthRealm"></property>
</bean>
<!--自定义Realm 为安全中心提供信息 -->
<bean id="AuthRealm" class="com.tarena.shiro.AuthRealm">
<property name="credentialsMatcher" ref="authCredential"></property>
</bean>
<!--自定义加密算法 -->
<bean id="authCredential" class="com.tarena.shiro.AuthCredential"/>
<!--授权,权限认证的适配器 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
<!-- shiro的过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--配置安全中心 -->
<property name="securityManager" ref="securityManager"></property>
<!--指定登陆的地址 当用户没有登陆时.默认跳转该页面-->
<property name="loginUrl" value="/login.html"></property>
<!--过滤器链 -->
<property name="filterChainDefinitions">
<value>
<!--添加过滤信息
1.anon 表示放行
2.authc 表示拦截-->
/user/login = anon
/css/** = anon
/font-awesome/** = anon
/fonts/** = anon
/head/** = anon
/images/** = anon
/js/** = anon
/page/** = anon
<!--/** 拦截所有的请求和静态资源文件 -->
/index.html* = authc
/index.jsp* = authc
/** = authc
</value>
</property>
</bean>
创建两个java类
处理登录认证和授权认证的类
public class AuthRealm extends AuthorizingRealm{
@Resource
private UserMapper userMapper;
//授权认证的回调方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//得到用户对象
Subject subject = SecurityUtils.getSubject();
String username = subject.getSession().getAttribute("username").toString();
//根据用户名查询模块信息 (获取模块名的集合)
List<String> moduleList = userMapper.findModuleByUserName(username);
//创建授权管理
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//传入授权管理的集合信息
info.addStringPermissions(moduleList);
return info;
}
@Override
//登陆认证模块的回调方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken loginToken = (UsernamePasswordToken) token;
String username = loginToken.getUsername();
//User user = userMapper.findUserByUserName(username);
/*
* principal:主要的; 本金的; 最重要的; 资本的; 真实的对象
* credentials:凭证,证件; 表示真实的密码
* realmName: 域,范围的名字 当前的realm
*/
//AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
return null;
}
}
加密算法类
public class AuthCredential extends SimpleCredentialsMatcher{
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
//通过token 获取用户名和密码
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
/*String username = userToken.getUsername();
String password = String.valueOf(userToken.getPassword());
String encryptPassword = Encrypt.getMd5(password, username);
userToken.setPassword(encryptPassword.toCharArray());*/
return super.doCredentialsMatch(userToken, info);
}
}
//这是用来执行加密的工具类
public class Encrypt {
public static String getMd5(String password,String username){
return new Md5Hash(password, username, 3).toString();
}
public static void main(String[] args) {
String password = new Md5Hash("admin", "admin", 3).toString();
System.out.println(password);
}
}
做完shiro登录后用shiro和不用shiro的区别:
不用shiro:
select user_id form t_user
where user_loginname=#{} and
user_password=#{}
用shiro:
select user_id id,
user_loginname loginName,
user_password password
from t_user
where user_loginname=#{}
不用shiro:
优点:访问数据库一次,能够完成登录业务
缺点:不能防护所有的敏感资源
用shiro:
优点:访问数据库一次,能够完成登录业务,可以防护敏感资源
缺点:性能堪忧,因为每访问任何一个资源,都要经过shiro的判断,
是否是登录用户
7008 wt_zss@126.com 角色管理,用户管理,课程管理,活动管理
A28 admin@tedu.cn 角色管理,用户管理,课程管理,视频管理,
活动管理,评论管理
根据不同的账号名,登录成功后,显示的模块多少不通

浙公网安备 33010602011771号