Shiro在SSM框架中的应用

Posted ssskkk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shiro在SSM框架中的应用相关的知识,希望对你有一定的参考价值。

上一篇Shiro基础的连接 

 如果想使用Relam的操作,那么必须要保证有一个具体的认证类实现了Relam接口

  • web.xml增加shiro的配置
<!-- 此配置描述的是在项目开发过程之中,Spring容器所需要使用到的配置文件 -->
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

   <!-- 进行shiro的过滤器的配置 -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <!-- 该参数表示shiro的生命周期将交由Spring容器进行管理(默认情况下,取值为false) -->
        <!-- 如果将其内容设置为true,则表示由Servlet容器进行管理 -->
        <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>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
  • 在applicationContext.xml假如shiro配置项信息

    配置shiro的登录入口

    <!-- 此处表示使用内置的表单登录控制验证 -->
    <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
        <!-- 定义出需要使用的参数,此参数与表单一一对应 -->
        <property name="usernameParam" value="mid"/>
        <property name="passwordParam" value="password"/>
        <property name="loginUrl" value="/loginUrl.action"/> <!-- 登录的请求url-->
    </bean>

    配置Shiro过滤器

    <!-- 配置shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 表示现在要配置的是一个安全管理器 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 出现错误之后的跳转路径的配置 -->
        <property name="loginUrl" value="/loginUrl.action"/>
        <!-- 认证失败之后的跳转路径页面 -->
        <property name="unauthorizedUrl" value="/unauthUrl.action"/>
        <!-- 登录成功之后的跳转访问路径 -->
        <property name="successUrl" value="/successUrl.action"/>
        <!-- 配置shiro里面需要使用到的过滤器操作 -->
        <property name="filters">
            <map>
                <entry key="authc" value-ref="formAuthenticationFilter"/>
            </map>
        </property> 
        <!-- shiro里面需要针对于所有的路径进行配置,所有的配置需要通过文本的形式设置 -->
        <property name="filterChainDefinitions">
            <value>
                /loginUrl.action=authc
                /pages/welcome.jsp=authc
            </value>
        </property>
    </bean> 
<!-- 配置Shiro在Spring中的生命周期的控制操作 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
  配置SecurityManager管理器
 <!-- 配置SecurityManager的管理 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 配置你需要使用的Realms -->
        <property name="realm" ref="memberRealm"/>
    </bean>

  编写memberRealm进行认证授权


package com.sun.realm;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
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.springframework.stereotype.Component;

import com.sun.service.IMemberService;
import com.sun.vo.Member;
@Component
public class MemberRealm extends AuthorizingRealm {
    @Resource
    private IMemberService memberService ;
    @SuppressWarnings("unchecked")
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("********** 2、用户角色与权限:doGetAuthorizationInfo **********");
        String username = (String) principals.getPrimaryPrincipal() ;    // 取得用户登录名
        SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo() ;    // 定义授权信息的返回数据
        try {
            Map<String,Object> map = this.memberService.listAuthByMember(username) ;
            Set<String> allRoles = (Set<String>) map.get("allRoles") ;
            Set<String> allActions = (Set<String>) map.get("allActions") ;
            auth.setRoles(allRoles);// 所有的角色必须以Set集合的形式出现
            auth.setStringPermissions(allActions);     // 所有的权限必须以Set集合的形式出现
        } catch (Exception e) {
            e.printStackTrace(); 
        } 
        return auth;
    } 
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("********** 1、用户登录认证:doGetAuthenticationInfo() **********");
        // 1、登录认证的方法需要先执行,需要用他来判断登录的用户信息是否合法
        String username = (String) token.getPrincipal() ;    // 取得用户名
        // 需要通过用户名取得用户的完整信息,利用业务层操作
        Member vo = null ;
        try {
            vo = this.memberService.get(username) ;
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (vo == null) {
            throw new UnknownAccountException("该用户名称不存在!") ;
        } else {    // 进行密码的验证处理
            String password = new String((char []) token.getCredentials()) ;
            // 将数据库中的密码与输入的密码进行比较,这样就可以确定当前用户是否可以正常登录
            if (vo.getPassword().equals(password)) {    // 密码正确
                AuthenticationInfo auth = new SimpleAuthenticationInfo(username, password, "memberRealm") ;
                return auth ;
            } else {
                throw new IncorrectCredentialsException("密码错误!") ;
            }
        }
    } 
}


这是首页登录的jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"//"+request.getServerName()+":"+request.getServerPort();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%-- <base href="<%=basePath %>"> --%>
<%System.out.println("---"+basePath); %>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Shiro</title>
</head>
<body>
    <form action="http://127.0.0.1:8080/shiroLogin" method = "post">
    用户名<input type="text" name = "mid" id = "mid"><br>
    密码 <input type="password" name = "password" id = "password"><br>
    <input type="submit" value="登录">
    <input type="reset" value="重置">
    </form>
</body>
</html>

这是登录跳转的Controller

package com.sun.action;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MemberLoginAction {
    @RequestMapping("/successUrl")
    public ModelAndView successUrl() {
        return new ModelAndView("welcome");
    }
}

 shiro登录的流程

从jsp的action找到配置的formAuthenticationFilter

然后登录的路径被shiroFilter过滤

shiroFilter交给配置的securityManager去管理

securityManager又交给配置的memberRealm去授权和认证

登录成功之后的跳转访问路径 

<property name="successUrl" value="/successUrl.action"/>

下一篇会写在集群环境下Shiro的Session管理,并上传相应的源代码(未完待续)



以上是关于Shiro在SSM框架中的应用的主要内容,如果未能解决你的问题,请参考以下文章

java SSM框架 代码生成器 websocket即时通讯 shiro redis 后台框架源码

java SSM框架 代码生成器 websocket即时通讯 shiro redis 后台框架源码

java SSM框架 代码生成器 websocket即时通讯 shiro redis 后台框架源码

java SSM框架 websocket即时通讯 代码生成器 shiro redis 后台框架源码

SSM框架 多数据源 代码生成器 websocket即时通讯 shiro redis 后台框架源码

shiro权限控制:shiro介绍以及整合SSM框架