1.导入jar
shiro-core-1.2.3
shiro-cache-1.2.3
shiro-spring-1.2.3
shiro-web-1.2.3
shiro-all-1.2.3
https://www.cnblogs.com/afeng7882999/p/4320034.html
2.配置文件
springnvc
<!-- 开启aop,支持shiro的注解 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 支持shiro的注解 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
applicationcontext-shiro
<!-- shiro的过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 如果没有认证将要跳转的登陆地址,http可访问的url,如果不在表单认证过虑器FormAuthenticationFilter中指定此地址就为身份认证地址 -->
<property name="loginUrl" value="/login.action" />
<!-- 没有权限跳转的地址 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 认证成功之后执行的url,shiro默认的处理方式是去执行用户登陆之前请求的地址
<property name="successUrl" value="/first.action"></property>
-->
<!-- 配置自定义的认证过滤器 -->
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter"></entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
<!-- 把样式,图片,js设置为可匿名访问 -->
/images/**=anon
/js/**=anon
/styles/**=anon
/validatecode.jsp=anon
<!-- 退出功能 logout过滤器会清空session-->
/logout.action=logout
<!-- 权限控制
/items/queryItem.action=perms[item:list]
-->
<!-- 配置需要认证的资源 -->
/**=authc
<!-- 匿名访问的资源
/**=anon
-->
</value>
</property>
</bean>
<!-- 创建SecurityManager对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customeRealm"></property>
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"></property>
<!-- 注入会话管理器 -->
<property name="sessionManager" ref="sessionManager"></property>
</bean>
<!--创建Realm对象 -->
<bean id="customeRealm" class="cn.qf.ssm.realm.MyRealm">
<!-- 注入凭证匹配器 -->
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 配置凭证匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"></property>
<property name="hashIterations" value="1"></property>
</bean>
<!-- 创建缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"></property>
</bean>
<!-- shiro的session管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效时间 -->
<property name="globalSessionTimeout" value="600000"></property>
<!-- 删除无效的session -->
<property name="deleteInvalidSessions" value="true"></property>
</bean>
<!-- 创建自定义的认证过滤器对象 -->
<bean id="formAuthenticationFilter" class="cn.qf.ssm.realm.MyFormAuthenticationFilter">
<property name="usernameParam" value="username"></property>
<property name="passwordParam" value="password"></property>
</bean>
3.业务流程
框架解释:
subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
securityManager:安全管理器,主体进行认证和授权都 是通过securityManager进行。
它包含下面的认证器和授权器。
authenticator:认证器,主体进行认证最终通过authenticator进行的。
authorizer:授权器,主体进行授权最终通过authorizer进行的。
sessionManager:web应用中一般是用web容器对session进行管理,
shiro也提供一套session管理的方式。可以实现单点登录。
SessionDao:通过SessionDao管理session数据,针对个性化的session数据存储
需要使用sessionDao。
cache Manager:缓存管理器,主要对session和授权数据进行缓存,
比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓
存数据进行管理。
realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据。
它的主要目的是与数据库打交道,查询数据库中的认证的信息
(比如用户名和密码),查询授权的信息(比如权限的code等,
所以这里可以理解为调用数据库查询一系列的信息,一般情况下在项
目中采用自定义的realm,因为不同的业务需求不一样))
cryptography:密码管理,提供了一套加密/解密的组件,方便开发。
比如提供常用的散列、加/解密等功能。
内置过滤器:
shiro内置了许多过滤器用来控制认证授权
anon : org.apache.shiro.web.filter.authc.AnonymousFilter
authc : org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic : org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms : org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port : org.apache.shiro.web.filter.authz.PortFilter
rest : org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles : org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl : org.apache.shiro.web.filter.authz.SslFilter
user : org.apache.shiro.web.filter.authc.UserFilter
shiro的授权方式有三种:
(1)—— 编程式:通过写if/else 授权代码块完成:(这种比较少用,一般在项目中采用后两种)
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}
(2)—— 注解式:通过在执行的Java方法上放置相应的注解完成:
@RequiresRoles("admin")
public void hello() {
//有权限
}
(3)—— JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
在jsp页面导入shiro的标签既可以使用shiro的标签来进行权限的判断:
Jsp页面添加:
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
业务逻辑
i.单点登录
1、subject(主体)请求认证,调用subject.login(token)
2、SecurityManager (安全管理器)执行认证
3、SecurityManager通过ModularRealmAuthenticator进行认证。
4、ModularRealmAuthenticator将token传给realm,realm根据token中用户 信息从数据库查询用户信息(包括身份和凭证)
5、realm如果查询不到用户给ModularRealmAuthenticator返回null, ModularRealmAuthenticator抛出异常(用户不存在)
6、realm如果查询到用户给ModularRealmAuthenticator返回 AuthenticationInfo(认证信息)
7、ModularRealmAuthenticator拿着AuthenticationInfo(认证信息)去进行凭证 (密码 )比对。如果一致则认证通过,如果不致抛出异常(凭证错误)。
授权
1、对subject进行授权,调用方法isPermitted("permission串")
2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库 查询权限数据调用realm的授权方法:doGetAuthorizationInfo
4、realm从数据库查询权限数据,返回ModularRealmAuthorizer
5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中, 说明用户访问permission串有权限,否则 没有权限,抛出异常。
使用FormAuthenticationFilter过虑器实现 ,原理如下:
将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl
FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的)
FormAuthenticationFilter调用realm传入一个token(username和password)
realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。
如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息)
3.代码
shiro-core-1.2.3
shiro-cache-1.2.3
shiro-spring-1.2.3
shiro-web-1.2.3
shiro-all-1.2.3
https://www.cnblogs.com/afeng7882999/p/4320034.html
2.配置文件
springnvc
<!-- 开启aop,支持shiro的注解 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 支持shiro的注解 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
applicationcontext-shiro
<!-- shiro的过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 如果没有认证将要跳转的登陆地址,http可访问的url,如果不在表单认证过虑器FormAuthenticationFilter中指定此地址就为身份认证地址 -->
<property name="loginUrl" value="/login.action" />
<!-- 没有权限跳转的地址 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 认证成功之后执行的url,shiro默认的处理方式是去执行用户登陆之前请求的地址
<property name="successUrl" value="/first.action"></property>
-->
<!-- 配置自定义的认证过滤器 -->
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter"></entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
<!-- 把样式,图片,js设置为可匿名访问 -->
/images/**=anon
/js/**=anon
/styles/**=anon
/validatecode.jsp=anon
<!-- 退出功能 logout过滤器会清空session-->
/logout.action=logout
<!-- 权限控制
/items/queryItem.action=perms[item:list]
-->
<!-- 配置需要认证的资源 -->
/**=authc
<!-- 匿名访问的资源
/**=anon
-->
</value>
</property>
</bean>
<!-- 创建SecurityManager对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customeRealm"></property>
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"></property>
<!-- 注入会话管理器 -->
<property name="sessionManager" ref="sessionManager"></property>
</bean>
<!--创建Realm对象 -->
<bean id="customeRealm" class="cn.qf.ssm.realm.MyRealm">
<!-- 注入凭证匹配器 -->
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 配置凭证匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"></property>
<property name="hashIterations" value="1"></property>
</bean>
<!-- 创建缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"></property>
</bean>
<!-- shiro的session管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效时间 -->
<property name="globalSessionTimeout" value="600000"></property>
<!-- 删除无效的session -->
<property name="deleteInvalidSessions" value="true"></property>
</bean>
<!-- 创建自定义的认证过滤器对象 -->
<bean id="formAuthenticationFilter" class="cn.qf.ssm.realm.MyFormAuthenticationFilter">
<property name="usernameParam" value="username"></property>
<property name="passwordParam" value="password"></property>
</bean>
3.业务流程
框架解释:
subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
securityManager:安全管理器,主体进行认证和授权都 是通过securityManager进行。
它包含下面的认证器和授权器。
authenticator:认证器,主体进行认证最终通过authenticator进行的。
authorizer:授权器,主体进行授权最终通过authorizer进行的。
sessionManager:web应用中一般是用web容器对session进行管理,
shiro也提供一套session管理的方式。可以实现单点登录。
SessionDao:通过SessionDao管理session数据,针对个性化的session数据存储
需要使用sessionDao。
cache Manager:缓存管理器,主要对session和授权数据进行缓存,
比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓
存数据进行管理。
realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据。
它的主要目的是与数据库打交道,查询数据库中的认证的信息
(比如用户名和密码),查询授权的信息(比如权限的code等,
所以这里可以理解为调用数据库查询一系列的信息,一般情况下在项
目中采用自定义的realm,因为不同的业务需求不一样))
cryptography:密码管理,提供了一套加密/解密的组件,方便开发。
比如提供常用的散列、加/解密等功能。
内置过滤器:
shiro内置了许多过滤器用来控制认证授权
anon : org.apache.shiro.web.filter.authc.AnonymousFilter
authc : org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic : org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms : org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port : org.apache.shiro.web.filter.authz.PortFilter
rest : org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles : org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl : org.apache.shiro.web.filter.authz.SslFilter
user : org.apache.shiro.web.filter.authc.UserFilter
shiro的授权方式有三种:
(1)—— 编程式:通过写if/else 授权代码块完成:(这种比较少用,一般在项目中采用后两种)
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}
(2)—— 注解式:通过在执行的Java方法上放置相应的注解完成:
@RequiresRoles("admin")
public void hello() {
//有权限
}
(3)—— JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:
在jsp页面导入shiro的标签既可以使用shiro的标签来进行权限的判断:
Jsp页面添加:
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
业务逻辑
i.单点登录
1、subject(主体)请求认证,调用subject.login(token)
2、SecurityManager (安全管理器)执行认证
3、SecurityManager通过ModularRealmAuthenticator进行认证。
4、ModularRealmAuthenticator将token传给realm,realm根据token中用户 信息从数据库查询用户信息(包括身份和凭证)
5、realm如果查询不到用户给ModularRealmAuthenticator返回null, ModularRealmAuthenticator抛出异常(用户不存在)
6、realm如果查询到用户给ModularRealmAuthenticator返回 AuthenticationInfo(认证信息)
7、ModularRealmAuthenticator拿着AuthenticationInfo(认证信息)去进行凭证 (密码 )比对。如果一致则认证通过,如果不致抛出异常(凭证错误)。
授权
1、对subject进行授权,调用方法isPermitted("permission串")
2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库 查询权限数据调用realm的授权方法:doGetAuthorizationInfo
4、realm从数据库查询权限数据,返回ModularRealmAuthorizer
5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中, 说明用户访问permission串有权限,否则 没有权限,抛出异常。
使用FormAuthenticationFilter过虑器实现 ,原理如下:
将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl
FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的)
FormAuthenticationFilter调用realm传入一个token(username和password)
realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。
如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息)
3.代码