Spring整合Shiro(二)

前面一个小节完成基本的配置,后面一个小节重点放在认证(登陆)和授权

  • UserHandler.java
package cn.zzu.wcj.shiro.handler;

import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
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.RequestParam;

import cn.zzu.wcj.shiro.service.ShiroService;

@Controller
@RequestMapping("/Shiro")
public class UserHandler {

    @Autowired
    private ShiroService shiroService  ;

    @RequestMapping("doLogin")
     public String doLogin(@RequestParam String userName,@RequestParam String password){
            Subject currentUser = SecurityUtils.getSubject();
            System.out.println(userName+"###############"+password);
            if (!currentUser.isAuthenticated()) {
                //把用户账号和密码封装成令牌
                UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
                System.out.println("############1.Token"+token.hashCode());
                //设置记住我
                token.setRememberMe(true);
                try {
                    //执行登陆
                    currentUser.login(token);
                //若账户不存在,则Shiro会抛出UnknownAccountException异常
                } catch (UnknownAccountException uae) {
                    System.out.println("##############用户名错误!"+uae);
                //若账户存在,但密码不存在,则抛出IncorrectCredentialsException异常               
                } catch (IncorrectCredentialsException ice) {
                    System.out.println("##############密码错误!"+ice);
                //若账户被锁定,就抛出LockedAccountException异常                
                } catch (LockedAccountException lae) {
                    System.out.println("##############账户锁定!"+lae);

                //所有认证时异常的父类
                }catch (AuthenticationException ae) {
                    System.out.println("##############登陆错误!"+ae);
                }catch(Exception e){
                     System.out.println("##################"+e);
                }
            }
            return "redirect:/list.jsp" ;
    }

    @RequestMapping("/testAnno")
    public String testAnno(HttpSession session){
            session.setAttribute("wcj","java");
            this.shiroService.sayHello(); 
            return "redirect:/list.jsp"  ;
    }

}
  • ShiroRealm.java
package cn.zzu.wcj.shiro.realm;

import java.util.Arrays;

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

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
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.apache.shiro.util.ByteSource;

public class ShiroRealm extends AuthorizingRealm {


    /**
     * @see 授权会被 shiro 回调的方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        System.out.println("#################################################授权回调");
        //1. 从 PrincipalCollection 中来获取登录用户的信息
        Object userName=principals.getPrimaryPrincipal()  ;
        //2. 利用登录的用户的信息来用户当前用户的角色或权限(可能需要查询数据库)
        Set<String> roles=new HashSet<String>()  ;  
        roles.addAll(Arrays.asList("user"))  ;
        //3. 创建 SimpleAuthorizationInfo, 并设置其 reles 属性.
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(roles)  ;
        return info  ;
    }

    /**
     * @see 此方法是用来完成认证(即登陆功能的)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
         System.out.println("############[UsernamePasswordRealm]2.Token"+token);
         SimpleAuthenticationInfo authcInfo=null ;
         //1.将AuthenticationToken强转成UsernamePasswordToken
         UsernamePasswordToken upToken=(UsernamePasswordToken) token;
         //2.获取用户名
         String userName=upToken.getUsername()  ;
         //3.与数据库中用户名进行比对
         if("unknow".equals(userName)){
              throw new UnknownAccountException("用户名不存在")  ;   //抛出用户名错误异常
         }
         if("ghost".equals(userName)){
             throw new LockedAccountException("用户被锁定")   ;
         }
         //4.将数据库中查询到的用户名和密码放置到SimpleAuthenticationInfo中
         //1)Object principal 用户认证信息,即用户名, 
         //2)Object credentials 用户密码, 
         //3)String realmName Real名称,通过getName取得
         Object principal="admin"   ;
         Object credentials="02bad5ac06ea6ce0be3a24fd39781d11"  ;
         String realmName=super.getName()   ;           //调用父类获取Realm名称的方法
         ByteSource credentialsSalt=ByteSource.Util.bytes(userName);  //盐值加密
         authcInfo=new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
         return authcInfo;
    }

}
  • ShiroService.java
package cn.zzu.wcj.shiro.service;

import java.util.Date;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.session.Session;
import org.springframework.stereotype.Service;

@Service
public class ShiroService {

    @RequiresRoles(value={"admin","user"},logical=Logical.OR)
    public void sayHello(){
        System.out.println("Hello World !!! "+new Date());
        Session session = SecurityUtils.getSubject().getSession();
        System.out.println("############wcj-->"+session.getAttribute("wcj"));
    }

}

Tips:上面的这些代码看懂了就可以快速搭建Shiro安全框架,你看不懂并不代表我看不懂,我粘贴一下就可以在项目中跑起来,OK?想学习就不要浮躁

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章