shiro+springboot使用demo小案例

							shiro+springboot使用

1、什么是shiro
shiro一款java安全框架,提供认证、授权、会话管理、加密等功能。
2、核心组件
subject:表示当前操作用户(包含用户、第三方进程、后台账户);代表了当前用户的安全操作
SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过该组件来管理内部组件实例,并通过它来提供安全管理的各种服务。
 Realm: 当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

3、项目搭建
项目结构,使用idea创建springboot项目
在这里插入图片描述
jar包引入

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--Apache Shiro所需的jar包 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.2.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-cas</artifactId>
            <version>1.2.4</version>
        </dependency>

配置注解类

package com.example.demo.controller.shiro;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
    /**
     * 权限认证,为当前登录的Subject授予角色和权限
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        //shiroFilter.setLoginUrl("/login");//未登录跳转
        shiroFilter.setUnauthorizedUrl("/test1");//未授权跳转
        LinkedHashMap<String,String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login", "anon");//未认证可登陆路劲
        filterChainDefinitionMap.put("/*", "authc");//未认证拦截所有路径
        shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilter;
    }

    /**
     * 核心的安全事务管理器
     *
     *
     * @return
     */
    @Bean(name = "securityManager")
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        //设置realm
        securityManager.setRealm( myShiroRealm(  )  );
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }

    /**
     * 身份认证Realm,此处的注入不可以缺少。否则会在UserRealm中注入对象会报空指针.
     * @return
     */
    @Bean
    public ShiroDBRealm myShiroRealm(  ){
        ShiroDBRealm myShiroRealm = new ShiroDBRealm();
        myShiroRealm.setCredentialsMatcher(  hashedCredentialsMatcher() );
        return myShiroRealm;
    }

    /**
     * 哈希密码比较器。在myShiroRealm中作用参数使用
     * 登陆时会比较用户输入的密码,跟数据库密码配合盐值salt解密后是否一致。
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用md5算法;
        hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5( md5(""));
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }

    /**
     * cookie管理对象;
     *
     * @return
     */
    @Bean
    public CookieRememberMeManager rememberMeManager() {
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());
        cookieRememberMeManager.setCipherKey(Base64.decode("5aaC5qKm5oqA5pyvAAAAAA=="));
        return cookieRememberMeManager;
    }
    /**
     * cookie对象;
     *
     * @return
     */
    @Bean
    public SimpleCookie rememberMeCookie() {
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        // 记住我cookie生效时间1小时 ,单位秒
        simpleCookie.setMaxAge(60 * 60 * 1 * 1);
        simpleCookie.setPath("test");
        simpleCookie.setHttpOnly(true);
        return simpleCookie;
    }

    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    /**
     * Shiro生命周期处理器
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 自动创建代理
     * @return
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}

创建realm类(继承AuthorizingRealm)

package com.example.demo.controller.shiro;

import com.example.demo.controller.entity.User;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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.List;
import java.util.Set;

public class ShiroDBRealm extends AuthorizingRealm {

    final String username = "admin";//用户名
    final String password = "d9be323985a51535f6f6c55750f23af5";//用户密码,使用123与wx加密得到

    /**
    *该方法身份认证
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取身份
            String username = (String) authenticationToken.getPrincipal();
        //模拟数据库查询
        User user = queryUserByName(username);
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getName(),
                user.getPassword(), // 密码
                ByteSource.Util.bytes(user.getSalt()),
                getName());
        return authenticationInfo;
    }
 /**
    *用户授权认证
    *调用时机,在使用Subject中的权限角色验证时,如checkPermission等
    */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> roles = new HashSet<>();//角色集合
        Set<String> set = new HashSet<String>();//权限集合
        set.add("test");//添加权限
        set.add("create");//添加权限
        info.setStringPermissions(set);
        System.out.print("权限添加成功");
        return info;
    }

    /**
     * 获取用户信息
     * @param name
     * @return
     */
    public User queryUserByName(String name){
        User user = new User();
        user.setSalt("wx");
        user.setId("1");
        user.setName(username);
        user.setPassword(password);
        return user;
    }
}

用户类
该类可自行创建,包含用户、角色、权限等类

加密工具类

package com.example.demo.controller.shiro;

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

public class SalfUtil {

    public static final String md5(String password, String salt){
        //加密方式
        String hashAlgorithmName = "MD5";
        //盐:为了即使相同的密码不同的盐加密后的结果也不同
        ByteSource byteSalt = ByteSource.Util.bytes(salt);
        //密码
        Object source = password;
        //加密次数
        int hashIterations = 2;
        SimpleHash result = new SimpleHash(hashAlgorithmName, source, byteSalt, hashIterations);
        return result.toString();
    }
    public static void main(String[] args) {
        String str = md5("123", "wx");
        System.out.print(str);
    }
}

登陆控制controller

package com.example.demo.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@Controller
public class LogoInController {
/**
*登陆
*/
    @RequestMapping("login")
    public String login(String name, String password){
        try {
            UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(name,password);
            Subject currentUser = SecurityUtils.getSubject();//获取当前用户信息
            currentUser.login(usernamePasswordToken);//登陆验证
            System.out.print(currentUser);
            System.out.print("Jinlai");
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
        return "index";//静态页面
    }

    @RequestMapping("test")
    @ResponseBody
    public String test(){
        try {
            System.out.print("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
        } catch (Exception e) {
            e.printStackTrace();
            return "test访问失败";
        }
        return "test访问成功";
    }
    @RequestMapping("test1")
    @ResponseBody
    public String test1(){
        try {
            Subject currentUser = SecurityUtils.getSubject();
            currentUser.checkPermission("create");
            System.out.print("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
        } catch (Exception e) {
            e.printStackTrace();
            return "test1访问失败";
        }
        return "test1访问成功";
    }
    @RequestMapping("test2")
    @RequiresPermissions("create")
    @ResponseBody
    public String test2(){
        try {
           // Subject currentUser = SecurityUtils.getSubject();
            //currentUser.checkPermission("create");//验证是否有该权限
            System.out.print("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
        } catch (Exception e) {
            e.printStackTrace();
            return "test2访问失败";
        }
        return "test2访问成功";
    }


    @RequestMapping("logout")
    @ResponseBody
    public String logout(){
        try {
            Subject currentUser = SecurityUtils.getSubject();//获取当前用户信息
            currentUser.logout();
        } catch (Exception e) {
            e.printStackTrace();
            return "退出失败";
        }
        return "退出成功";
    }

    public static void main(String[] args) {
       try {

       }catch (Exception e){

       }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38316726/article/details/90056621