shiro分步学习,详细-------web篇

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
roles		org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
perms		org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
user		org.apache.shiro.web.filter.authc.UserFilter
logout		org.apache.shiro.web.filter.authc.LogoutFilter
port		org.apache.shiro.web.filter.authz.PortFilter
rest		org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
ssl		org.apache.shiro.web.filter.authz.SslFilter


anon:匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤;示例“/static/**=anon”
authc:表示需要认证(登录)才能使用;示例“/**=authc”
        主要属性:usernameParam:表单提交的用户名参数名( username);  passwordParam:表单提交的密码参数名(password); rememberMeParam:表单提交的密码参数名(rememberMe);  loginUrl:登录页面地
         址(/login.jsp);successUrl:登录成功后的默认重定向地址; failureKeyAttribute:登录失败后错误信息存储key(shiroLoginFailure);
authcBasic:Basic HTTP身份验证拦截器,主要属性: applicationName:弹出登录框显示的信息(application);
roles:角色授权拦截器,验证用户是否拥有资源角色;示例“/admin/**=roles[admin]”
perms:权限授权拦截器,验证用户是否拥有资源权限;示例“/user/create=perms["user:create"]”
user:用户拦截器,用户已经身份验证/记住我登录的都可;示例“/index=user”
logout:退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/);示例“/logout=logout”
port:端口拦截器,主要属性:port(80):可以通过的端口;示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
rest:rest风格拦截器,自动根据请求方法构建权限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)构建权限字符串;
       示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll);
ssl:SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他和port拦截器一样;
注:
anon,authcBasic,auchc,user是认证过滤器,
perms,roles,ssl,rest,port是授权过滤器

shiro过滤方式: 

 shiro过滤器数字越小,优先级越高

authc登录拦截器工作原理 authc拦截器有2个作用:

1>登录认证     请求进来时,拦截并判断当前用户是否登录了,如果已经登录了放行, 如果没有登录,跳转到authc.loginUrl属性配置的路径,注意:默认是/login.jsp

2>执行登录认证     请求进来时,如果请求的路径为authc.loginUrl属性配置的路径(没配置,默认是/login.jsp)时,如果当前用户没有登录,authc这个拦截器会尝试获取请求中的账号跟密码值,然后比对ini配置文件或者realm中的用户列表,如果比对正确,直接执行登录操作,反之,抛异常,跳转到authc.loginUrl指定的路径。

注意:请求中账号与密码必须固定为username 跟password, 如果需要改动必须额外指定,authc.usernameParam=xxx   authc.passwordParam=xxxx

authc登录成功之后处理逻辑:

Shiro的jsp标签

 

标签名称			         标签条件(均是显示标签内容)
<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:principal property="username"/>     	显示用户身份中的属性值

shiro的web应用

1、导入相关依赖

   <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!-- shiro核心的依赖 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.2</version>
        </dependency>
        <!-- shiro对web支持的依赖 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.2.2</version>
        </dependency>
        <!-- serlvet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

2、在web.xml中配置shiro过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

    <!--初始化securityManager对象所需要的环境配置-->
    <context-param>
        <param-name>shiroEnvironmentClass</param-name>
        <param-value>org.apache.shiro.web.env.IniWebEnvironment</param-value>
    </context-param>
    <context-param>
        <param-name>shiroConfigLocations</param-name>
        <param-value>classpath:shiro.ini</param-value>
    </context-param>
    <!--
    	从Shiro 1.2开始引入了Environment/WebEnvironment的概念,即由它们的实现提供相应的SecurityManager及其相应的依赖。
    	ShiroFilter会自动找到Environment然后获取相应的依赖。
    	底层:返回反射创建shiroEnvironmentClass对象,调用其init方法.
    		shiroEnvironmentClass中的init方法创建SecurityManager实例并绑定到当前运行环境
     -->
    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>


    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <!-- 拦截所有的请求 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3、ini配置文件

[main]
#默认是/login.jsp
authc.loginUrl=/login
#用户无需要的角色时跳转的页面
roles.unauthorizedUrl=/nopermission.jsp
#用户无需要的权限时跳转的页面
perms.unauthorizedUrl=/nopermission.jsp
#登出之后重定向的页面
logout.redirectUrl=/login
[users]
admin=666,admin
zhangsan=666,deptMgr
[roles]
admin=employee:*,department:*
deptMgr=department:view
[urls]
#静态资源可以匿名访问
/static/**=anon
#访问员工列表需要身份认证及需要拥有admin角色
/employee=authc,roles[admin]
#访问部门列表需要身份认证及需要拥有department:view的权限
/department=authc,perms["department:view"]
#当请求loginOut,会被logout捕获并清除session
/loginOut=logout
#所有的请求都需要身份认证
/**=authc

4、主要代码:

    LoginServlet:

package com.zhangchao.shiro.servlet;

import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "loginServlet", urlPatterns = "/login")
public class LoginServlet  extends HttpServlet {
	@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
    }

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
        //如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
        String exceptionClassName = (String) req.getAttribute("shiroLoginFailure");
        //根据shiro返回的异常类路径判断,抛出指定异常信息
        System.out.println(exceptionClassName);
        if(exceptionClassName!=null){
            if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
                //最终会抛给异常处理器
                System.out.println("账号不存在");
                req.setAttribute("errorMsg", "账号不存在");
            } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
                System.out.println("用户名/密码错误");
                req.setAttribute("errorMsg", "用户名/密码错误");
            } else {
                //最终在异常处理器生成未知错误.
                System.out.println("其他异常信息");
                req.setAttribute("errorMsg", "其他异常信息");
            }
        }
        //此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
        //登陆失败还到login页面
        req.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(req, resp);
    }
	
}

完整代码在github,点击前往

同时,非常感谢姚老师的视频,还有笔记,本文大部分内容由笔记而来,笔记和xmind都在github

视频学习地址,点击进入

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值