该demo整合Shiro的相关配置参考开涛的博客

数据库表格相关设计

 
表格设计得比较简单,导航栏直接由角色表auth_role的角色描述vRoleDesc(父结点)和角色相关权限中的权限描述(标记为导航结点)vPermissionDesc(展开子项)组成。 

Shiro相关设置

密码输入错误次数限制

//密码重试5次次数限制
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher{
private Cache<String,AtomicInteger> passwordRetryCache; public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager){
passwordRetryCache=cacheManager.getCache("passwordRetryCache");
} @Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username=(String)token.getPrincipal();
AtomicInteger retryCount=passwordRetryCache.get(username);
if(retryCount==null){
retryCount=new AtomicInteger(0);
passwordRetryCache.put(username, retryCount);
}
if(retryCount.incrementAndGet()>5){
throw new ExcessiveAttemptsException();
}
boolean matches= super.doCredentialsMatch(token, info);//匹配密码
if(matches){
passwordRetryCache.remove(username);
}
return matches;
}
}

相关配置:

<!-- 凭证(密码)匹配器 -->
<bean id="credentialsMatcher" class="com.test.shiro.credentials.RetryLimitHashedCredentialsMatcher">
<constructor-arg ref="cacheManager"/>
<property name="hashAlgorithmName" value="md5"/><!--md5加密-->
<property name="hashIterations" value="2"/><!--加密迭代两次-->
<property name="storedCredentialsHexEncoded" value="true"/><!--为true时使用Hex编码(默认);false时使用Base64编码-->
</bean>

使用缓存实现为ehcache,相关配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="shiroCache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<cache name="passwordRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"<!--非永久有效-->
timeToIdleSeconds="3600"<!-- 对象空闲时间,即60min后失效-->
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
<!--...-->
</ehcache>

扩展AuthorizingRealm:用于从数据库抓取密码等相关验证信息和相关权限信息

public class UserRealm extends AuthorizingRealm{

    @Autowired
private UserService userService; //获取相关授权信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userName=(String)principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
authorizationInfo.setRoles(userService.findPermissionsByUserName(userName));//获取角色信息
authorizationInfo.setStringPermissions(userService.findPermissionsByUserName(userName));//获取权限信息 return authorizationInfo;
} //获取身份验证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName=(String)token.getPrincipal();
User user=userService.getUserByUserName(userName);//获取身份信息(密码和密码盐)
if(user==null){
throw new UnknownAccountException();
}
SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(
user.getUserName(),
user.getPassword(),
ByteSource.Util.bytes(user.getUserName()+user.getPasswordSalt()),
getName());
return authenticationInfo;
} }

登录相关

扩展FormAuthenticationFilter:用于登录后获取用户导航栏,并将其存入session范围

public class WithNavibarFormAuthenticationFilter extends FormAuthenticationFilter {

    @Autowired
private UserService userService; @Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
ServletResponse response) throws Exception {
HttpServletRequest httpReq=(HttpServletRequest)request; String userName=(String)SecurityUtils.getSubject().getPrincipal();
List navigationBar=userService.getNavigationBar(userName);
httpReq.getSession().setAttribute("navibar", navigationBar);
return super.onLoginSuccess(token, subject, request, response);
} }

登录Controller实现(用户密码不匹配情况下执行)

@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
//... @RequestMapping("/login")
public ModelAndView login(HttpServletRequest req){
String error=null;
String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");
if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
error = "用户名/密码错误";
} else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
error = "用户名/密码错误";
} else if(exceptionClassName != null) {
error = "其他错误:" + exceptionClassName;
}
ModelAndView mav=new ModelAndView("login");
mav.addObject("error", error);
return mav;
}
//...
}

登录表单代码:注意提交action=”“,以及输入控件name值须与form表单过滤器中的设置对应

<form class="form-signin" method="post" action="">
<h3 class="form-signin-heading">请登录</h3>
<label for="inputEmail" class="sr-only">用户名</label>
<input type="text" id="inputEmail" class="form-control" placeholder="用户名" name="username" required autofocus>
<label for="inputPassword" class="sr-only">密码</label>
<input type="password" id="inputPassword" class="form-control" placeholder="密码" name="password" required>
<div class="checkbox">
<label>
<input type="checkbox" name="rememberMe"> 记住我
</label>
</div>
<p class="bg-warning">${error}</p>
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
</form>

最后通过Spring注解,控制访问

@RequiresPermissions("user:list")
@RequestMapping("/list")
public ModelAndView showUserList(){
//
}

完整shiro配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 缓存管理器 使用Ehcache实现 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:config/ehcache.xml"/>
</bean>
<!-- 凭证(密码)匹配器 -->
<bean id="credentialsMatcher" class="com.test.shiro.credentials.RetryLimitHashedCredentialsMatcher">
<constructor-arg ref="cacheManager"/>
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="2"/>
<property name="storedCredentialsHexEncoded" value="true"/>
</bean>
<!-- Realm实现 -->
<bean id="userRealm" class="com.test.shiro.realm.UserRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
<property name="cachingEnabled" value="true"/>
<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="180000"/>
</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="userRealm"/>
<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="com.test.shiro.filter.WithNavibarFormAuthenticationFilter">
<property name="usernameParam" value="username"/>
<property name="passwordParam" value="password"/>
<property name="rememberMeParam" value="rememberMe"/>
<property name="loginUrl" value="/user/login"/><!--注意value值为登录url-->
</bean>
<!-- Shiro的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/user/login"/>
<property name="filters">
<util:map>
<entry key="authc" value-ref="formAuthenticationFilter"/>
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
/=authc
/index=authc
/user/login=authc<!-- 使用表单filter authc -->
/logout=logout
/static/**=anon<!-- 不拦截静态资源文件 -->
/**=user
</value>
</property>
</bean> <!-- Shiro生命周期处理器-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>

其他如dao、service、controller组件实现省略

完整代码见:https://github.com/weixupeng/auth-control_SSM

JavaWeb项目:Shiro实现简单的权限控制(整合SSM)的更多相关文章

  1. JAVAEE——BOS物流项目11:在realm中授权、shiro的方法注解权限控制、shiro的标签权限控制、总结shiro的权限控制方式、权限管理

    1 学习计划 1.在realm中进行授权 2.使用shiro的方法注解方式权限控制 n 在spring文件中配置开启shiro注解支持 n 在Action方法上使用注解 3.★使用shiro的标签进行 ...

  2. Spring项目集成ShiroFilter简单实现权限管理

    Shiros是我们开发中常用的用来实现权限控制的一种工具包,它主要有认证.授权.加密.会话管理.与Web集成.缓存等功能.我是从事javaweb工作的,我就经常遇到需要实现权限控制的项目,之前我们都是 ...

  3. elasticsearch使用jetty进行简单的权限控制

    默认elasticsearch是使用netty作为http的容器,由于netty并没有权限模块,所以默认es没有任何的权限控制,直接通过http就可以进行任何操作,除非把http禁用.但如果你使用el ...

  4. Shiro的认证和权限控制

    权限控制的方式 从类别上分,有两大类: - 认证:你是谁?–识别用户身份. - 授权:你能做什么?–限制用户使用的功能. 权限的控制级别 从控制级别(模型)上分: - URL级别-粗粒度 - 方法级别 ...

  5. shiro框架的四中权限控制方式

    https://www.cnblogs.com/cocosili/p/7103025.html 一.在自定义的realm中进行权限控制 在applicationContext.xml文件中添加  /a ...

  6. **CodeIgniter通过hook的方式实现简单的权限控制

    根据自己的实际情况,需要两个文件,一个是权限控制类,Acl,另外一个是权限配置的文件acl.php放在了config这个目录下. Acl这个类放在了application/hook/acl.php.通 ...

  7. springboot+mybatis+shiro——登录认证和权限控制

    转载:https://z77z.oschina.io/ 一.引入依赖 shiro-all包含shiro所有的包.shiro-core是核心包.shiro-web是与web整合.shiro-spring ...

  8. shiro框架学习-7- Shiro权限控制注解和编程方式

    讲解权限角色控制 @RequiresRoles, @RequiresPermissions等注解的使用和编程式控制 配置文件的方式 使用ShiroConfig 注解方式 @RequiresRoles( ...

  9. [PHP] 最简单的权限控制设计

    假设url部分我们只有action和method , 某个控制器下的某个方法 , 比如:log/loginlog   查看日志下的登陆日志, action就是log , method就是loginlo ...

随机推荐

  1. zabbix利用percona-toolkit工具监控Mysql主从同步状态

    一.下载percona-toolkit工具包 percona-toolkit是一组高级命令行工具的集合,可以查看当前服务的摘要信息,磁盘检测,分析慢查询日志,查找重复索引,实现表同步等等. [root ...

  2. P5200 [USACO19JAN]Sleepy Cow Sorting 牛客假日团队赛6 D 迷路的牛 (贪心)

    链接:https://ac.nowcoder.com/acm/contest/993/E 来源:牛客网 对牛排序 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...

  3. No application found. Either work inside a view function or push an application context.

    flask报了这个错,字面意思是说没有应用上下文,字面给的解决意见是要么放置在一个视图内,要么提供一个应用(flask)上下文. 查看文档发现文档给了个解决方案: 一个是通过app.app_conte ...

  4. 微信小程序模板消息后端代码

    利用spring 事件发送模板消息 1.定义事件 import com.ruoyi.project.salerauth.domain.TemplateMessage; import org.sprin ...

  5. Ubuntu下安装CUDA8.0及nvidia驱动

    参考:https://blog.csdn.net/qq_35379989/article/details/80147630 cuda的历史版本下载地址:https://developer.nvidia ...

  6. 16. ClustrixDB Rebalancer

    管理平衡 Clustrix Rebalancer被设计成自动作为后台进程运行,以便跨集群重新平衡数据.介绍如何配置和监视rebalancer,但是大多数部署不需要用户干预. Rebalancer主要通 ...

  7. Swagger+SpringBoot整理

    maven依赖 1 <dependency> 2 <groupId>io.springfox</groupId> 3 <artifactId>sprin ...

  8. 结合webpack使用vue-router

    demo结构 webpack.config.js var path = require('path'); // const { VueLoaderPlugin } = require('vue-loa ...

  9. 用smtplib来发送邮件

    先安装 pip install smtplib 发送qq,163邮件,带有附件的邮件 1.qq邮件 # 用于发送邮件的模块import smtplib # QQ邮箱/163邮箱的邮件发送:py文件发送 ...

  10. 在Java web模板的上进行编写

    要求: 链接:https://pan.baidu.com/s/15NdAt-aiv-X9sRbMSfXYXQ 提取码:7agw web模板: 链接:https://pan.baidu.com/s/1A ...