Shiro学习记录


Shiro主要功能:身份验证;授权;会话管理;密码 IDEA中 ctrl+ alt+ v可自动生成对应变量及对应的数据类型 IDEA中 ctrl+ alt+ t可自动提示一些可用的,例如try catch,if else等

1.介绍

导包一定是:import org.apache.shiro或其之下更进一步详细的包,不要导成别的包,例如java.lang的,否则会报错

初始项目:实现登陆判断(身份验证):以下代码均在main方法中

//假设路径中能够获得用户名和密码
Factory<SecurityManager> factory = new IniSecurityManagerFactory("路径");
SecurityManager securityManager = factory.getInstance();
//当前用户:Subject————>SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
//当前用户
Subject user = SecurityUtils.getSubject();
//通过UsernamePasswordToken来模拟html/jsp传递过来的用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken("用户名","密码");
//通过shiro判断用户是否登录成功
//login是void类型方法,通过抛出异常来判断
try{
	user.login(token);//login是shiro自带的
	System.out.println("登陆成功");
}catch(AuthenticationException e){
	System.out.println("登陆失败");
}

2.jdbcRealm工具类(身份验证)

通过数据库实现登陆判断(身份验证):
java的main方法中:

//假设路径中能够获得用户名和密码
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_shiro.ini");
SecurityManager securityManager = factory.getInstance();
//当前用户:Subject————>SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
//当前用户
Subject user = SecurityUtils.getSubject();
//通过UsernamePasswordToken来模拟html/jsp传递过来的用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken("用户名","密码");
//通过shiro判断用户是否登录成功
//login是void类型方法,通过抛出异常来判断
try{
	user.login(token);//login是shiro自带的
	System.out.println("登陆成功");
}catch(AuthenticationException e){
	System.out.println("登陆失败");
}

jdbc_shiro.ini(在resources目录下)文件中:

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm

//数据库c3p0连接池
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/news?useUnicode=true&characterEncoding=utf-8
dataSource.user="rout"
dataSource.password="123456"

jdbcRealm.dataSource=$dataSource
securityManager.realm=$jdbcRealm

在这里插入图片描述

3.SSM整合(认证加授权)

3.1.pom.xml文件添加相关依赖

    <!-- shiro  -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.3.2</version>
    </dependency>

3.2.web.xml文件添加过滤器

  <!-- shiro过滤器 -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

3.3.jsp文件添加说明

<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

配合

<shiro:guest><!--未认证时就显示-->
		登录
</shiro:guest>
<shiro:authenticated><!--认证后才显示-->
		退出登录
</shiro:authenticated>

使用

3.3.applicationContext.xml文件添加控制

    <bean id="myRealm" class="com.shiro.myRealm" />
        <!--配置安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--关联一个认证授权域-->
        <property name="realm" ref="myRealm"/>
    </bean>
        <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="/pages/homepage.jsp"/>
        <!--未授权-->
        <property name="unauthorizedUrl" value="/pages/403.jsp"/>
        <!--过滤器规则-->
        <property name="filterChainDefinitions">
            <value>
                /index.jsp = anon  <!--匿名-->
                /readerpost.jsp = anon
                /login.jsp = anon
                /pages/** = authc<!--必须认证-->
            </value>
        </property>
    </bean>

3.4.修改Controller层中login()内代码

    @RequestMapping("/login.do")
    @ResponseBody
    public String login(String userid, String password, HttpSession session){
        //得到一个主题对象
        Subject subject = SecurityUtils.getSubject();
        //创建一个token
        UsernamePasswordToken token = new UsernamePasswordToken(userid,password);
        try{
            //传令牌
            subject.login(token);
            if(subject.isAuthenticated()){
                int id=Integer.parseInt(userid);
                Admin admin= new Admin();
                admin=adminService.findAdminByAdminId(id);
                session.setAttribute("adminid",admin.getId());
                Gson json=new Gson();
                String str=json.toJson(admin);// 传入Bean类型
                System.out.println(str);
                return str;
            }else{
                return null;
            }
        }catch (AuthenticationException ex){
            return null;
        }
    }

在这里插入图片描述
主要是画框的部分

3.5.在myRealm中

在这里插入图片描述

public class myRealm extends AuthorizingRealm {
    @Autowired
    private AdminService adminService;

    //获取授权信息:进行授权工作
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //获取认证信息:进行认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        char[] password = token.getPassword();
        int id=Integer.parseInt(username);
        boolean admin = adminService.login(id,String.valueOf(password));
        System.out.println(admin);
        System.out.println(username);
        System.out.println(String.valueOf(password));
        if(admin){
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,String.valueOf(password), getName());
            return simpleAuthenticationInfo;
        }
        return null;
    }
}

3.6.在myRealm中添加授权部分

    //获取授权信息:进行授权工作
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String adminid = (String) super.getAvailablePrincipal(principalCollection);
        int id=Integer.parseInt(adminid);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //添加角色
        Role role = adminService.getRoleByAdminId(id);
        info.addRole(role.getRolename());
        //添加权限
        List<String> permissions = adminService.getPermissionsByRoleId(role.getId());
        info.addStringPermissions(permissions);
        return info;
    }

3.7.在applicationContext.xml文件中添加权限设置:

在这里插入图片描述

3.8.出现异常(localhost 重定向次数过多)

在这里插入图片描述
原因: 在配置文件中filter 的配置为:/* 过滤了所有的访问,并且在filter的代码中有设置授权未通过时跳转到pages/403.jsp页面,但又设置了pages下所有页面未经授权无法访问,所以出现了死循环。
解决方法: 将403.jsp页面换个地方:
在这里插入图片描述

3.9.补充:数据库

在这里插入图片描述

4.Shiro框架中常用标签(jsp文件中)

在html标签之前,需要先引用标签库:<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
例如:<shiro:guest>中间可加任意html标签</shiro:guest>

<shiro:authenticated>        登录之后
<shiro:notAuthenticated>        不在登录状态时
<shiro:guest>            用户在没有RememberMe时
<shiro:user>            用户在RememberMe时
<shiro:hasAnyRoles name="abc,123" >    在有abc或者123角色时
<shiro:hasRole name="abc">        拥有角色abc
<shiro:lacksRole name="abc">        没有角色abc
<shiro:hasPermission name="abc">    拥有权限资源abc
<shiro:lacksPermission name="abc">    没有abc权限资源
<shiro:principal>        显示用户身份名称
<shiro:principal property="username"/>         显示用户身份中的属性值
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值