SSM + jsp整合shiro

1.首先整合SSM框架,起码项目要能跑起来

以前整合好的ssm框架
springmvc-config.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 注解驱动 -->
    <mvc:annotation-driven/>
    <!-- 静态资源路径 -->
    <mvc:default-servlet-handler/>
    <!-- 扫描controller包 -->
    <context:component-scan base-package="com.kuang.controller"/>

    <!-- 视图解析器 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

spring-dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 导入本地jdbc配置 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- DataSource:使用spring数据源替换mybatis的配置 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 配置数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置mybatis配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 自动扫描Mapper -->
        <property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/>
    </bean>

    <!-- 自动生成userMapper实现类 -->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.kuang.mapper"/>
    </bean>
</beans>

spring-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 扫描service包 -->
    <context:component-scan base-package="com.kuang.service"/>

    <import resource="classpath:spring-dao.xml"/>

    <!-- 声明式事务 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>


</beans>

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <import resource="classpath:springmvc-config.xml"/>
    <import resource="classpath:spring-dao.xml"/>
    <import resource="classpath:spring-service.xml"/>

</beans>

jdbc.properties

jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/student?characterEncoding=utf8
jdbc.username = root
jdbc.password = 1511

2.新建spring-shiro配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		"
       default-lazy-init="true">

    <!--1. 配置securityManager安全管理器 -->
    <!--
    	SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;
		且它管理着所有Subject;可以看出它是Shiro 的核心,它负责与后边介绍的其他组件进行交互
     -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="shiroDbRealm" />
    </bean>

    <!--2. 配置 CacheManager. 2.1需要加入 ehcache 的 jar 包及配置文件. -->
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"> </bean>

    <!--3.配置realm 自定义的Realm-->
    <!--
    	Shiro 从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,
    	那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;
		也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;
		可以把Realm看成DataSource , 即安全数据源
	-->
    <bean id="shiroDbRealm" class="com.kuang.auth.realm.UserRealm"></bean>

    <!--4.配置lifecycleBeanPostProcessor,可以自动调用spring ioc 容器中的shiro bean 的生命周期方法  -->
    <!-- 开启Shiro注解的Spring配置方式的beans。在lifecycleBeanPostProcessor之后运行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

    <!--5. 启用 IOC 容器中使用 shiro 的注解. 但必须在配置了 LifecycleBeanPostProcessor 之后才可以使用. -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true" />
    </bean>

    <!-- Shiro Filter id值和web.xml文件配置的过滤器名称相同 -->
    <bean id="shiroFilter"
          class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!-- 登录页面 -->
        <!--<property name="loginUrl" value="/login.jsp" />-->
        <!-- 登录成功页面 已经在登录Controller中配置 所以这里就注释了-->
        <!--<property name="successUrl" value="/WEB-INF/views/home.jsp"/>-->
        <!-- 没有权限的页面 -->
        <property name="unauthorizedUrl" value="/user/error"/>
        <!--
          配置哪些页面需要受保护.
          以及访问这些页面需要的权限.
          1). anon 可以被匿名访问
          2). authc 必须认证(即登录)后才可能访问的页面.
          3). logout 登出.
          4). roles 角色过滤器
      -->
        <property name="filterChainDefinitions">
            <value>
                <!-- 登录可匿名访问 -->
                <!-- 注意:路径的匹配顺序从上往下,返回第一个匹配到的配置
                比如当把   /** = authc 放在最上面,
                        那无论下面配置了什么路径 都需要认证,

                 -->
                /index = anon
                / = anon
                /user/login = anon
                <!-- 其他的需要授权访问authc -->
                /user/add = perms[user:add]
                /user/update = perms[user:update]
                <!-- logout只需在这里配置一个路径即可完成注销功能,即使控制器没有写 -->
                /logout = logout
                /** = authc
            </value>
        </property>
    </bean>


    <!-- 开启Shiro注解的Spring配置方式的beans。在lifecycleBeanPostProcessor之后运行 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

    <!-- shiro为集成spring -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!-- 无权限跳转到登陆页,可自行定义 -->
                <prop key="org.apache.shiro.authz.UnauthorizedException">error/error</prop>
            </props>
        </property>
    </bean>
</beans>

application.xml配置文件中也要导入

<import resource="classpath:spring-shiro.xml"/>

3.web.xml中页面添加shiro

<!-- shiro 安全过滤器 -->
<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>

web.xml完整代码

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:spring-config.xml
            classpath:spring-shiro.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- 配置过滤器 -->
<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>

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


<!-- shiro 安全过滤器 -->
<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>



</web-app>

4.创建UserRealm类,并继承AuthorizingRealm类

package com.kuang.auth.realm;

import com.kuang.pojo.User;
import com.kuang.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;

//UserRealm继承AuthorizingRealm类
public class UserRealm extends AuthorizingRealm{

    @Autowired
    private UserService userMapper;

    /**
     * 授权
     *      在这里可以配置权限方面的信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        //获取getPrincipal里存储的信息
        User user = (User) subject.getPrincipal();

        //添加权限(Collection权限集合)
        info.addStringPermissions(Arrays.asList(user.getPerms().split(",")));

        //添加角色(Collection权限集合)
        //info.addRoles();

        return info;
    }

    /**
     * 认证
     *      在这里可以将用户传进来的数据与数据库的用户名密码进行匹配
     *      还能存储正确的User对象(principal)
     *      new SimpleAuthenticationInfo(user(principal), user.getPassword(), user.getUsername());
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        String username = usernamePasswordToken.getUsername();

        String password = String.valueOf(usernamePasswordToken.getPassword());

        User user = userMapper.findByUsername(username);

        if(user == null) {
            throw new AccountException("账号或密码错误");
        }
        if(!password.equals(user.getPassword())){
            throw new AccountException("账号或密码错误");
        }

        SecurityUtils.getSubject().getSession().setAttribute("userInfo",user);

        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                user, user.getPassword(), user.getUsername());
        return simpleAuthenticationInfo;
    }

}

5.编写主页,登录等jsp页面

建好的页面,除了基本功能什么都没有
在这里插入图片描述

6.jsp中引入shiro标签,并使用

想要在jsp页面使用shiro标签必须导入标签库
<%@taglib prefix=“shiro” uri=“http://shiro.apache.org/tags” %>


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 导入shiro + Jsp整合权限控制 --%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
  <title>主页</title>
</head>

<%--<c:if test="${pageContext.session.getAttribute('userInfo')}">
  <a href="${pageContext.request.contextPath}/user/logout">注销</a>
</c:if>--%>
<%-- 判断是否已认证 --%>
<shiro:authenticated>
  <%-- 取出储存的user对象中的username --%>
  <shiro:principal property="username">
      <h3>欢迎回来 <a href="#">${username}</a></h3>
  </shiro:principal>

  <a href="${pageContext.request.contextPath}/logout">注销</a>
</shiro:authenticated>

<%-- 判断是否没有认证 --%>
<shiro:notAuthenticated>
    <a href="${pageContext.request.contextPath}/user/toLogin">登录</a>
</shiro:notAuthenticated>

<hr>

<%-- 判断是否拥有某个权限 --%>
<shiro:hasPermission name="user:add">
<a href="${pageContext.request.contextPath}/user/add">add</a>
</shiro:hasPermission>

<shiro:hasPermission name="user:update">
<a href="${pageContext.request.contextPath}/user/update">update</a>
</shiro:hasPermission>
</body>
</html>

7.测试shiro是否正常使用

主页,只显示当前用户拥有的权限,未登录当然什么都没有
在这里插入图片描述
登录页面
在这里插入图片描述

登录成功后显示当前权限

在这里插入图片描述

上图显示admin用户只拥有add权限,即使输入update也无法访问

在这里插入图片描述
测试成功

注:配上shiro jsp页面使用标签说明

下面来讲解具体的标签用法。

1.guest(游客)

 
  1. <shiro:guest>
  2. 您当前是游客,<a href="javascript:void(0);" class="dropdown-toggle qqlogin" >登录</a>
  3. </shiro:guest>

2.user(已经登录,或者记住我登录)

 
  1. <shiro:user>
  2. 欢迎[<shiro:principal/>]登录,<a href="/logout.shtml">退出</a>
  3. </shiro:user>

3.authenticated(已经认证,排除记住我登录的)

 
  1. <shiro:authenticated>
  2. 用户[<shiro:principal/>]已身份验证通过
  3. </shiro:authenticated>

4.notAuthenticated(和authenticated相反)

 
  1. <shiro:notAuthenticated>
  2. 当前身份未认证(包括记住我登录的)
  3. </shiro:notAuthenticated>

这个功能主要用途,识别是不是本次操作登录过的,比如支付系统,进入系统可以用记住我的登录信息,但是当要关键操作的时候,需要进行认证识别。

5.principal标签,这个要稍微重点讲讲。好多博客都是一下带过。

principal 标签,取值取的是你登录的时候。在Realm 实现类中的如下代码:

 
  1. ....
  2. return new SimpleAuthenticationInfo(user,user.getPswd(), getName());

new SimpleAuthenticationInfo(第一个参数,....) 的第一个参数放的如果是一个username ,那么就可以直接用。

 
  1. <!--取到username-->
  2. <shiro: principal/>

如果第一个参数放的是对象,比如我喜欢放User 对象。那么如果要取username 字段。

 
  1. <!--需要指定property-->
  2. <shiro:principal property="username"/>

和下面 Java  代码一致

 
  1. User user = (User)SecurityUtils.getSubject().getPrincipals();
  2. String username = user.getUsername();

6.hasRole标签(判断是否拥有这个角色)

 
  1. <shiro:hasRole name="admin">
  2. 用户[<shiro:principal/>]拥有角色admin<br/>
  3. </shiro:hasRole>

7.hasAnyRoles标签(判断是否拥有这些角色的其中一个)

 
  1. <shiro:hasAnyRoles name="admin,user,member">
  2. 用户[<shiro:principal/>]拥有角色admin或user或member<br/>
  3. </shiro:hasAnyRoles>

8.lacksRole标签(判断是否不拥有这个角色)

 
  1. <shiro:lacksRole name="admin">
  2. 用户[<shiro:principal/>]不拥有admin角色
  3. </shiro:lacksRole>

9.hasPermission标签(判断是否有拥有这个权限)

 
  1. <shiro:hasPermission name="user:add">
  2. 用户[<shiro:principal/>]拥有user:add权限
  3. </shiro:hasPermission>

10.lacksPermission标签(判断是否没有这个权限)

 
  1. <shiro:lacksPermission name="user:add">
  2. 用户[<shiro:principal/>]不拥有user:add权限
  3. </shiro:lacksPermission>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值