Shiro框架入门

Shiro框架入门

1、认证 登录

检验待登录的用户是否是系统合法用户,是,认证通过,不是,就拒绝

xml配置文件
<!-- MyShiroRealm bean 配置-->
<bean id="myShiroRealm" class="com.hqyj.fj.realm.MyShiroRealm">
     <property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 配置shiro核心组件 SecurityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- 我们自定义的认证域对象注入到SecurityManager对象中-->
    <property name="realm" ref="myShiroRealm" />
</bean>
pom.xml
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.2.2</version>
</dependency>
java代码
package com.hqyj.fj.realm;

import com.hqyj.fj.pojo.Role;
import com.hqyj.fj.pojo.User;
import com.hqyj.fj.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.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/*
*   认证域
*   给shiro框架返回系统中用户的认证信息
*   给shiro框架返回系统中用户的授权信息
* */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    //给shiro框架返回系统中待认证用户的认证信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //使用认证令牌获取当前待登录的用户名
        String username = (String)token.getPrincipal();
        //在我们的系统中查询用户的认证信息
        User user = userService.getOneByUsername(username);
        //如果用户不存在,抛出用户不存在的异常
        if(user == null){
            throw new UnknownAccountException(username+"不存在");
        }
        //在shiro会话域*享用户信息,以便业务层获取使用
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("loginUser", user);
        //使用三个参数的构造方法来构造,用户名、密码、当前认证域的名称
//        SimpleAuthenticationInfo info =
//                new SimpleAuthenticationInfo(username, user.getPassword(), getName());
      ByteSource saltBytes =ByteSource.Util.bytes(user.getUsername());
        SimpleAuthenticationInfo info =
              new SimpleAuthenticationInfo(username, user.getPassword(), saltBytes,getName());
        System.out.println("获取认证信息");
        System.out.println(info);
        return info;
    }
      @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    //是下面关于授权的代码,可以复制下面的//doGetAuthenticationInfo方法
         
    return null;
    }
}
控制层controlle java代码
    @RequestMapping("/login")
    @ResponseBody
    public Map<String, Object> login(String username, String password){
        //检查请求参数
        if(username == null || password == null){
            Map<String, Object> result = new HashMap<>();
            result.put("code",-9);
            result.put("message","请求参数错误");
            return result;
        }
        //调用服务层实现业务
        return userServie.login(username,password);
    }

    @RequestMapping("/logout")
    @ResponseBody
    public Map<String, Object> logout(){
        //调用服务层实现业务
        return userServie.logout();
    }
服务层servrce java代码
    @Override
    public Map<String, Object> login(String username, String password) {
        Map<String, Object> result = new HashMap<>();
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //判断当前是否已经认证过
        if(!subject.isAuthenticated()){
            //创建一个认证令牌
            UsernamePasswordToken token = new UsernamePasswordToken(username,password);

            //做登录
            try{
                subject.login(token);
            }catch (UnknownAccountException e){
                //未知账号异常
                result.put("code", -1);
                result.put("message",username+"用户不存在");
                return result;
            }catch (IncorrectCredentialsException e){
                //密码错误异常
                result.put("code", -2);
                result.put("message",username+"用户密码错误");
                return result;
            }catch (AuthenticationException e){
                result.put("code",-10);
                result.put("message","认证失败");
                return result;
            }
        }
        //认证通过,获取已保存在shiro session域中的用户信息
        Session session = subject.getSession();
        Object loginUser = session.getAttribute("loginUser");
        result.put("code", 0);
        result.put("message",username +"认证成功");
        //直接返回给控制器方法
        result.put("loginUser",loginUser);
        return result;
    }

    @Override
    public Map<String, Object> logout() {
        //使用shiro框架获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //使用shiro对当前用户登出
        subject.logout();
        Map<String, Object> result = new HashMap<>();
        result.put("code", 0);
        result.put("message", "成功登出");
        return result;
    }
核心代码讲解

Shiro框架入门

2、授权

当已认证用户系统收收权限时,检查所具有的权限,如果有该资源的访问权限,权限通过,允许访问,反之,拒绝访问

xml代码
  <!-- shiro过滤器,用于授权 -->
    <!-- 这里的id shiroFilter 和web.xml中配置的代理过滤器的名称一致-->
<!--    当已经认证的用户访问系统资源时,检查所具有的权限 如果有访问权限
        授权通过,允许访问吧,反之,拒绝访问
        web应用收权限-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
<!--        没有认证过的用户,访问受限资源时,shiro直接跳转该配置的url-->
        <property name="loginUrl" value="/index.jsp"></property>
<!--        已认证过但是没有访问权限的用户 访问受限资源时 shiro直接跳转到该处置的url-->
        <property name="unauthorizedUrl" value="/unauthorized.jsp"></property>
        <property name="filterChainDefinitions">
            <value>
<!--                配置过滤器链
                   想要控制url=身份信息:anon 匿名用户
                                     authc 认证通过用户
                                     roles[角色名]具有某个角色的用户
                                     permes[权限名]具有某个权限的用户-->
                               /shiroTag=anon
                              /index.jsp=anon
                              /user/login=anon
                              /shiro/mustauthc=authc
                               /shiro/mustauthc=roles[管理员]
                              /shiro/mustnormal=roles[普通用户]
                              /**=authc
            </value>
        </property>
    </bean>
java代码
package com.hqyj.fj.realm;

import com.hqyj.fj.pojo.Role;
import com.hqyj.fj.pojo.User;
import com.hqyj.fj.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.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/*
*   认证域
*   给shiro框架返回系统中用户的认证信息
*   给shiro框架返回系统中用户的授权信息
* */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    //给shiro框架返回系统中待认证用户的认证信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
   //是上面关于认证的代码,可以复制上面的  doGetAuthenticationInfo方法;
        return null;
    }
   //给shiro框架返回系统中的信息
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("获取授权信息");
        String username=(String) principals.getPrimaryPrincipal();
        System.out.println(username);
        //获取待授权的用户权限信息:角色信息,和权限信息
        User user=userService.getOneByUsername(username);
        //组装一个Set<String>角色信息
        Set<String> roles=new HashSet<>();
        //组装一个Set<String>权限信息
        Set<String> perms=new HashSet<>();
        for (Role role:user.getRoles()){
            roles.add(role.getName());
        }
        //创建一个授权角色信息
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        //赋予角色权限
        info.setRoles(roles);
        //赋予权限相关的授权信息
        info.setStringPermissions(perms);
        return info;
    }


}
结果

登录成功
Shiro框架入门

登录失败

Shiro框架入门

授权问题

Shiro框架入门
Shiro框架入门

3、Session

Session 可以不通过java web 的session对象来实现会话功能,可以使用shiro session对象实现会话领域的数据共享问题

4、加密

登录时的密码,加密

  • 散列算法

    MD5 SHA1 SHA256 明文-----》xxxxx32234af455将原文的关键字提取出来,生成一串看不懂的暗文信息,从暗文信息无法还原成原文,同一个原文信息转换成唯一一个暗文信息。

  • 加密算法

    可以加密解密的算法

通过算法进行密码加密

xml代码
 <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--        这里配置的算法和迭代此地,和MD5Util是一致的-->
        <property name="hashAlgorithmName" value="MD5"></property>
        <property name="hashIterations" value="1000"></property>
    </bean>
    <!-- MyShiroRealm bean 配置-->
    <bean id="myShiroRealm" class="com.hqyj.fj.realm.MyShiroRealm">
         <property name="credentialsMatcher" ref="credentialsMatcher"></property>
    </bean>
java代码
package com.hqyj.fj.utils;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;

/*
* 使用shiro 提供的加密相关的工具类做个加密(散列算法)明文->暗文
* */
public class MD5Util {
    /*
     * password 原文
     * slat 盐
     * 多次使用散列算法进行加密,增加密码强度,破解难度
     * 加盐:增加密码强度,破解难度
    */
    public  static String md5Hash(String password,String salt){
        ByteSource slaBytes=ByteSource.Util.bytes(salt);
        //SimpleHash(String algorithmName, Object source, Object salt)
     SimpleHash simpleHash=   new SimpleHash("MD5",password,slaBytes,1000);

          return simpleHash.toString();
    }
}
测试类结果
@Test
public  void  testMd5Hash(){
    String password="123456";
    String salt="zhangsan";
    String hashePass= MD5Util.md5Hash(password,salt);
    System.out.println(hashePass);
}

Shiro框架入门

此时123456已经加密

Shiro框架入门

Shiro框架入门

上一篇:API Sanity Checker在Ubuntu中的使用


下一篇:c# WinForm加载焦点