Shiro认证框架整合配置

  • A+
所属分类:Java Java框架

Shiro认证框架整合配置

1.导入坐标

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-all</artifactId>
  <version>1.2.3</version>
</dependency>

2.web.xml中关于shiro的配置

<!--spring核心监听器,默认加载WEB-INF目录下的applicationContext.xml-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/applicationContext*.xml</param-value>
    </context-param>

    <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>

3.applicationContext-shiro.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:p="http://www.springframework.org/schema/p"
   xmlns:context="http://www.springframework.org/schema/context" 
   xmlns:tx="http://www.springframework.org/schema/tx"
   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/aop    
   http://www.springframework.org/schema/aop/spring-aop.xsd    
   http://www.springframework.org/schema/tx    
   http://www.springframework.org/schema/tx/spring-tx.xsd    
   http://www.springframework.org/schema/context    
   http://www.springframework.org/schema/context/spring-context.xsd">

   <!-- 配置Spring整合shiro -->
   <!-- 配置安全管理器 -->
   <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
      <!-- 自己编写一个realm域对象 -->
      <property name="realm" ref="authRealm"/>
   </bean>

   <!-- 编写realm类 -->
   <bean id="authRealm" class="com.gyhqq.shiro.AuthRealm">
      <!-- 注入密码比较器对象 -->
      <property name="credentialsMatcher" ref="passwordMatcher"/>
   </bean>

   <!-- 密码比较器类 -->
   <bean id="passwordMatcher" class="com.gyhqq.shiro.PasswordMatcher"/>

   <!-- Spring框架需要整合shiro安全框架 -->
   <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
      <!-- 注入安全管理器 -->
      <property name="securityManager" ref="securityManager"/>
      <!-- 登录页面 -->
      <property name="loginUrl" value="/login.jsp"/>
      <!-- 认证成功了,跳转的页面
      <property name="successUrl" value=""/>
      -->
      <!-- 没有权限的跳转页面 -->
      <property name="unauthorizedUrl" value="/403.jsp"/>
      <!-- 定义访问的规则 -->
      <property name="filterChainDefinitions">
            <!-- /**代表下面的多级目录也过滤 -->
            <value>
            /*.jsp* = anon
            /login* = anon
            /logout* = anon
            /img/** = anon
            /css/** = anon
            /page/** = anon
            /plugins/** = anon
            /** = authc   
            /*.* = authc
            </value>
        </property>
   </bean>
   
   <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 生成代理,通过代理进行控制 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"/>
    </bean>
    
    <!-- 安全管理器 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
   
</beans>

4.编写自定义认证类

package com.gyhqq.shiro;

import com.gyhqq.dao.ISysUserDao;
import com.gyhqq.domain.SysUser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private ISysUserDao userDao;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("==授权==");
        //此处获取用户的角色信息,封装给shiro框架
        return null;
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        System.out.println("=认证=");
        UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
        // 获取到用户名
        String username = upToken.getUsername();

        // 通过用户名查询数据
        SysUser sysUser = userDao.findUserByName(username);
        System.out.println("登录用户"+sysUser);
        if(sysUser != null){
            // 获取到该用户,构造方法,第二个参数表示密码,第三个参数随便定义字符串的名称,为了区别realm用
            AuthenticationInfo info = new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), this.getName());
            return info;
        }
        return null;
    }
}

5.自定义密码比较器

package com.gyhqq.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordMatcher extends SimpleCredentialsMatcher {
    /**
     * 用于进行密码比较的
     * token -- 表示从页面传过来的用户名和密码
     * info     -- 表示从数据库中查询到的密码
     */
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        // 把token向下强转成实现类
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        // 获取密码
        String inputPwd = new String(upToken.getPassword());

        String password = new Md5Hash(inputPwd,upToken.getUsername(),2).toString();
        // 获取到数据库中的密码
        String dbPwd = info.getCredentials().toString();

        System.out.println("数据库密码"+dbPwd);
        System.out.println("界面输入密码"+password);

        return super.equals(password, dbPwd);
    }
}

6.进入页面后调用login方法通过subject调用shiro的认证方法

package com.gyhqq.controller;

import com.gyhqq.domain.SysUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {

    @RequestMapping("/login")
    public String login(String username,String password){
        try {
            //1.得到subject对象
            Subject subject = SecurityUtils.getSubject();
            //2.封装用户数据
            AuthenticationToken token = new UsernamePasswordToken(username,password);
            //3.实现登录操作
            subject.login(token);
            //4.登录成功后,可以从shiro取出用户信息
            SysUser user = (SysUser) subject.getPrincipal();

            return "main";
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return "redirect:/login.jsp";
        }

    }

    //退出
    public String logout(){
        SecurityUtils.getSubject().logout();
        return "logout";
    }
}

最后注意在service的方法上添加@RequiresPermissions(value="部门管理"),controller不能加的原因是springmvc和spring是两个容器。

  • 资源分享QQ群
  • weinxin
  • 官方微信公众号
  • weinxin
沙海
C语言项目源码分享
TripodCloud:性价比最高的CN2 GIA服务器
Linux服务器网站环境安装
C语言郝斌老师教程

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: