Shiro 与Servlet集成授权(十)

   Shiro提供了与Web集成的支持,其通过一个ShiroFilter入口来拦截需要安全控制的URL,然后进行相应的控制,ShiroFilter类似于如Struts2/SpringMVC这种web框架的前端控制器,其是安全控制的入口点,其负责读取配置(如ini配置文件),然后判断URL是否需要登录/权限等工作。

 使用maven来搭建shiro+serlvet授权

 (1)pom.xml文件

<!-- 添加servlet支持 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
		</dependency>

		<!-- jstl支持 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- log4j日志支持 -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>


		<!-- commons-logging -->
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>



		<!--slf4j-api -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.25</version>
		</dependency>



		<!-- shiro 包 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.3.2</version>

		</dependency>

		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>1.3.2</version>

		</dependency>

(2)通过查看官网如何配置web.xml文件


   如果shiro.ini文件没有配置,则默认会去src/main/webapp/WEB-INF/这个目录下寻找shiro.ini这个文件. 

	<!-- (1)shiro监听器 -->
	<listener>
		<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
	</listener>


	<!--(2)shiroFilter过滤 -->
	<filter>
		<filter-name>ShiroFilter</filter-name>
		<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
		<!-- 初始化参数 :配置在src/main/resources目录下-->
		<init-param>
			<param-name>configPath</param-name>
			<param-value>classpath:shiro.ini</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>ShiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

 (3)shiro.ini文件(可以查看官网文档)


[main]
#身份认证,角色,权限
authc.loginUrl=/login  #loginUrl是属性(FormAuthenticationFilter)
roles.unauthorizedUrl=/unauthorized.jsp  #unauthorizedUrl是属性在RolesAuthorizationFilter
perms.unauthorizedUrl=/unauthorized.jsp #unauthorizedUrl同上
[users]
#用户有着对应的角色
mike=123456,admin
jack=aaa,teacher
json=012
[roles]
#角色
admin=user:*
teacher=student:*
[urls]
#访问的地址的权限
/login=anon  #匿名访问
/admin=authc #需要认证
/student=roles[teacher] #必须要有这个角色才能访问
/teacher=perms["user:create"]  必须拥有这个权限才能访问

(4)jsp登录页面

	<form action="login" method="post">
		userName:<input name="userName" />
		<p />
		password:<input type="password" name="password" />
		<p />
		<input type="submit" value="login" />
	</form>

(5)创建LoginServlet用来测试身份验证

protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("LoginServlet doPost!");
		
		// 输出对象
		PrintWriter out = response.getWriter();
        
		//获得请求参数
		String userName=request.getParameter("userName");
		String password=request.getParameter("password");
		
		//获得当前用户对象
		Subject currentUser=SecurityUtils.getSubject();
		
		//获得令牌
		UsernamePasswordToken token=new UsernamePasswordToken(userName, password);
		
		try {
			
			//登录
			currentUser.login(token);
			
			//跳转
			response.sendRedirect("ok.jsp");
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			request.setAttribute("msg", "用户名或密码错误!");
			request.getRequestDispatcher("login.jsp").forward(request, response);
		}
		

		out.flush();
		out.close();
	}

(6)创建AdminServlet用来测试角色和权限

@WebServlet(name = "AdminServlet", urlPatterns = { "/admin","/student","/teacher"})
public class AdminServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
//	org.apache.shiro.web.filter.authc.FormAuthenticationFilter
//	org.apache.shiro.web.filter.authz.RolesAuthorizationFilter

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public AdminServlet() {
		// System.out.println("constructure LoginServlet");

	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = response.getWriter();
		
		//获得路径
		String path=request.getServletPath();
		String methodName=path.substring(1);
		
		System.out.println(path+"-->"+methodName);
		
		//反射机制
		try {
			Method method=getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
		
			//调用
			method.invoke(this, request,response);
		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		

		out.flush();
		out.close();
	}
	
	
	protected void admin(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = response.getWriter();

		out.println("AdminServlet Admin!");
		
		System.out.println("access Admin!");
		
		out.flush();
		out.close();
	}
	protected void student(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = response.getWriter();
		
		out.println("AdminServlet Student!");
		
		out.flush();
		out.close();
	}
	protected void teacher(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = response.getWriter();
		
		out.println("AdminServlet Teacher!");
		
		
		out.flush();
		out.close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("AdminServlet doPost!");
	
	}

}

运行测试:

(a)用mike用户访问,能访问/admin哦




(b)用jack用户访问,能访问/student,/teacher哦





(c)用json用户访问,不能访问/student哦



注意:

url模式使用Ant风格模式

Ant路径通配符支持?、*、**,注意通配符匹配不包括目录分隔符“/”:

?:匹配一个字符,如”/admin?”将匹配/admin1,/admin2 ..,但不匹配/admin或/admin12;

*:匹配零个或多个字符串,如/admin*将匹配/admin、/admin123,但不匹配/admin/1;

**:匹配路径中的零个或多个路径,如/admin/**将匹配/admin/a或/admin/a

 admin1 /admin2 /admin3....



可以访问: http://localhost:8888/shiroweb/admin12 


可以访问: http://localhost:8888/shiroweb/admin/admin


Jsp标签授权

jsp页面导入<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
Guest 标签:用户没有身份验证时显示相应信息,即游客访问信息;
User 标签:用户已经身份验证/记住我登录后显示相应的信息;
Authenticated 标签:用户已经身份验证通过,即 Subject.login 登录成功,不是记住我登录的。
notAuthenticated 标签:用户没有身份验证通过,即没有调用 Subject.login 进行登录,包括记住我自动登录
的也属于未进行身份验证。
principal 标签 显示用户身份信息,默认调用 Subject.getPrincipal()获取,即 Primary Principal。
hasRole 标签 如果当前 Subject 有角色将显示 body 体内容。
lacksRole 标签 如果当前 Subject 没有角色将显示 body 体内容。
hasAnyRoles 标签 如果当前 Subject 有任意一个角色(或的关系)将显示 body 体内容。
hasPermission 标签 如果当前 Subject 有权限将显示 body 体内容。
lacksPermission 标签 如果当前 Subject 没有权限将显示 body 体内容。

登录成功ok.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>欢迎您</h1>


	<shiro:hasRole name="admin">
       admin角色用户 <shiro:principal/>
   </shiro:hasRole>

	<shiro:hasPermission name="student:create">
      student:create权限的用户  <shiro:principal/>
    </shiro:hasPermission>
    
    
</body>

mike用户登录

jack用户登录





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在shiro集成jwt中设置白名单,可以使用shiro的过滤器链进行配置。具体来说,可以在shiro的配置文件中添加一个自定义的过滤器,在该过滤器中实现对白名单的处理。以下是一个简单的示例: ```java public class JwtFilter extends AuthenticatingFilter { private List<String> whiteList; public JwtFilter(List<String> whiteList) { this.whiteList = whiteList; } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { HttpServletRequest httpRequest = (HttpServletRequest) request; String path = httpRequest.getServletPath(); return whiteList.contains(path); } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { // 处理未授权访问 } @Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { // 创建JwtToken } } ``` 在上面的示例中,JwtFilter继承自AuthenticatingFilter,实现了isAccessAllowed和onAccessDenied方法。isAccessAllowed方法用于判断当前请求是否在白名单中,如果在白名单中则直接放行,否则进入下一个过滤器。onAccessDenied方法则处理未授权访问的情况。 在shiro的配置文件中,可以将JwtFilter添加到过滤器链中,同时配置白名单: ```xml <bean id="jwtFilter" class="com.example.JwtFilter"> <constructor-arg> <list> <value>/login</value> <value>/register</value> </list> </constructor-arg> </bean> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- ... --> <property name="filters"> <map> <entry key="jwt" value-ref="jwtFilter"/> </map> </property> <property name="filterChainDefinitions"> <value> /login = anon /register = anon /** = jwt </value> </property> <!-- ... --> </bean> ``` 在上面的配置中,JwtFilter被添加到了过滤器链中,并且配置了白名单。具体来说,/login和/register被配置为匿名访问,其他请求则需要经过JwtFilter进行认证和授权

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值