1. 权限概述
系统提供了很多功能,并不是所有的用户登录系统都可以操作这些功能。我们需要对用户的访问进行控制。
认证:系统提供的用于识别用户身份的功能(通常是登录功能)。
授权:系统提供的赋予用户访问某个功能的能力。
1. 常见的权限控制的方式
1.1 URL拦截权限控制---基于过滤器或者拦截器
方法注解权限控制---基于代理技术
1. 权限模块数据模型
用户表:t_user
角色表:auth_role
权限表:auth_function
用户角色关系表:user_role
角色权限关系表:role_function
1. apache shiro
ApacheShiro is a powerful and easy-to-use Java security framework that performsauthentication, authorization, cryptography, and session management. WithShiro’s easy-to-understand API, you can quickly and easily secure anyapplication – from the smallest
mobile applications to the largest web andenterprise applications.
提供的功能
shiro的程序运行流程图:
Application code:应用程序代码,开发人员编写的代码
Subject:主体,当前用户
SecurityManager:安全管理器,shiro框架的核心对象,管理各个组件
Realm:类似于Dao,负责访问安全数据(用户数据、角色数据、权限数据)
1. 将shiro应用到项目
第一步:导入shiro-all.jar
第二步:在web.xml中配置一个spring用于整合shiro的过滤器
第三步:在spring配置文件中配置一个bean,id必须和上面的过滤器名称相同
<!-- 配置一个工厂bean,用于创建shiro框架用到过滤器 --> <beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!--注入安全管理器 --> <propertyname="securityManager"ref="securityManager"></property> <!--注入当前系统的登录页面 --> <propertyname="loginUrl"value="/login.jsp"/> <!--注入成功页面 --> <propertyname="successUrl"value="/index.jsp"/> <!--注入权限不足提示页面 --> <propertyname="unauthorizedUrl"value="/unauthorizedUrl.jsp"/> <!--注入URL拦截规则 --> <propertyname="filterChainDefinitions"> <value> /css/** = anon /images/** = anon /js/** = anon /login.jsp* = anon /validatecode.jsp* = anon /userAction_login.action = anon /page_base_staff.action =perms["staff"] /* = authc </value> </property> </bean> |
第四步:在spring配置文件中注册安全管理器,为安全管理器注入realm
<!-- 注册自定义realm --> <beanid="bosRealm"class="com.xiao.wen.shiro.BOSRealm"></bean>
<beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--注入上面的realm --> <propertyname="realm"ref="bosRealm"/> </bean> |
第五步:自定义一个BOSRealm
publicclass BOSRealmextends AuthorizingRealm { @Resource private IUserDaouserDao; /** * 认证方法 */ protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token)throws AuthenticationException { System.out.println("认证方法。。。"); UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername();//从令牌中获得用户名
User user = userDao.findUserByUsername(username); if (user ==null) { //用户名不存在 returnnull; } else { //用户名存在 String password = user.getPassword();//获得数据库中存储的密码 //创建简单认证信息对象 /*** * 参数一:签名,程序可以在任意位置获取当前放入的对象 * 参数二:从数据库中查询出的密码 * 参数三:当前realm的名称 */ SimpleAuthenticationInfoinfo =new SimpleAuthenticationInfo(user, password,this.getClass().getSimpleName()); returninfo;//返回给安全管理器,由安全管理器负责比对数据库中查询出的密码和页面提交的密码 } } /** * 授权方法 */ protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { returnnull; } } |
第六步:完善UserAction的login方法
publicString login(){ //生成的验证码 String key = (String) ServletActionContext.getRequest().getSession().getAttribute("key"); //判断用户输入的验证码是否正确 if(StringUtils.isNotBlank(checkcode) &&checkcode.equals(key)){ //验证码正确 //获得当前用户对象 Subject subject = SecurityUtils.getSubject();//状态为“未认证” String password = model.getPassword(); password = MD5Utils.md5(password); //构造一个用户名密码令牌 AuthenticationToken token =new UsernamePasswordToken(model.getUsername(), password); try{ subject.login(token); }catch (UnknownAccountException e) { e.printStackTrace(); //设置错误信息 this.addActionError(this.getText("usernamenotfound")); return"login"; }catch (Exception e) { e.printStackTrace(); //设置错误信息 this.addActionError(this.getText("loginError")); return"login"; } //获取认证信息对象中存储的User对象 User user = (User) subject.getPrincipal(); ServletActionContext.getRequest().getSession().setAttribute("loginUser", user); return"home"; }else{ //验证码错误,设置错误提示信息,跳转到登录页面 this.addActionError(this.getText("validateCodeError")); return"login"; } } |
第七步:在自定义Realm中编写授权方法
此处仅仅只是一个参考例子,实际应用中将会从xml或者是数据库中读取角色数据权限放入缓存,
已方便每一次权限拦截所做的权限校验。
1. shiro提供的权限控制方式
1.1 URL拦截权限控制
1.1 方法注解权限控制
第一步:在spring配置文件中开启shiro的注解支持
第二步:在Action的方法上使用shiro的注解描述执行当前方法需要具有的权限
1.1 页面标签权限控制
第一步:在jsp页面中引入shiro的标签
第二步:使用shiro的标签根据当前用户拥有的权限动态展示页面元素
以上就是shiro的使用过程。