shiro使用教程
一、shiro是什么
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。不仅可以在Web项目中使用,在普通的项目中也是可以使用的
二、shiro可以做什么
shiro可以进行细粒度地权限控制,包括对方法,对链接,对页面显示进行权限控制。
三、在Web项目中使用shiro进行权限管理
1、 在web.xml中添加shiro的拦截器
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
2、 spring-mvc.xml中添加shiro的权限注解支持
<aop:config proxy-target-class="true"></aop:config>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
3、 使用spring对ehcache进行缓存管理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"
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.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 支持缓存注解 -->
<cache:annotation-driven cache-manager="ehcacheManager" /> <!--ehcache-->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean> <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactory"/>
</bean>
</beans>
4、 使用ehcache进行缓存管理
在ehcache中添加如下缓存块
<diskStore path="java.io.tmpdir"/>
<cache name="authorizationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache> <cache name="authenticationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache> <cache name="shiro-activeSessionCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
5、实现CacheManager的接口,对shiro权限使用spring进行缓存管理
public class SpringCacheManagerWrapper implements CacheManager {
private org.springframework.cache.CacheManager cacheManager;
/**
* 设置spring cache manager
*
* @param cacheManager
*/
public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
org.springframework.cache.Cache springCache = cacheManager.getCache(name);
return new SpringCacheWrapper(springCache);
}
static class SpringCacheWrapper implements Cache {
private org.springframework.cache.Cache springCache;
SpringCacheWrapper(org.springframework.cache.Cache springCache) {
this.springCache = springCache;
}
@Override
public Object get(Object key) throws CacheException {
Object value = springCache.get(key);
if (value instanceof SimpleValueWrapper) {
return ((SimpleValueWrapper) value).get();
}
return value;
}
@Override
public Object put(Object key, Object value) throws CacheException {
springCache.put(key, value);
return value;
}
@Override
public Object remove(Object key) throws CacheException {
springCache.evict(key);
return null;
}
@Override
public void clear() throws CacheException {
springCache.clear();
}
@Override
public int size() {
if(springCache.getNativeCache() instanceof Ehcache) {
Ehcache ehcache = (Ehcache) springCache.getNativeCache();
return ehcache.getSize();
}
throw new UnsupportedOperationException("invoke spring cache abstract size method not supported");
}
@Override
public Set keys() {
if(springCache.getNativeCache() instanceof Ehcache) {
Ehcache ehcache = (Ehcache) springCache.getNativeCache();
return new HashSet(ehcache.getKeys());
}
throw new UnsupportedOperationException("invoke spring cache abstract keys method not supported");
}
@Override
public Collection values() {
if(springCache.getNativeCache() instanceof Ehcache) {
Ehcache ehcache = (Ehcache) springCache.getNativeCache();
List keys = ehcache.getKeys();
if (!CollectionUtils.isEmpty(keys)) {
List values = new ArrayList(keys.size());
for (Object key : keys) {
Object value = get(key);
if (value != null) {
values.add(value);
}
}
return Collections.unmodifiableList(values);
} else {
return Collections.emptyList();
}
}
throw new UnsupportedOperationException("invoke spring cache abstract values method not supported");
}
}
}
6、自定义放在session中的实体
public class CustomPrincipal implements Serializable {
private Integer id;
private String username;
public CustomPrincipal(String username) {
this.username = username;
}
public CustomPrincipal(int id, String username) {
this.id = id;
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
/**
* 本函数输出将作为默认的<shiro:principal/>输出.
*/
@Override
public String toString() {
return username;
}
}
7、重写realm
public class AdministratorRealm extends AuthorizingRealm {
private AdministratorService administratorService;
public AdministratorService getAdministratorService() {
return administratorService;
}
public void setAdministratorService(AdministratorService administratorService) {
this.administratorService = administratorService;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
CustomPrincipal customPrincipal = (CustomPrincipal)principals.getPrimaryPrincipal();
String username = customPrincipal.getUsername();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
Set<String> roles = administratorService.getRoles(username);
roles.add(UserConstants.ADMINISTRATOR_STR);
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(administratorService.getPermissions(username));
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = (String)usernamePasswordToken.getPrincipal();
Administrator administrator = administratorService.getAdministrator(username);
if (administrator == null) {
throw new UnknownAccountException();//没找到帐号
}
if (Boolean.FALSE.equals(administrator.getAdmiStatus())) {
throw new LockedAccountException(); //帐号锁定
}
CustomPrincipal principal = new CustomPrincipal(administrator.getAdmiId(), administrator.getAdmiAccount());
//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
principal, //用户名
administrator.getAdmiPassword(), //密码
ByteSource.Util.bytes(administrator.getCredentialsSalt()),//salt=username+salt
getName() //realm name
);
return authenticationInfo;
}
@Override
public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}
@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
super.clearCachedAuthenticationInfo(principals);
}
@Override
public void clearCache(PrincipalCollection principals) {
super.clearCache(principals);
}
public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}
public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}
public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}
}
8、spring-shiro.xml实例化类
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <aop:config proxy-target-class="true"></aop:config> <!-- 缓存管理器 -->
<bean id="cacheManager" class="com.misuosi.mshop.shiro.cache.SpringCacheManagerWrapper">
<property name="cacheManager" ref="ehcacheManager"/>
</bean> <!-- 凭证匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="2"/>
<property name="storedCredentialsHexEncoded" value="true"/>
</bean> <!-- Realm实现 -->
<bean id="administratorRealm" class="com.misuosi.mshop.shiro.realm.AdministratorRealm">
<property name="administratorService" ref="administratorService"/>
<property name="credentialsMatcher" ref="credentialsMatcher"/>
<property name="cachingEnabled" value="false"/>
<property name="authenticationCachingEnabled" value="true"/>
<property name="authenticationCacheName" value="authenticationCache"/>
<property name="authorizationCachingEnabled" value="true"/>
<property name="authorizationCacheName" value="authorizationCache"/>
</bean> <!-- 会话ID生成器 -->
<bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/> <!-- 会话Cookie模板 -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="-1"/>
</bean> <!-- 会话DAO -->
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
<property name="sessionIdGenerator" ref="sessionIdGenerator"/>
</bean> <!-- 会话验证调度器 -->
<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
<property name="sessionValidationInterval" value="1800000"/>
<property name="sessionManager" ref="sessionManager"/>
</bean> <!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="1800000"/>
<property name="deleteInvalidSessions" value="true"/>
<property name="sessionValidationSchedulerEnabled" value="true"/>
<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
<property name="sessionDAO" ref="sessionDAO"/>
<property name="sessionIdCookieEnabled" value="true"/>
<property name="sessionIdCookie" ref="sessionIdCookie"/>
</bean> <!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="administratorRealm"/>
<property name="sessionManager" ref="sessionManager"/>
<property name="cacheManager" ref="cacheManager"/>
</bean> <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
<property name="arguments" ref="securityManager"/>
</bean> <!-- 基于Form表单的身份验证过滤器 -->
<bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
<property name="successUrl" value="/admin/index"/>
<property name="loginUrl" value="/admin/login"/>
</bean> <bean id="adminLogoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<property name="redirectUrl" value="/admin/login"/>
</bean> <!-- Shiro的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="filters">
<util:map>
<entry key="adminAuthc" value-ref="formAuthenticationFilter"/>
<entry key="adminLogout" value-ref="adminLogoutFilter"/>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
/admin/login = adminAuthc
/admin/logout = adminLogout
/admin/** = adminAuthc,roles[admin]
</value>
</property>
</bean> <!-- Shiro生命周期处理器-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>
9、freemarker使用shiro的标签
把标签的实现贴到freemarker.tag的包中,在freemarker的配置中添加freemarker标签。
public class ShiroTagFreeMarkerConfigurer extends FreeMarkerConfigurer {
@Override
public void afterPropertiesSet() throws IOException, TemplateException {
super.afterPropertiesSet();
this.getConfiguration().setSharedVariable("shiro", new ShiroTags());
}
}
10、完成
shiro使用教程的更多相关文章
- Shiro 基础教程
原文地址:Shiro 基础教程 博客地址:http://www.extlight.com 一.前言 Apache Shiro 是 Java 的一个安全框架.功能强大,使用简单的Java安全框架,它为开 ...
- Shiro实战教程-刘志敏-专题视频课程
Shiro实战教程-62人已学习 课程介绍 本教程只介绍基本的 Shiro 使用,不会过多分析源码等,重在使用. 适用人群: 1.了解基于Servlet进行Web应用开发 2.了解Spr ...
- Apache Shiro系列教程之三:Shiro的结构
Shiro的设计目标是简化应用的安全管理工作.软件通常是以用户为基础设计的.也就是说,我们经常是根据用户是怎样和我们的软件交互的来设计相关的用户接口.比如,你可能会说"如果是已经登录的用户与 ...
- springboot+shiro整合教程
进阶教程: 1. springboot+shiro+redis(单机redis版)整合教程 2. springboot+shiro+redis(集群redis版)整合教程 3.springboot+s ...
- Apache Shiro 快速入门教程,shiro 基础教程 (这篇文章非常好)
第一部分 什么是Apache Shiro 1.什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 ...
- shiro入门教程
一.shiro入门 shiro.ini和log4j.properties要放在src下面,lib是和src同级别的,然后lib下面的jar包是必须的,lib下面的jar包需要add path,如果报错 ...
- Apache Shiro 快速入门教程,shiro 基础教程
第一部分 什么是Apache Shiro 1.什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 ...
- Shiro实战教程(一)
Shiro完整架构图 Shiro认证过程 Shiro授权的内部处理机制 Shiro 支持三种方式的授权 1.编程式:通过写if/else 授权代码块完成: Subject subject = Secu ...
- Spring Boot Shiro 使用教程
Apache Shiro 已经大名鼎鼎,搞 Java 的没有不知道的,这类似于 .Net 中的身份验证 form 认证.跟 .net core 中的认证授权策略基本是一样的.当然都不知道也没有关系,因 ...
随机推荐
- web前端面试题及答案
1.常用那几种浏览器测试?有哪些内核(Layout Engine)? 答: (Q1) 浏览器:IE,Chrome,FireFox,Safari,Opera. (Q2) 内核:Trident,Ge ...
- AngularJS自定义指令之可选参数replace
replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false.默认值意味着模板会被当作子元素插入到调用此指令的元素内部: 如: <my-directive>& ...
- Thrift入门初探--thrift安装及java入门实例
什么是thrift? 简单来说,是Facebook公布的一款开源跨语言的RPC框架. 那么问题来了. 什么是RPC框架? RPC全称为Remote Procedure Call,意为远程过程调用. 假 ...
- 缓冲流自动把getchar()填充
#include"stdio.h" #include"conio.h" #include<stdlib.h> int main() { char c ...
- 简述.jpg .Gif .png-8 .png-24的区别
最近有很多朋友在开发过程中有时候会遇到图片加载不清晰,透明度失真,或者对图片进行操作之后造成图片损耗的现象,在这里给大家简单介绍一下常用的几种图片格式之间的区别 Gif格式特点: 1.透明性,Gif是 ...
- vuejs数据双向绑定原理(get & set)
前端的数据双向绑定指的是view(视图)和model(数据)两者之间的关系:view层是页面上展示给用户看的信息,model层一般是指通过http请求从后台返回的数据.view到model的绑定都是通 ...
- apicloud上传图片
//定义api $("#photo").change(function(){ //获取图片 api.getPicture({ sourceType: 'library', enco ...
- 关于Edittext默认弹出软键盘为数字键
如果说我们只是输入数字的话,我们可以直接在xml文件中: android:inputType="number" 如果是身份证类型的话,我们可以这样: android:inputTy ...
- 【解题报告】VijosP1351 棋盘制作
思路: 1. 矩形:用f[i][j][1]表示右下角为(I,j),最大的,符合条件的矩形的长,用f[i][j][2]表示右下角为(I,j),最大的,符合条件的矩形的高,预设f内所有元素为1 If(a[ ...
- java-信息安全(二)-对称加密算法DES,3DES,AES,Blowfish,RC2,RC4
概述 信息安全基本概念: DES(Data Encryption Standard,数据加密标准) 3DES(Triple DES,三重数据加密算法(TDEA,Triple Data Encrypti ...