shiro+SSM的一个简单例子

1、 首先搭建spring+springMVC+MyBatis的配置
1.1、数据库的连接配置(jdbc.properties):

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://ip/instance?;useUnicode=true;characterEncoding=UTF-8;autoReconnect=true
username=root
password=123456
#定义初始连接数
initialSize=0
#定义最大连接数
maxActive=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

1.2、Mybatis(spring-mybatis.xml)的相关配置:

<context:component-scan base-package="com.icinfo" />
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:jdbc.properties" />
</bean>

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      destroy-method="close">
    <property name="driverClassName" value="${driver}" />
    <property name="url" value="${url}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />
    <!-- 初始化连接大小 -->
    <property name="initialSize" value="${initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxActive" value="${maxActive}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="${maxWait}"></property>
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <!-- 自动扫描mapping.xml文件 -->
    <property name="mapperLocations" value="classpath:com/icinfo/mapper/mapping/*Mapper.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.icinfo.mapper" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<!-- 引入shiro的配置文件 -->
<import resource="classpath:spring-shiro-demo.xml"/>

1.3、spring-mvc(spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.1.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <context:component-scan base-package="com.icinfo.controller" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        <context:include-filter type="annotation"
                                expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>

    <!-- 根据路径后缀选择不同视图 -->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="contentNegotiationManager">
            <bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                <property name="mediaTypes">
                    <map>
                        <entry key="json" value="application/json"/>
                        <entry key="xml" value="application/xml"/>
                        <entry key="html" value="text/html"/>
                    </map>
                </property>
                <property name="defaultContentType" value="text/html"/>
                <!-- 忽略Accept Header-->
                <property name="ignoreAcceptHeader" value="true"/>
                <!-- 关闭 ?format=json的支持 -->
                <property name="favorParameter" value="false"/>
                <!-- 开启扩展名支持 -->
                <property name="favorPathExtension" value="true"/>
            </bean>
        </property>
        <property name="viewResolvers">
            <list>
                <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                    <property name="viewClass"
                              value="org.springframework.web.servlet.view.JstlView"/>
                    <property name="contentType" value="text/html"/>
                    <property name="prefix" value="/WEB-INF/views/page/"/>
                    <property name="suffix" value=".jsp"/>
                </bean>
            </list>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                    <property name="prettyPrint" value="false"/>
                </bean>
                <bean class="org.springframework.web.servlet.view.xml.MappingJackson2XmlView"/>
            </list>
        </property>
    </bean>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>
    <mvc:resources mapping="/js/**" location="/WEB-INF/views/js/" cache-period="1296000"/>
</beans>

1.4、shiro(spring-shiro-demo.xml)的配置

    <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.xsd">
     <!-- 配置/** = anon 是为了防止js和css的路径被拦截 -->   
     <bean id="filterChainDefinitions" class="java.lang.String">
                <constructor-arg>
                    <value>
                        /index/goLogin = anon
                        /index/login = anon
                        /index/logout = logout
                        /user/** = authc
                        /** = anon
                    </value>
                </constructor-arg>
            </bean>
        
            <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
                <property name="loginUrl" value="/index/goLogin"/>
                <property name="successUrl" value="/admin"/>
                <property name="unauthorizedUrl" value="/admin/error/unauthorized"/>
                <property name="securityManager" ref="securityManager"/>
                <property name="filterChainDefinitions" ref="filterChainDefinitions" />
                <property name="filters">
            <map>
                <entry key="logout" value-ref="logout">
                </entry>
            </map>
        </property>
            </bean>
   <bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/index/goLogin"/>
    </bean>
        
            <!-- 安全管理器 -->
            <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
                <!--<property name="sessionManager" ref="defaultWebSessionManager"/>-->
                <property name="realm" ref="securityAuthorizingRealm"/>
            </bean>
        
            <!-- 自定义的Realm -->
            <bean id="securityAuthorizingRealm" class="com.icinfo.relam.MyShiroRealm">
                <property name="userService" ref="userService"/>
            </bean>
        
            <!-- 会话验证调度器 -->
            <!--<bean id="sessionValidationScheduler" class="com.icinfo.framework.security.shiro.quartz.QuartzSessionValidationScheduler">-->
                <!--<property name="sessionValidationInterval" value="1800000"/>-->
                <!--<property name="sessionManager" ref="defaultWebSessionManager"/>-->
            <!--</bean>-->
        
            <!--<bean id="defaultWebSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">-->
                <!--<property name="globalSessionTimeout" value="1800000"/>-->
                <!--<property name="deleteInvalidSessions" value="true"/>-->
                <!--<property name="sessionValidationSchedulerEnabled" value="true"/>-->
                <!--<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>-->
                <!--<property name="sessionIdCookie.name" value="_hm_cid"/>-->
                <!--<property name="sessionListeners">-->
                    <!--<list>-->
                        <!--<bean class="com.icinfo.framework.core.web.listener.CsrfTokenListener"/>-->
                    <!--</list>-->
                <!--</property>-->
            <!--</bean>-->
            <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
        </beans>

1.5、编写自己的Realm,继承AuthorizingRealm,重写doGetAuthorizationInfo和doGetAuthenticationInfo方法,当我们在登录方法中调用SecurityUtils.getSubject().login(token)时会间接调用我们指定Realm的doGetAuthenticationInfo方法来验证用户信息。
在这里插入图片描述
代码块:

package com.icinfo.relam;
import com.icinfo.model.User;
import com.icinfo.service.UserService;
import org.apache.commons.lang3.StringUtils;
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 java.util.List;

/**
 * @author fz
 * @create 2019-01-08 下午 4:41
 */
public class MyShiroRealm extends AuthorizingRealm {

    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        return null;
    }

    /**
     * 获取验证信息
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        if(StringUtils.isBlank(usernamePasswordToken.getUsername())){
            return null;
        }
        /**
         * 下面可以写自己的验证逻辑(因为是测试用例,简单验证下)
         */
        User user = userService.findUserByUsername(usernamePasswordToken.getUsername());
        if(user == null){
            throw new AuthenticationException("用户信息认证失败");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(usernamePasswordToken.getUsername(), user.getPassword(), getName());
        return info;
    }

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

1.6、web.xml需要添加的配置

   <filter>
    <!-- 名称需要和spring-shiro-demo.xml中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>

1.7、(IndexController)

package com.icinfo.controller;

import com.icinfo.dto.LoginDto;
import com.icinfo.framework.common.ajax.AjaxResult;
import com.icinfo.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author fz
 * @create 2019-01-17 下午 5:46
 */
@Controller
@RequestMapping("/index")
public class IndexController {

    @Autowired
    UserService userService;
    Logger logger = LoggerFactory.getLogger(IndexController.class);

    @RequestMapping("/goLogin")
    public ModelAndView goLogin(){
        System.out.println("---------------访问主页面----------------");
        ModelAndView mav = new ModelAndView("login");
        return mav;
    }

    @RequestMapping("/login")
    @ResponseBody
    public AjaxResult login(HttpServletRequest request, HttpServletResponse response, LoginDto loginDto) throws Exception{

        if(loginDto == null || StringUtils.isBlank(loginDto.getUsername()) || StringUtils.isBlank(loginDto.getPassword())){
            return AjaxResult.error("用户名或密码不能为空");
        }
        UsernamePasswordToken token = new UsernamePasswordToken(loginDto.getUsername(),loginDto.getPassword().toCharArray());
        Subject subject = SecurityUtils.getSubject();
        try{
            subject.login(token);
        }catch (Exception e){
            logger.info("登录失败,失败原因:[{}]", e.getMessage());
            e.printStackTrace();
            return AjaxResult.error("登录失败,请检查用户名和密码是否正确!");
        }
        return AjaxResult.success("success");
    }

    /**
     * 首页
     * @return
     * @throws Exception
     */
    @RequestMapping
    public ModelAndView index() throws Exception{
        ModelAndView mav = new ModelAndView("index");
        return mav;
    }

    /**
     * 登出
     * @return
     * @throws Exception
     */
    @RequestMapping("logout")
    public String logout() throws Exception{
        Subject subject = SecurityUtils.getSubject();
        if(subject.isAuthenticated()){
            subject.logout();
        }
        return "redirect:/index/goLogin";
    }
}

1.8、(UserController)

package com.icinfo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * 用户控制器
 *
 * @author fz
 * @create 2019-01-28 上午 10:58
 */
@RequestMapping("/user")
@Controller
public class UserController {

    @RequestMapping("/userAddPage")
    public ModelAndView userAddPage() throws Exception{

        ModelAndView mav = new ModelAndView("user_add");
        return mav;
    }
}

2、前台简单页面测试
2.1、登录页面(login.jsp)

 <%@ page contentType="text/html;charset=UTF-8" trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html>
<head>
    <title>登录页面</title>
</head>
<body>
<form id="form">
    用户名:<input type="input" name="username" id="username"/>
    密  码:<input type="input" name="password" id="password"/>
    <input type="button" value="登录" id="submit"/>
</form>
</body>
<script src="/js/lib/jquery-1.12.3.min.js"></script>
<script src="/js/lib/jquery.serialize-object.min.js"></script>
<script src="/js/login.js"></script>
</html>

2.2、login.js

$(function () {
    $("#submit").click(function () {
        $.ajax({
            url:'/index/login',
            type:'post',
            dataType: 'json',
            data:$("#form").serializeObject(),
            success: function (json) {
                console.log(json);
                if(json.status=="success"){
                    window.location.href = '/index';
                }else{
                    alert(json.msg);
                }
            }
        })
    })
})

2.3、index.jsp

<%@ page contentType="text/html;charset=UTF-8" trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html>
<head>
    <title>首页</title>
</head>
<body>
<div>
    登录成功。
</div>
</body>
<script src="/js/lib/jquery-1.12.3.min.js"></script>
<script src="/js/lib/jquery.serialize-object.min.js"></script> 
</html>

2.4、user_add.jsp

<%@ page contentType="text/html;charset=UTF-8" trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html>
<head>
    <title>首页</title>
</head>
<body>
<div>
    <h1>添加用户页面</h1>
</div>
</body>
<script src="/js/lib/jquery-1.12.3.min.js"></script>
<script src="/js/lib/jquery.serialize-object.min.js"></script>
</html>

2.5、用户表的表结构
在这里插入图片描述

3、测试阶段
3.1、验证未登录情况下跳转到login.jsp
3.1.1、输入新增用户页面地址
在这里插入图片描述
3.1.2、跳转到用户登录页面
在这里插入图片描述
3.1.3、输入错误的用户名密码
在这里插入图片描述
3.1.4、提示用户名或密码错误
在这里插入图片描述
3.1.5、输入正确的用户名和密码
在这里插入图片描述
3.1.6、登录成功,跳转到首页
在这里插入图片描述
3.1.7 这时可以打开新增用户页面
在这里插入图片描述
到这一个简单的用户登录的例子就做完了,作者水平有限,写的不对的地方请留言,轻喷!!!!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值