shiro入门demo(三)认证+授权+拦截

发布时间:2023年12月27日

一、demo:

1、pom:

<groupId>com.demo.shiro</groupId>
    <artifactId>shiro-filter-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <!--单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.31</version>
        </dependency>

        <!-- AOP依赖,必须,否则shiro权限拦截验证不生效 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

2、Realm:这里没有连接数据库,在UserConstants中假设数据

/**
 * 模拟数据库查询数据,假设有:用户名/密码/角色/资源
 * admin/123/xtgly/user_manage、role_manage、menu_manage、school_manage
 * zs/123/userAdmin、roleAdmin/user_manage、role_manage、menu_manage
 * ls/123/schoolAdmin/school_manage
 */
public class UserConstants {

    public static Map<String, String> getUsers() {
        Map<String,String> users = new HashMap<>();
        users.put("admin","123");
        users.put("zs","123");
        users.put("ls","123");
        return users;
    }

    public static Map<String,List<String>> getUserRoles() {
        Map<String,List<String>> userRoles = new HashMap<>();
        //admin
        List<String> adminRoles = new ArrayList<>();
        adminRoles.add("xtgly");
        userRoles.put("admin",adminRoles);
        //zs
        List<String> zsRoles = new ArrayList<>();
        zsRoles.add("userAdmin");
        zsRoles.add("roleAdmin");
        userRoles.put("zs",zsRoles);
        //ls
        List<String> lsRoles = new ArrayList<>();
        lsRoles.add("schoolAdmin");
        userRoles.put("ls",lsRoles);
        return userRoles;
    }

    public static Map<String,List<String>> getUserPermissions() {
        Map<String,List<String>> userPermissions = new HashMap<>();
        List<String> lsPermissions = new ArrayList<>();
        //ls
        lsPermissions.add("school_manage");
        userPermissions.put("ls",lsPermissions);
        //zs
        List<String> zsPermissions = new ArrayList<>();
        zsPermissions.add("user_manage");
        zsPermissions.add("role_manage");
        zsPermissions.add("menu_manage");
        userPermissions.put("zs",zsPermissions);
        //admin
        List<String> adminPermissions = new ArrayList<>();
        adminPermissions.add("school_manage");
        userPermissions.put("admin",adminPermissions);
        return userPermissions;
    }
}
public class MyRolePermissionRealm extends AuthorizingRealm {

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        String primaryPrincipal = (String) principal.getPrimaryPrincipal();
        Map<String, List<String>> userRoles = UserConstants.getUserRoles();
        List<String> roles = userRoles.get(primaryPrincipal);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(roles);
        //资源
        Map<String, List<String>> userPermissions = UserConstants.getUserPermissions();
        List<String> permissions = userPermissions.get(primaryPrincipal);
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());
        Map<String,String> dbUsers = UserConstants.getUsers();
        Set<String> dbUserNames = dbUsers.keySet();
        //验证用户名
        if(!dbUserNames.contains(username)){
            throw new UnknownAccountException();
        }
        //验证密码
        String dbPwd = dbUsers.get(username);
        if(!dbPwd.equals(password)){
            throw new IncorrectCredentialsException();
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password,this.getName());
        return simpleAuthenticationInfo;
    }
}

3、拦截器:

public class ShiroFormAuthenticationFilter extends FormAuthenticationFilter{
    Logger logger  = LoggerFactory.getLogger(ShiroFormAuthenticationFilter.class);

    /**
     * 未登陆
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (!isLoginRequest(request, response)) {
            this.handleErrorMsg(request,response);
           return false;
        }
        if (isLoginSubmission(request, response)) {
            if (logger.isTraceEnabled()) {
                logger.trace("Login submission detected.  Attempting to execute login.");
            }
            return executeLogin(request, response);
        } else {
            if (logger.isTraceEnabled()) {
                logger.trace("Login page view.");
            }
            return true;
        }
    }

    private void handleErrorMsg(ServletRequest request, ServletResponse response) throws IOException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setHeader("Access-Control-Allow-Origin",  req.getHeader("Origin"));
        resp.setHeader("Access-Control-Allow-Credentials", "true");
        resp.setContentType("application/text; charset=utf-8");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("登陆失效");
        out.flush();
        out.close();
    }
}

4、配置文件:

import com.demo.shiro.filter.ShiroFormAuthenticationFilter;
import com.demo.shiro.realm.MyRolePermissionRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.realm.Realm;
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.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //域
    @Bean
    public Realm getMyShiroRealm(){
        return new MyRolePermissionRealm();
    }

    //入口
    @Bean
    public SecurityManager getMySecurityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(this.getMyShiroRealm());
        SecurityUtils.setSecurityManager(securityManager);
        return securityManager;
    }

    //拦截器配置
    @Bean
    public ShiroFilterFactoryBean shirFilter() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(this.getMySecurityManager());
        //shiroFilterFactoryBean.setLoginUrl("/login");
        /**
         * 只写这个,访问报错
         * {
         *   "timestamp": 1703231180623,
         *   "status": 404,
         *   "error": "Not Found",
         *   "message": "No message available",
         *   "path": "/shiroTest/login.jsp"
         * }
         */
        Map<String, String> filterChainDefinitionMap = new HashMap<>();
        filterChainDefinitionMap.put("/**","authc");
        filterChainDefinitionMap.put("/login/login","anon");
        LinkedHashMap<String, Filter> filtsMap=new LinkedHashMap<String, Filter>();
        filtsMap.put("authc",new ShiroFormAuthenticationFilter() );
        shiroFilterFactoryBean.setFilters(filtsMap);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }


    //以下为注解支持配置
    /**
     * Shiro生命周期处理器
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 开启Shiro-aop注解支持
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

5、util

public class SessionUtil {
    public static String getUser() {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        return (String) session.getAttribute("currUserAccount");
    }
}

6、controller:

@RequestMapping("/login")
@RestController
public class LoginController {

    @RequestMapping("/login")
    public String login(String username,String password){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(
                username, password
        );
        try {
            subject.login(token);
            System.out.println("认证成功");
            Session session = subject.getSession();
            //缓存用户
            session.setAttribute("currUserAccount",username);
            //权限
            boolean isp = subject.isPermitted("school_manage");
            return (String) session.getId();
        } catch (AuthenticationException e) {
            System.out.println("认证失败");
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/logOut")
    public void logOut(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }
}
@RequestMapping("/user")
@RestController
@RequiresRoles("roleAdmin")
public class UserManageController {

    @RequestMapping("/test")
    public String test(){
        return "这是用户管理";
    }

    @RequestMapping("/getUser")
    public String getUser(){
        return SessionUtil.getUser();
    }
}
@RequestMapping("/school")
@RestController
public class SchoolManageController {

    @RequestMapping("/test")
    @RequiresPermissions("school_manage")
    public String test(){
        return "这是学校管理";
    }
}

测试:

文章来源:https://blog.csdn.net/w_t_y_y/article/details/135251139
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。