shiro开发(四)

1      shiro授权

 

1.1    授权流程

 

1.2    授权方式

Shiro 支持三种方式的授权:

n  编程式:通过写if/else 授权代码块完成:

Subject subject =SecurityUtils.getSubject();

if(subject.hasRole(“admin”)) {

//有权限

} else {

//无权限

}

n  注解式:通过在执行的Java方法上放置相应的注解完成:

@RequiresRoles("admin")

public void hello() {

//有权限

}

n  JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:

<shiro:hasRolename="admin">

<!— 有权限—>

</shiro:hasRole>

 

本教程序授权测试使用第一种编程方式,实际与web系统集成使用后两种方式。

 

1.3    授权测试

1.3.1  shiro-permission.ini

创建存放权限的配置文件,shiro-permission.ini:


[user]

#用户zhang的密码是123,此用户具有role1role2两个角色

zhang=123,role1,role2

wang=123,role2

 

[roles]

role1=user:create,user:update  #角色role1拥有create、update权限

role2=user:create,user:delete   #角色role2拥有create、delete权限

#角色role3对资源user拥有create权限

role3=user:create

在ini文件中用户、角色、权限的配置规则是:“用户名=密码,角色1,角色2...” “角色=权限1,权限2...”,首先根据用户名找角色,再根据角色找权限,角色是权限集合。

 

 

 

1.3.2  权限字符串规则

         权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

 

例子:

用户创建权限:user:create,或user:create:*

用户修改实例001的权限:user:update:001

用户实例001的所有权限:user*001

 

 

1.3.3  测试代码

 

         测试代码同认证代码,注意ini地址改为shiro-permission.ini,主要学习下边授权的方法,注意:在用户认证通过后执行下边的授权代码。

 

@Test

    publicvoid testPermission(){

 

       // ini文件中创建SecurityManager工厂

       Factory<SecurityManager>factory =new IniSecurityManagerFactory(

              "classpath:shiro-permission.ini");

 

       // 创建SecurityManager

       SecurityManagersecurityManager = factory.getInstance();

 

       // securityManager设置到运行环境

       SecurityUtils.setSecurityManager(securityManager);

 

       // 创建主体对象

       Subject subject =SecurityUtils.getSubject();

 

       // 对主体对象进行认证

       // 用户登陆

       // 设置用户认证的身份(principals)和凭证(credentials)

       UsernamePasswordToken token =newUsernamePasswordToken("zhang","123");

       try {

           subject.login(token);

       } catch(AuthenticationException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

 

       // 用户认证状态

       Boolean isAuthenticated =subject.isAuthenticated();

 

       System.out.println("用户认证状态:" +isAuthenticated);

 

       // 用户授权检测基于角色授权

       // 是否有某一个角色

       System.out.println("用户是否拥有一个角色:" +subject.hasRole("role1"));

       // 是否有多个角色

       System.out.println("用户是否拥有多个角色:" +subject.hasAllRoles(Arrays.asList("role1","role2")));

      

//     subject.checkRole("role1");

//     subject.checkRoles(Arrays.asList("role1","role2"));

 

       // 授权检测,失败则抛出异常

       // subject.checkRole("role22");

 

       // 基于资源授权

       System.out.println("是否拥有某一个权限:" +subject.isPermitted("user:delete"));

       System.out.println("是否拥有多个权限:" +subject.isPermittedAll("user:create:1",   "user:delete"));

      

       //检查权限

       subject.checkPermission("sys:user:delete");

       subject.checkPermissions("user:create:1","user:delete");

      

 

    }

 

 

1.3.4  基于角色的授权

//用户授权检测基于角色授权

       // 是否有某一个角色

       System.out.println("用户是否拥有一个角色:" +subject.hasRole("role1"));

       // 是否有多个角色

       System.out.println("用户是否拥有多个角色:" +subject.hasAllRoles(Arrays.asList("role1","role2")));

            

 对应的check方法:

subject.checkRole("role1");

subject.checkRoles(Arrays.asList("role1","role2"));

 

上边check方法如果授权失败则抛出异常:

org.apache.shiro.authz.UnauthorizedException:Subject does not have role [.....]

        

 

 

1.3.5  基于资源授权

 

//基于资源授权

       System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));

       System.out.println("是否拥有多个权限:" +subject.isPermittedAll("user:create:1",   "user:delete"));

对应的check方法:

subject.checkPermission("sys:user:delete");

subject.checkPermissions("user:create:1","user:delete");

 

 

上边check方法如果授权失败则抛出异常:

org.apache.shiro.authz.UnauthorizedException:Subject does not have permission [....]

        

 

 

1.4    自定义realm

         与上边认证自定义realm一样,大部分情况是要从数据库获取权限数据,这里直接实现基于资源的授权。

1.4.1  realm代码

 

         在认证章节写的自定义realm类中完善doGetAuthorizationInfo方法,此方法需要完成:根据用户身份信息从数据库查询权限字符串,由shiro进行授权。

        

 

//授权

    @Override

    protected AuthorizationInfodoGetAuthorizationInfo(

           PrincipalCollectionprincipals) {

       // 获取身份信息

       String username =(String) principals.getPrimaryPrincipal();

       // 根据身份信息从数据库中查询权限数据

       //....这里使用静态数据模拟

       List<String> permissions=new ArrayList<String>();

       permissions.add("user:create");

       permissions.add("user.delete");

      

       //将权限信息封闭为AuthorizationInfo

      

       SimpleAuthorizationInfosimpleAuthorizationInfo =new SimpleAuthorizationInfo();

       for(Stringpermission:permissions){

           simpleAuthorizationInfo.addStringPermission(permission);

       }

      

       returnsimpleAuthorizationInfo;

    }

 

 

1.4.2  shiro-realm.ini

ini配置文件还使用认证阶段使用的,不用改变。

思考:shiro-permission.ini中的[roles]为什么不需要了??

 

1.4.3  测试代码

同上边的授权测试代码,注意修改ini地址为shiro-realm.ini。

 

 

1.4.4  授权执行流程

 

1、  执行subject.isPermitted("user:create")

2、  securityManager通过对ModularRealmAuthorizer授权

3、ModularRealmAuthorizer调取realm获取权限信息

4、  ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

 

 

 

2      shiro与项目集成开发

 

2.1    shiro与spring web项目整合

 

         shiro与springweb项目整合在“基于url拦截实现的工程”基础上整合,基于url拦截实现的工程的技术架构是springmvc+mybatis,整合注意两点:

         1、shiro与spring整合

         2、加入shiro对web应用的支持

 

2.1.1  取消原springmvc认证和授权拦截器

去掉springmvc.xml中配置的LoginInterceptor和PermissionInterceptor拦截器。

 

2.1.2  加入shiro的 jar包

 

2.1.3  web.xml添加shiro Filter

 

<!-- shiro过虑器,DelegatingFilterProx会从spring容器中找shiroFilter-->

    <filter>

    <filter-name>shiroFilter</filter-name>

    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

       <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>

    </filter-mapping>

 

 

2.1.4  applicationContext-shiro.xml

 

<!--Shiro Web过滤器 -->

    <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"/>

<!-- shiro拦截器配置 -->

       <property name="filters">

           <map>

              <entry key="authc"value-ref="formAuthenticationFilter"/>

           </map>

       </property>

       <property name="filterChainDefinitions">

           <value>

              <!-- 必须通过身份认证方可访问,身份认证的url必须和过虑器中指定的loginUrl一致 -->

               /loginsubmit.action=authc

              <!--退出拦截,请求logout.action执行退出操作 -->

              /logout.action= logout

              <!-- 无权访问页面 -->

              /refuse.jsp = anon

              <!-- roles[XX]表示有XX角色才可访问 -->

              /item/list.action =roles[item],authc

              /js/** anon

              /images/** anon

              /styles/** anon

              <!-- user表示身份认证通过或通过记住我认证通过的可以访问 -->

              /** = user

              <!-- /**放在最下边,如果一个url有多个过虑器则多个过虑器中间用逗号分隔,如:/** = user,roles[admin] -->

 

           </value>

       </property>

    </bean>

 

 

    <!-- 安全管理器 -->

    <bean id="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

       <property name="realm"ref="userRealm"/>

      

    </bean>

 

    <!-- 自定义 realm -->

    <bean id="userRealm"class="cn.itcast.ssm.realm.CustomRealm1">

    </bean>

    <!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->

    <bean id="formAuthenticationFilter"

       class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">

       <!-- 表单中账号的input名称 -->

       <property name="usernameParam"value="usercode"/>

       <!-- 表单中密码的input名称 -->

       <property name="passwordParam"value="password"/>

       <!-- <property name="rememberMeParam"value="rememberMe"/> -->

       <!-- loginurl:用户登陆地址,此地址是可以http访问的url地址 -->

       <property name="loginUrl"value="/loginsubmit.action"/>

    </bean>


securityManager:这个属性是必须的。

loginUrl:没有登录认证的用户请求将跳转到此地址,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。

unauthorizedUrl:没有权限默认跳转的页面。

 

使用shiro注解授权

 

在springmvc.xml中配置shiro注解支持,可在controller方法中使用shiro注解配置权限:

 

<!--开启aop,对类代理 -->

    <aop:config proxy-target-class="true"></aop:config>

    <!-- 开启shiro注解支持 -->

    <bean

       class="

org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

       <property name="securityManager"ref="securityManager"/>

    </bean>

 

修改Controller代码,在方法上添加授权注解,如下:

 

//查询商品列表

    @RequestMapping("/queryItem")

     @RequestPermissions("item:query")

    public ModelAndViewqueryItem()throws Exception {

 

         上边代码@RequiresPermissions("item:query")表示必须拥有“item:query”权限方可执行。

         其它的方法参考示例添加注解,一边添加一边思考这比基于url拦截有什么好处。

 

 

2.1.6  自定义realm

 

此realm先不从数据库查询权限数据,当前需要先将shiro整合完成,在上边章节定义的realm基础上修改。

 

publicclass CustomRealm1 extends AuthorizingRealm{

 

    @Autowired

    private SysServicesysService;

 

    @Override

    public String getName() {

       return"customRealm";

    }

 

    // 支持什么类型的token

    @Override

    publicbooleansupports(AuthenticationToken token) {

       return tokeninstanceof UsernamePasswordToken;

    }

 

    // 认证

    @Override

    protected AuthenticationInfodoGetAuthenticationInfo(

           AuthenticationToken token)throws AuthenticationException {

 

       // token获取用户身份信息

       String username = (String)token.getPrincipal();

       // username从数据库中查询

       // ....

        // 如果查询不到则返回null

       if (!username.equals("zhang")) {//这里模拟查询不到

           returnnull;

       }

 

       // 获取从数据库查询出来的用户密码

       String password = "123";// 这里使用静态数据模拟。。

      

       // 根据用户id从数据库取出菜单

       //...先用静态数据

       List<SysPermission>menus =new ArrayList<SysPermission>();;

      

       SysPermission sysPermission_1=new SysPermission();

       sysPermission_1.setName("商品管理");

       sysPermission_1.setUrl("/item/queryItem.action");

       SysPermission sysPermission_2=new SysPermission();

       sysPermission_2.setName("用户管理");

       sysPermission_2.setUrl("/user/query.action");

      

       menus.add(sysPermission_1);

       menus.add(sysPermission_2);

      

       // 构建用户身体份信息

       ActiveUser activeUser =new ActiveUser();

       activeUser.setUserid(username);

       activeUser.setUsername(username);

       activeUser.setUsercode(username);

       activeUser.setMenus(menus);

 

       // 返回认证信息由父类AuthenticatingRealm进行认证

       SimpleAuthenticationInfosimpleAuthenticationInfo =new SimpleAuthenticationInfo(

              activeUser, password,getName());

 

       returnsimpleAuthenticationInfo;

    }

 

    // 授权

    @Override

    protected AuthorizationInfodoGetAuthorizationInfo(

           PrincipalCollectionprincipals) {

       // 获取身份信息

       ActiveUser activeUser =(ActiveUser) principals.getPrimaryPrincipal();

       //用户id

       String userid =activeUser.getUserid();

       // 根据用户id从数据库中查询权限数据

       // ....这里使用静态数据模拟

       List<String> permissions=new ArrayList<String>();

       permissions.add("item:query");

       permissions.add("item:update");

 

       // 将权限信息封闭为AuthorizationInfo

 

       SimpleAuthorizationInfosimpleAuthorizationInfo =new SimpleAuthorizationInfo();

       for (String permission :permissions) {

           simpleAuthorizationInfo.addStringPermission(permission);

       }

 

       returnsimpleAuthorizationInfo;

    }

 

}

 

 

 

2.1.7  登录

//用户登陆页面

    @RequestMapping("/login")

    public String login()throws Exception{

       return"login";

    }

    // 用户登陆提交

    @RequestMapping("/loginsubmit")

    public Stringloginsubmit(Model model, HttpServletRequest request)

           throws Exception {

 

       // shiro在认证过程中出现错误后将异常类路径通过request返回

       String exceptionClassName =(String) request

              .getAttribute("shiroLoginFailure");

       if (UnknownAccountException.class.getName().equals(exceptionClassName)){

           thrownew CustomException("账号不存在");

       } elseif(IncorrectCredentialsException.class.getName().equals(

              exceptionClassName)) {

           thrownew CustomException("用户名/密码错误");

       } else{

           thrownew Exception();//最终在异常处理器生成未知错误

       }

    }

 

2.1.8  首页

 

由于session由shiro管理,需要修改首页的controller方法:

 

//系统首页

    @RequestMapping("/first")

    public String first(Modelmodel)throws Exception{

      

       //主体

       Subject subject =SecurityUtils.getSubject();

       //身份

       ActiveUser activeUser = (ActiveUser)subject.getPrincipal();

       model.addAttribute("activeUser", activeUser);

       return"/first";

    }

 

 

2.1.9  退出

 

由于使用shiro的sessionManager,不用开发退出功能,使用shiro的logout拦截器即可。

 

<!--退出拦截,请求logout.action执行退出操作 -->

/logout.action = logout

 

 

2.1.10             无权限refuse.jsp

 

当用户无操作权限,shiro将跳转到refuse.jsp页面。

参考:applicationContext-shiro.xml

 

 

 

2.2    realm连接数据库

 

2.2.1  添加凭证匹配器

添加凭证匹配器实现md5加密校验。

修改applicationContext-shiro.xml:

 

<!--凭证匹配器 -->

    <bean id="credentialsMatcher"

       class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">

       <property name="hashAlgorithmName"value="md5"/>

       <property name="hashIterations"value="1"/>

    </bean>

 

<!--自定义 realm -->

    <bean id="userRealm"class="cn.itcast.ssm.realm.CustomRealm1">

       <property name="credentialsMatcher"ref="credentialsMatcher"/>

    </bean>

 

 

2.2.2  realm代码

修改realm代码从数据库中查询用户身份信息和权限信息,将sysService注入realm。

 

 

publicclass CustomRealm1 extends AuthorizingRealm{

 

    @Autowired

    private SysServicesysService;

 

    @Override

    public String getName() {

       return"customRealm";

    }

 

    // 支持什么类型的token

    @Override

    publicbooleansupports(AuthenticationToken token) {

       return tokeninstanceofUsernamePasswordToken;

    }

 

    @Override

    protected AuthenticationInfodoGetAuthenticationInfo(

           AuthenticationToken token)throws AuthenticationException {

       // token中获取用户身份

       String usercode = (String)token.getPrincipal();

 

       SysUser sysUser = null;

       try {

           sysUser = sysService.findSysuserByUsercode(usercode);

       } catch (Exception e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

 

       // 如果账号不存在

       if (sysUser ==null) {

           thrownewUnknownAccountException("账号找不到");

       }

 

       // 根据用户id取出菜单

       List<SysPermission>menus =null;

       try {

           menus = sysService.findMenuList(sysUser.getId());

       } catch (Exception e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

       // 用户密码

       String password =sysUser.getPassword();

       //

       String salt =sysUser.getSalt();

      

       // 构建用户身体份信息

       ActiveUser activeUser =new ActiveUser();

       activeUser.setUserid(sysUser.getId());

       activeUser.setUsername(sysUser.getUsername());

       activeUser.setUsercode(sysUser.getUsercode());

       activeUser.setMenus(menus);

      

       SimpleAuthenticationInfosimpleAuthenticationInfo =new SimpleAuthenticationInfo(

              activeUser, password,ByteSource.Util.bytes(salt),getName());

      

       return simpleAuthenticationInfo;

    }

 

    @Override

    protected AuthorizationInfodoGetAuthorizationInfo(

           PrincipalCollectionprincipals) {

      

       //身份信息

       ActiveUser activeUser =(ActiveUser) principals.getPrimaryPrincipal();

       //用户id

       String userid =activeUser.getUserid();

       //获取用户权限

       List<SysPermission>permissions =null;

       try {

           permissions = sysService.findSysPermissionList(userid);

       } catch (Exception e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

       //构建shiro授权信息

       SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();

       for(SysPermissionsysPermission:permissions){

           simpleAuthorizationInfo.addStringPermission(sysPermission.getPercode());

       }

      

       returnsimpleAuthorizationInfo;

      

    }

 

}

 

 

 

 

 

2.3    缓存

   shiro每个授权都会通过realm获取权限信息,为了提高访问速度需要添加缓存,第一次从realm中读取权限数据,之后不再读取,这里Shiro和Ehcache整合。

 

2.3.1 添加Ehcache的jar包

 

2.3.2 配置

在applicationContext-shiro.xml中配置缓存管理器。

<!--安全管理器 -->

    <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>

 

<!--缓存管理器 -->

    <bean id="cacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">

    </bean>

 

2.4    session管理

在applicationContext-shiro.xml中配置sessionManager:

<!--安全管理器 -->

    <bean id="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

       <property name="realm"ref="userRealm"/>

       <property name="sessionManager"ref="sessionManager"/>

    </bean>

<!--会话管理器 -->

    <bean id="sessionManager"class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">

        <!-- session的失效时长,单位毫秒 -->

        <property name="globalSessionTimeout"value="600000"/>

        <!-- 删除失效的session -->

        <propertyname="deleteInvalidSessions"value="true"/>

    </bean>

 

 

 

2.5    验证码

 

2.5.1 自定义FormAuthenticationFilter

需要在验证账号和名称之前校验验证码。

 

publicclassMyFormAuthenticationFilter extends FormAuthenticationFilter {

    protectedbooleanonAccessDenied(ServletRequest request,

           ServletResponse response,Object mappedValue)throws Exception {

 

       // 校验验证码

       // session获取正确的验证码

       HttpSession session =((HttpServletRequest)request).getSession();

       //页面输入的验证码

       String randomcode =request.getParameter("randomcode");

       //session中取出验证码

       String validateCode = (String)session.getAttribute("validateCode");

       if (!randomcode.equals(validateCode)){

           // randomCodeError表示验证码错误

           request.setAttribute("shiroLoginFailure","randomCodeError");

           //拒绝访问,不再校验账号和密码

           returntrue;

       }

       

       returnsuper.onAccessDenied(request,response, mappedValue);

    }

}

 

2.5.2 修改FormAuthenticationFilter配置

修改applicationContext-shiro.xml中对FormAuthenticationFilter的配置。

 

<beanid="formAuthenticationFilter"

       class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">

 

改为

      

<beanid="formAuthenticationFilter"

       class="cn.itcast.ssm.shiro.MyFormAuthenticationFilter">

 

 

2.5.3 登陆页面

添加验证码:

<TR>

                         <TD>验证码:</TD>

                         <TD><inputid="randomcode"name="randomcode"size="8"/> <img

                            id="randomcode_img" src="${baseurl}validatecode.jsp"alt=""

                            width="56" height="20"align='absMiddle'/> <a

                            href=javascript:randomcode_refresh()>刷新</a></TD>

                     </TR>

 

2.5.4 配置validatecode.jsp匿名访问

 

修改applicationContext-shiro.xml:

 

 

2.6    记住我

         用户登陆选择“自动登陆”本次登陆成功会向cookie写身份信息,下次登陆从cookie中取出身份信息实现自动登陆。

2.6.1 用户身份实现java.io.Serializable接口

向cookie记录身份信息需要用户身份信息对象实现序列化接口,如下:

 

 

 

2.6.2 配置

 

<!--安全管理器 -->

    <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"/>

       <!-- 记住我 -->

       <property name="rememberMeManager" ref="rememberMeManager"/>

    </bean>

 

<!-- rememberMeManager管理器 -->

    <bean id="rememberMeManager"class="org.apache.shiro.web.mgt.CookieRememberMeManager">

       <property name="cookie"ref="rememberMeCookie"/>

    </bean>

    <!-- 记住我cookie -->

    <bean id="rememberMeCookie"class="org.apache.shiro.web.servlet.SimpleCookie">

       <constructor-arg value="rememberMe" />

       <!-- 记住我cookie生效时间30 -->

       <property name="maxAge"value="2592000"/>

    </bean>

 

 

修改formAuthenticationFitler添加页面中“记住我checkbox”的input名称:

 

<beanid="formAuthenticationFilter"

       class="cn.itcast.ssm.shiro.MyFormAuthenticationFilter">

       <!-- 表单中账号的input名称 -->

       <property name="usernameParam"value="usercode"/>

       <!-- 表单中密码的input名称 -->

       <property name="passwordParam"value="password"/>

       <property name="rememberMeParam" value="rememberMe"/>

       <!-- loginurl:用户登陆地址,此地址是可以http访问的url地址 -->

       <property name="loginUrl"value="/loginsubmit.action"/>

    </bean>

 

 

2.6.3 登陆页面

在login.jsp中添加“记住我”checkbox。

 

<TR>

                         <TD></TD>

                         <TD>

                         <input type="checkbox"name="rememberMe"/>自动登陆

                         </TD>

                     </TR>

 

 

3      附:

3.1    shiro过虑器

过滤器简称

对应的java类

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

logout

org.apache.shiro.web.filter.authc.LogoutFilter

 

 

anon:例子/admins/**=anon 没有参数,表示可以匿名使用。

authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数

roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。

rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。

port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString

是你访问的url里的?后面的参数。

authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证

 

ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https

user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查

注:

anon,authcBasic,auchc,user是认证过滤器,

perms,roles,ssl,rest,port是授权过滤器

 

3.2    shiro的jsp标签

 

Jsp页面添加:

<%@ tagliburi="http://shiro.apache.org/tags"prefix="shiro" %>

 

标签名称

标签条件(均是显示标签内容)

<shiro:authenticated>

登录之后

<shiro:notAuthenticated>

不在登录状态时

<shiro:guest>

用户在没有RememberMe时

<shiro:user>

用户在RememberMe时

<shiro:hasAnyRoles name="abc,123" >

在有abc或者123角色时

<shiro:hasRole name="abc">

拥有角色abc

<shiro:lacksRole name="abc">

没有角色abc

<shiro:hasPermission name="abc">

拥有权限资源abc

<shiro:lacksPermission name="abc">

没有abc权限资源

<shiro:principal>

显示用户身份名称

 <shiro:principalproperty="username"/>     显示用户身份中的属性值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个shiro的入门Demo.. 使用了Spring MVC,mybaits等技术.. 数据库设计 : User : name--password Role : id--userid--roleName Function : id--userid--url tinys普通用户只能访问index.jsp admin用户通过添加了admin的permission,所以可以访问admin.jsp role用户通过添加了role角色,所以可以访问role.jsp 这是最基本的shiro的运用..目的是让你快速了解shiro的机制.. 这个Demo体现shiro的地方主要在两个类以及shiro.xml的配置文件 CustomRealm : 处理了登录验证以及授权.. ShiroAction : 用来传递登录时的用户数据..转换为token传递给realm...之后根据结果做相应的逻辑处理.. shiro.xml : shiro的主要配置... 规则定义在以下地方 : <!-- 过滤链定义 --> <property name="filterChainDefinitions"> <value> /login.jsp* = anon /index.jsp* = authc /index.do* = authc /admin.jsp*=authc,perms[/admin] /role.jsp*=authc,roles[role] </value> </property> 2015-10-28更新 --通过添加了以下内容来使用注解方式配置权限.... <!-- Support Shiro Annotation 必须放在springMVC配置文件中 --> <!-- 异常处理,权限注解会抛出异常,根据异常返回相应页面 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">unauth</prop> <prop key="org.apache.shiro.authz.UnauthenticatedException">login</prop> </props> </property> </bean> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> <!-- end --> --修改了过滤链 <!-- 过滤链定义 --> //简单的讲就是把需要特别处理的路径写到前面,越特殊写到越前 <property name="filterChainDefinitions"> <value> <!-- 注意这里需要把前缀写全.../shiro这里 --> /shiro/login.do*=anon /login.jsp* = anon /admin.jsp*=authc,perms[/admin] /role.jsp*=authc,roles[role] /** = authc </value> </property>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值