springboot shiro集成

pom

<?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.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.shrimpking</groupId>
    <artifactId>demo5-shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo5-shiro</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-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </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>
        <!-- shiro 1.4.0 thymeleaf-extras-shiro 2.0.0组合       -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

domain

package com.shrimpking.domain;

import lombok.Data;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2024/1/27 22:02
 */
@Data
public class UserDo
{

    private Integer id;

    private String userName;

    private String password;
}

controller

package com.shrimpking.contrroller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
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.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;

import javax.lang.model.element.UnknownAnnotationValueException;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2024/1/28 11:18
 */
@Controller
public class UserController
{
    @GetMapping("/index")
    public String index(){
        return "index";
    }

    @GetMapping("/403")
    public String error403(){
        return "403";
    }

    @GetMapping("/article")
    @RequiresPermissions("system:article:article")
    public String article(){
        return "article";
    }

    @GetMapping("/setting")
    @RequiresPermissions("system:setting:setting")
    public String setting(){
        return "setting";
    }

    @GetMapping("/show")
    @ResponseBody
    public String show(){
        Subject subject = SecurityUtils.getSubject();
        String str = "";
        if(subject.hasRole("admin")){
            str += ",您拥有admin权限";
        }else {
            str += ",您没有admin权限";
        }

        if(subject.hasRole("sales")){
            str += ",您拥有sales权限";
        }else {
            str += ",您没有sales权限";
        }

        try
        {
            subject.checkPermission("system:setting:setting");
            str += ",您拥有setting权限";
        }catch (UnknownAnnotationValueException ex){
            str += ",您没有setting权限";
        }

        return str;
    }

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

    @PostMapping("/login")
    @ResponseBody
    public Object loginSubmit(@RequestParam String userName,@RequestParam String password){
        Map<String,Object> map = new HashMap<>();
        UsernamePasswordToken token = new UsernamePasswordToken(userName,password);
        Subject subject = SecurityUtils.getSubject();
        try
        {
            subject.login(token);
            map.put("status",0);
            map.put("message","登录成功");
            return map;
        }catch (AuthenticationException ex){
            map.put("status",1);
            map.put("message","用户名或密码错误");
            return map;
        }
    }

    @GetMapping("/logout")
    public String logout(HttpSession session, SessionStatus sessionStatus, Model model){
        //退出登录
        session.removeAttribute("userData");
        sessionStatus.setComplete();
        SecurityUtils.getSubject().logout();
        return "redirect:/login";
    }

}

shiroconfig

package com.shrimpking.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
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.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2024/1/27 22:19
 */
@Configuration
public class ShiroConfig
{
    @Bean
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 开启shiro aop注解支持,如@RequiresRoles,@RequiresPermissions
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor
                = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    /**
     * 开启shiro aop注解支持
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator =
                new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }

    /**
     * shiroDialect,是为了在thymeleaf中使用shiro标签而设置的bean
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

    /**
     * shiroFilterFactoryBean 实现过滤器的过滤
     * setFilterChainDefinitionMap 设置可访问或禁止访问的目录
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean
                = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        //设置登录页面
        factoryBean.setLoginUrl("/login");
        //登录后的页面
        factoryBean.setSuccessUrl("/index");
        //未认证的页面
        factoryBean.setUnauthorizedUrl("/403");

        //设置无须加载权限的页面过滤器
        LinkedHashMap<String,String> filterChainMap = new LinkedHashMap<>();
        filterChainMap.put("/fonts/**","anon");
        filterChainMap.put("/css/**","anon");
        filterChainMap.put("/js/**","anon");
        //authc表示有权限,anon表示不需要权限,
        //**表示某个目录下所有的文件
        //filterChainMap.put("/**","anon");
        filterChainMap.put("/**","authc");

        //设置过滤器
        factoryBean.setFilterChainDefinitionMap(filterChainMap);
        return factoryBean;
    }

    /**
     * 获取用户令牌
     * @return
     */
    @Bean
    public UserRealm userRealm(){
        UserRealm userRealm = new UserRealm();
        return userRealm;
    }

    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm());
        return securityManager;
    }
}

realm

package com.shrimpking.config;

import com.shrimpking.domain.UserDo;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
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 java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2024/1/27 22:03
 */
public class UserRealm extends AuthorizingRealm
{
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
    {
        //授权
        //获取用户
        UserDo user = (UserDo)principalCollection.getPrimaryPrincipal();
        Integer userId = user.getId();
        //新建一个授权模块
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //模拟 设置角色
        Set<String> roles = new HashSet<>();
        roles.add("admin");
        roles.add("sales");
        info.setRoles(roles);

        //模拟 设置权限
        Set<String> permissions = new HashSet<>();
        permissions.add("system:article:article");
        permissions.add("system:article:add");
        permissions.add("system:article:edit");
        permissions.add("system:article:remove");
        permissions.add("system:article:batchRemove");
        permissions.add("system:setting:setting");
        info.setStringPermissions(permissions);

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException
    {
        //认证
        //获取用户名
        String username = (String)authenticationToken.getPrincipal();

        Map<String,Object> map = new HashMap<>(16);
        map.put("username",username);
        //获取密码
        String password = new String((char[])authenticationToken.getCredentials());
        //模拟数据库,比对数据
        if(!"admin".equals(username) || !"1234".equals(password)){
            throw new IncorrectCredentialsException("账号或密码错误");
        }

        //认证通过
        UserDo user = new UserDo();
        user.setId(1);
        user.setUserName(username);
        user.setPassword(password);

        //建立一个认证模块
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,password,this.getName());

        return info;
    }
}

启动类

package com.shrimpking;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Demo5ShiroApplication
{

    public static void main(String[] args)
    {
        SpringApplication.run(Demo5ShiroApplication.class, args);
    }

}

 index

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <a href="/article">前往文章页面</a>
    </div>
    <div>
        <a href="/setting">前往设置页面</a>
    </div>
    <div>
        <a href="/show">show页面</a>
    </div>
    <div>
        <a href="/logout">退出</a>
    </div>
</body>
</html>

403

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>错误页面提示:没有授权,无法访问</h1>
</body>
</html>

article

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>必须获得system:article授权才会显示</h1>
</body>
</html>

login

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <input type="text" id="userName" name="userName" value="">
    </div>
    <div>
        <input type="password" id="password" name="password" value="">
    </div>
    <div>
        <input type="button" id="btnSave" value="登录">
    </div>
    <script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.js"></script>
    <script>
        $(function () {
            $("#btnSave").click(function () {
                var userName = $("#userName").val();
                var password = $("#password").val();
                $.ajax({
                    cache:true,
                    type:"POST",
                    url:"/login",
                    data:"userName=" + userName + "&password=" + password,
                    dataType:"json",
                    async:false,
                    error: function (request) {
                        console.log("connection error")
                    },
                    success:function (data) {
                        if(data.status == 0){
                            window.location = "/index";
                            return false;
                        }else {
                            alert(data.message)
                        }
                    }
                });
            })
        })

    </script>
</body>
</html>

setting

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>必须获得system:setting授权才会显示</h1>
</body>
</html>

application.properties

server.port=8089

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虾米大王

有你的支持,我会更有动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值