Springboot + thymeleaf + shiro 小练习

Springboot + thymeleaf + shiro 小练习

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.security</groupId>
    <artifactId>boot-security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-security</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <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>

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

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

       <!-- 最高支持springboot2.0.9-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

ShiroConfig.java

package com.shiro.bootshiro.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * Subject  : 代表当前的用户
 * SecurityManager : 安全管理器  管理者所有的用户
 * Realm  :用户的认证和授权
 */
@Configuration
public class ShiroConfig {

    //ShiroFilterFactoryBean 拦截配置
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultSecurityManager defaultSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
        /**
         * authc  需要通过认证
         * anno   不需要权限可以访问
         * perms 权限过滤器,需要某种权限才能访问
         * roles  角色过滤器,需要某种角色才能访问
         */
        Map<String, String> authMap = new LinkedHashMap<String, String>();

        /*authMap.put("/index", "authc");
        authMap.put("/", "authc");*/

        /*authMap.put("/user/add", "perms[user:add]");
        authMap.put("/user/update", "perms[user:update]");*/
        shiroFilterFactoryBean.setFilterChainDefinitionMap(authMap);
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        // 没有权限跳转的页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/errorPage");

        return shiroFilterFactoryBean;
    }

    //DefaultWebSecurityManager 安全管理器

    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(userRealm);
        return defaultSecurityManager;
    }

    //Realm  认证和授权
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    // 整合ShiroDialect
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }

    /**
     * 开启 aop 的注解支持
     * 因为 shiro注解切面着手的,所以需要开启aop注解
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    /**
     * 开启shiro 注解支持
     *
     * @RequiresPermissions 需要有权限才能访问
     * @RequiresRoles 需要有角色才能访问
     * @RequiresUser 必须已经经过身份验证或者记住我登录的才能访问
     * @RequiresAuthentication 通过的身份验证的才能访问
     * @RequiresGuest 游客的身份就可以访问
     * <p>
     * shiro 可以配置多个注解,按照以下的处理顺序,只有前面的通过了,才会处理下面的,不然直接返回
     * RequiresRoles
     * RequiresPermissions
     * RequiresAuthentication
     * RequiresUser
     * RequiresGuest
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultSecurityManager defaultSecurityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        // 设置安全管理器
        authorizationAttributeSourceAdvisor.setSecurityManager(defaultSecurityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

UserRealm.java

package com.shiro.bootshiro.config;

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 java.util.Arrays;
import java.util.List;

public class UserRealm extends AuthorizingRealm {


    // 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("===============进入授权===========");
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        String username = (String) principalCollection.getPrimaryPrincipal();
        if ("root".equals(username)) {
            simpleAuthorizationInfo.addStringPermission("user:add");
            simpleAuthorizationInfo.addStringPermission("user:update");
            simpleAuthorizationInfo.addRole("add");
            simpleAuthorizationInfo.addRole("update");
        }
        if ("gao".equals(username)) {
            simpleAuthorizationInfo.addStringPermission("user");
            simpleAuthorizationInfo.addRole("add");
        }
        return simpleAuthorizationInfo;
    }

    // 认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("===============进入认证===========");

        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        // 后续这里可以对接数据库
        String[] username = new String[]{"root", "gao", "guest"};
        List<String> list = Arrays.asList(username);
        String password = "root";

        if (list.indexOf(usernamePasswordToken.getUsername()) < 0) {
            return null;
        }

        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("loginUser", usernamePasswordToken.getUsername());
        return new SimpleAuthenticationInfo(usernamePasswordToken.getUsername(), password, "");
    }
}

ShiroController.java

package com.shiro.bootshiro.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ShiroController {
    @RequiresGuest()
    @RequestMapping({"/", "/index"})
    public String index() {
        return "index";
    }

    @RequiresRoles({"add", "update"})
    @RequestMapping("/user/add")
    public String add() {
        return "add";
    }


    @RequiresPermissions(value = {"user:update", "user:add"}, logical = Logical.OR)
    @RequestMapping("/user/update")
    public String update() {
        return "update";
    }


    @RequestMapping("/login")
    public ModelAndView login(String username, String password, ModelAndView modelAndView) {
        // 获取当前用户
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
        } catch (UnknownAccountException uae) {   // 用户名错误
            modelAndView.addObject("msg", "用户名错误");
            modelAndView.setViewName("login");
            return modelAndView;
        } catch (IncorrectCredentialsException ice) {   // 密码错误
            modelAndView.addObject("msg", "密码错误");
            modelAndView.setViewName("login");
            return modelAndView;
        }
        modelAndView.setViewName("index");
        return modelAndView;
    }

    @RequestMapping("/toLogin")
    public String toLogin() {
        return "login";
    }


    @RequestMapping("/logout")
    public String logOut() {
        SecurityUtils.getSubject().logout();
        return "login";
    }

    @RequestMapping("/errorPage")
    public String errorPage() {
        return "error";
    }
}

页面太low了,就不挂出来了。。。。也不是重点


版权声明:本文为NotfoundExcption原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。