销售宝系统_Day05(shiro)

  • shiro入门

Shiro权限管理

Apache Shiro是一个强大且易用的Java安全框架,有身份验证授权密码学会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

Spring security 重量级安全框架
Apache Shiro轻量级安全框架

  • 一、自定义Realm

导包

    
        
            org.apache.shiro
            shiro-core
            1.4.0
        
        
            commons-logging
            commons-logging
            1.2
        
        
            junit
            junit
            4.12
        
    

MyRealm

package com.xpc.realm;

import org.apache.commons.collections.SynchronizedPriorityQueue;
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.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

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

//自定义Realm,需要去实现一个Realm接口
public class MyRealm  extends AuthorizingRealm {
    //设置一个名字
    @Override
    public String getName(){
        return "MyRealm";
    }
    //权限认证
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //拿到当前登陆的用户
        String username = (String) principalCollection.getPrimaryPrincipal();
        //通过模拟数据库的方法拿到角色与权限
        Set roles = getRoles(username);
        Set permissions = getPermissions(username);
        //创建返回权限对象
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //把角色和权限设置到返回对象中去
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }

    //根据用户名拿到角色
    public Set getRoles(String sername){
        Set roles = new HashSet();
        roles.add("admin");
        roles.add("it");
        return roles;
    }
    //根据用户名拿到权限
    public Set getPermissions(String sername){
        Set perms = new HashSet();
        perms.add("employee:*");
        //perms.add("employee:update");
        return perms;
    }

    //登陆认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //拿到令牌
        UsernamePasswordToken token =(UsernamePasswordToken)authenticationToken;
        String username = token.getUsername();//拿到用户名
        String password = getByName(username);
        if (password==null)
            return null;  //表示该用户不存在

        /**
         * Object principal:用户名
         * Object credentials:密码
         * String realmName:取名(随便取)
         */
        //获取到盐值
        ByteSource salt = ByteSource.Util.bytes("xpc");
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, salt,getName());
        return simpleAuthenticationInfo;
    }

    //模拟从数据库拿数据的过程
    public String getByName(String username){
        if ("admin".equals(username)){
            return "c5e48d40051cc49bd56cbfe49346b23c"; //123456
        }else if("xpc".equals(username)){
            return "ec8cc66a7f7457a45e4dab44d0882d78";  //334455
        }
        //如果没有该用户就返回null
        return null;
    }
}
  • 功能测试MyRealmTest
package com.xpc.realm;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

public class MyRealmTest {
    @Test
    public void  testMyRealm(){
        //新建一个自己的Realm
        MyRealm myRealm = new MyRealm();
        //HashedCredentialsMatcher:hashed密码匹配器
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //设置加密算法
        matcher.setHashAlgorithmName("MD5");
        //设置加密次数
        matcher.setHashIterations(10);
        //匹配器交给Realm
        myRealm.setCredentialsMatcher(matcher);
        //根据Realm创建SecurityManager对象
        DefaultSecurityManager securityManager = new DefaultSecurityManager(myRealm);

        //把它变成一个公共的对象
        SecurityUtils.setSecurityManager(securityManager);

        //拿到主体
        Subject currentUser = SecurityUtils.getSubject();

        //准备登陆
        if(!currentUser.isAuthenticated()){
            try {
                //准备令牌
                UsernamePasswordToken token = new UsernamePasswordToken("xpc","334455");
                //登陆
                currentUser.login(token);
                System.out.println("查看是否登陆成功:"+currentUser.isAuthenticated());
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("对不起,您输入对的账号有误!");
            }catch (IncorrectCredentialsException e){
                e.printStackTrace();
                System.out.println("对不起,您输入对的密码有误!");
            }catch (AuthenticationException e){
                e.printStackTrace();
                System.out.println("发生了一个未知的错误");
            }
        }
        System.out.println("判断是否是admin角色"+currentUser.hasRole("admin"));
        System.out.println("判断是否有employee:*这个权限"+currentUser.isPermitted("employee:*"));
    }

    @Test
    public void  testPassword(){
        /*
         String algorithmName("MD5"):加密算法
         Object source("admin"):密码
         Object salt("xpc"):加的盐值
         int hashIterations(10):加密次数
        */
        SimpleHash hash = new SimpleHash("MD5","334455","xpc",10);
        System.out.println(hash.toHex());
    }
}
  • 二、Shiro集成Spring

web.xml配置

    
    
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
            targetFilterLifecycle
            true
        
    
    
        shiroFilter
        /*
    

applicationContext.xml配置


在main/resources里创建一个applicationContext-shiro.xml




    
    
        
    


    
    
        
        
            
                
                
            
        
    

    
    
    
    
        
    

    
    
        
    

    
    
        
        
        
        
        
        
        


        
        
            
                
                
                
                
            
        
    
    
    


    
    
    

Java代码
MyrRealm

package com.xpc.web.shior;

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.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

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

public class MyrRealm extends AuthorizingRealm {
    @Override
    public String getName(){
        return "MyrRealm";
    }

    //权限认证
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();

        Set roles = getRoles(username);
        Set permissions = getPermissions(username);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    //根据用户名拿到角色
    public Set getRoles(String sername){
        Set roles = new HashSet();
        roles.add("admin");
        roles.add("it");
        return roles;
    }
    //根据用户名拿到权限
    public Set getPermissions(String sername){
        Set perms = new HashSet();
        perms.add("employee:*");
        perms.add("dept:*");
        return perms;
    }

    //登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;

        String username = token.getUsername();
        String password = getPassword(username);

        if (password==null)
            return null;
        ByteSource salt = ByteSource.Util.bytes("xpc");//获取到盐值
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, salt, getName());
        return simpleAuthenticationInfo;
    }
    //模拟从数据库拿到密码的过程
    public String getPassword(String username){
        if ("admin".equals(username)){
            return "c5e48d40051cc49bd56cbfe49346b23c";  //123456
        }else if ("xpc".equals(username)){
            return "ec8cc66a7f7457a45e4dab44d0882d78";  //334455
        }
        return null;    //表示没有该用户
    }
}

FilterChainDefinitionMapFactory

package com.xpc.web.shior;

import org.apache.commons.collections.map.LinkedMap;

import java.util.LinkedHashMap;
import java.util.Map;

//用类的方式来做权限拦截
/*
     /login = anon
     /employee/index = perms[employee:index]
     /dept/index = perms[dept:index]
     /** = authc
*/
public class FilterChainDefinitionMapFactory {
    public Map builderFilterChainDefinitionMap(){
        //LinkedHashMap是有序的
        Map map = new LinkedHashMap();
        //设置放行
        map.put("/login", "anon");

        ////设置权限拦截
        map.put("/employee/index", "perms[employee:index]");
        map.put("/dept/index", "perms[dept:index]");

        //设置所有拦截
        map.put("/**", "authc");
        return map;
    }
}

LoginController

package com.xpc.web.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
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){
        //1.拿到subject(当前用户)
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()){
            try{
                UsernamePasswordToken token = new UsernamePasswordToken(username,password);
                subject.login(token);
                System.out.println("查看是否登陆成功:"+subject.isAuthenticated());
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("对不起,您输入对的账号有误!");
            }catch (IncorrectCredentialsException e){
                e.printStackTrace();
                System.out.println("对不起,您输入对的密码有误!");
            }catch (AuthenticationException e){
                e.printStackTrace();
                System.out.println("发生了一个未知的错误");
            }
        }
        //登陆成功就进入成功页面,没登陆成功就再次登陆
        if (subject.isAuthenticated()){
            return "redirect:/s/main.jsp";
        }else {
            return "forward:/s/login.jsp";
        }
    }
}

销售宝系统_Day05(shiro)_第1张图片

你可能感兴趣的:(销售宝(第二个项目))