Shiro安全框架学习(四) —— shiro集成到WEB中

web.xml文件

 修改web.xml,在里面加了个过滤器。 这个过滤器的作用,

简单的说,就是 替换掉Shiro 入门里的TestShiro 这部分的工作,下面的代码就可以省掉了。

//加载配置文件,并获取工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

//获取安全管理者实例
SecurityManager sm = factory.getInstance();

//将安全管理者放入全局对象
SecurityUtils.setSecurityManager(sm);
<web-app>
	<listener>
		<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
	</listener>
	
	<!-- 默认先从/WEB-INF/shiro.ini找,如果没有就找classpath:shiro.ini -->
	<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 入门里的TestShiro 构造全局对象的那部分的工作 -->
	<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>

User.java)(Dao.java)(DatabaseRealm.java

 这3个类是与前面的Shiro安全框架学习(二) —— shiro结合数据库进行验证和授权中的一样。


 LoginServlet

 LoginServlet 映射路径/login的访问。
获取账号和密码,然后组成UsernamePasswordToken 对象,仍给Shiro进行判断。 如果判断不报错,即表示成功,客户端跳转到根目录,否则返回login.jsp,并带上错误信息error。
登录成功后还会把subject放在shiro的session对象里在JSP页面中就可以用于:<c:if test="${empty subject.principal}">判断),例如在index.jsp页面中就可以根据subject.principal是否为null值判断显示不同的内容:

备注:有关Shiro中Principal的使用

<!-- 通过 ${subject.principal} 来判断用户是否登录,如果登录过了就显示退出,如果未登录就显示登录按钮 -->
<c:if test="${empty subject.principal}">
    <a href="login.jsp">登录</a><br>
</c:if>
<c:if test="${!empty subject.principal}">
    <span class="desc">你好,${subject.principal},</span>
    <a href="doLogout">退出</a><br>
</c:if>

shiro的这个session和httpsession是串通好了的,所以在这里放了,它会自动放在httpsession里,它们之间是同步的。

package com.how2java;

import java.io.IOException;

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 org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

@WebServlet(name = "loginServlet", urlPatterns = "/login")  
public class LoginServlet extends HttpServlet {  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
      throws ServletException, IOException {  
        String name = req.getParameter("name");  
        String password = req.getParameter("password");  
        Subject subject = SecurityUtils.getSubject();  
        UsernamePasswordToken token = new UsernamePasswordToken(name, password);  
        try {  
            subject.login(token);
            Session session=subject.getSession(); //通过subject获取Session
            session.setAttribute("subject", subject);
            
            resp.sendRedirect("");
        } catch (AuthenticationException e) {  
            req.setAttribute("error", "验证失败");  
            req.getRequestDispatcher("login.jsp").forward(req, resp); 
        }  
    }  
}  

shiro.ini配置

 [main]

  1. 指定了用数据库进行验证和授权判断
  2. 指定了未登录,无角色,无权限分别跳转到哪个页面去

 [users]

  1. users,roles和perms都通过前面知识点的数据库配置了,所以这里是空的

 [urls] 

  1. 用来指定哪些资源需要什么对应的授权才能使用
[main]  
#使用数据库进行验证和授权
databaseRealm=com.how2java.DatabaseRealm
securityManager.realms=$databaseRealm

#当访问需要验证的页面,但是又没有验证的情况下,跳转到login.jsp
authc.loginUrl=/login.jsp
#当访问需要角色的页面,但是又不拥有这个角色的情况下,跳转到noroles.jsp
roles.unauthorizedUrl=/noRoles.jsp
#当访问需要权限的页面,但是又不拥有这个权限的情况下,跳转到noperms.jsp
perms.unauthorizedUrl=/noPerms.jsp

#users,roles和perms都通过前面知识点的数据库配置了
[users]  

#urls用来指定哪些资源需要什么对应的授权才能使用
[urls]  
#doLogout地址就会进行退出行为
/doLogout=logout 
#login.jsp,noroles.jsp,noperms.jsp 可以匿名访问
/login.jsp=anon
/noroles.jsp=anon
/noperms.jsp=anon

#查询所有产品,需要登录后才可以查看
/listProduct.jsp=authc  
#增加商品不仅需要登录,而且要拥有 productManager 权限才可以操作
/deleteProduct.jsp=authc,roles[productManager]  
#删除商品,不仅需要登录,而且要拥有 deleteProduct 权限才可以操作
/deleteOrder.jsp=authc,perms["deleteOrder"]   

anon 和 authc 简介:

anon:  任何用户发送的请求都能够访问

authc:经过认证的请求可访问,否则将会将请求重定向到 ini 配置文件配置的 authc.loginUrl 资源,进行认证操作。


JSP页面

  •  index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 
<link rel="stylesheet" type="text/css" href="static/css/style.css" />
 
</head>
<body>
 
<div class="workingroom">
    <div class="loginDiv">
     
    <c:if test="${empty subject.principal}">
        <a href="login.jsp">登录</a><br>
    </c:if>
    <c:if test="${!empty subject.principal}">
        <span class="desc">你好,${subject.principal},</span>
        <a href="doLogout">退出</a><br>
    </c:if>
         
    <a href="listProduct.jsp">查看产品</a><span class="desc">(登录后才可以查看) </span><br>
    <a href="deleteProduct.jsp">删除产品</a><span  class="desc">(要有产品管理员角色, zhang3没有,li4 有) </span><br>
    <a href="deleteOrder.jsp">删除订单</a><span class="desc">(要有删除订单权限, zhang3有,li4没有) </span><br>
</div>
 
</body>
</html>

注意:

  1. 要引入正确的jstl标签
  2. 通过 ${subject.principal} 来判断用户是否登录,如果登录过了就显示退出,如果未登录就显示登录按钮
  3. 提供3个超链,分别要 登录后才可以查看,有角色才能看,有权限才能看,便于进行测试
  4. 和shiro.ini配置中的[urls]一一对应

  • login.jsp

登陆页面,如果有错误返回会显示错误. 账号密码也写在下面,只是方便输入(数据跟数据库数据一致,方便测试)

<div class="errorInfo">${error}</div>
    <form action="login" method="post">
        账号: <input type="text" name="name"> <br>
        密码: <input type="password" name="password"> <br><br>
        <input type="submit" value="登录"><br><br>
    <div>
        <span class="desc">账号:zhang3 密码:12345 角色:admin</span><br>
        <span class="desc">账号:li4 密码:abcde 角色:productManager</span><br>
    </div>      
    </form>
</div>

  • listProduct.jsp

根据 shiro.ini 里的配置信息:/listProduct.jsp=authc

这个页面要在登录之后才能访问

<div class="workingroom">
    listProduct.jsp ,能进来,就表示已经登录成功了
    <br>
    <a href="#" onClick="javascript:history.back()">返回</a>
</div>

  • deleteOrder.jsp

根据 shiro.ini 里的配置信息:/deleteOrder.jsp=authc,perms["deleteOrder"]
这个页面要在登录之后,并且有权限的前提下才能访问

<div class="workingroom">
    deleteProduct.jsp,能进来<br>就表示拥有 productManager 角色<br>
    <a href="#" onClick="javascript:history.back()">返回</a>
</div>

  • noRoles.jsp

根据 shiro.ini 里的配置信息:roles.unauthorizedUrl=/noRoles.jsp
当没有角色的时候,就会跳转到这里来

<div class="workingroom">
    角色不匹配<br>
    <a href="#" onClick="javascript:history.back()">返回</a>
</div>

  • noPerms.jsp

根据 shiro.ini 里的配置信息:perms.unauthorizedUrl=/noPerms.jsp
当没有权限的时候,就会跳转到这里来

 <div class="workingroom">
    权限不足<br>
    <a href="#" onClick="javascript:history.back()">返回</a>
</div>

来源于:

http://how2j.cn/k/shiro/shiro-web/1722.html#nowhere

猜你喜欢

转载自blog.csdn.net/weixin_41888813/article/details/81383592
今日推荐