springboot整合shiro

shiro#

官网:https://shiro.apache.org/

GitHub:https://github.com/apache/shiro

与springboot整合#

导入依赖:

        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-web-starter</artifactId>
            <version>1.5.3</version>
        </dependency>

自定义Realm#

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;

public class UserRealm extends AuthorizingRealm {

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission("user:del");
        return info;
    }

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

        //假设已经从数据库获取数据
        if(!"admin".equals(token.getUsername())) return null;

        return new SimpleAuthenticationInfo("","admin","");
    }
}

创建配置类ShiroConfig#

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
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;

@Configuration
public class ShiroConfig {

    /*
     * Subject 用户
     * SecurityManager 管理所有用户
     * Realm 连接数据
     * */

    //ShiroFilterFactoryBean
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){

        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(securityManager);

        //添加shiro的内置过滤器
        /*
            anon: 无需认证就可访问
            authc:必须认证才能访问
            user:必须拥有记住我功能才能访问
            perms: 拥有对某个资源的权限才能访问
            roles:拥有某个角色权限才能访问
       */
        Map<String, String> filterMap = new LinkedHashMap<>();

        //授权
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");

        //filterMap.put("/user/*","authc");

        bean.setFilterChainDefinitionMap(filterMap);

        //设置登录界面
        bean.setLoginUrl("/login");
        //设置未授权页面
        bean.setUnauthorizedUrl("/noauth");

        return bean;
    }

    //DefaultWebSecurityManager
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联UserRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //创建Realm,需自定义
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

授权详细写法:

过滤器 说明 示例
anon 没有参数,表示可以匿名使用 /admins/**=anon
authc 表示需要认证(登录)才能使用,没有参数 /admins/user/**=authc
roles 拥有某个角色权限才能访问,参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如:admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。 /admins/user/**=roles[admin]
perms 拥有对某个资源的权限才能访问,参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,相当于isPermitedAll()方法。 /admins/user/**=perms[user:add:*]
rest 根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。 /admins/user/**=rest[post]
port 根据请求的端口 /admins/user/**=port[8081]
authcBasic 没有参数表示httpBasic认证 /admins/user/**=authcBasic
ssl ssl没有参数,表示安全的url请求,协议为https /admins/user/**=ssl
user user没有参数表示必须存在用户,当登入操作时不做检查 /admins/user/**=user

注:anon,authcBasic,auchc,user是认证过滤器,perms,roles,ssl,rest,port是授权过滤器

Controller登录方法#

//登录方法
@RequestMapping("/login")
public String login(String username,String password,Model model){
    //获取当前用户
    Subject subject = SecurityUtils.getSubject();
    //封装用户登录数据
    UsernamePasswordToken token =new UsernamePasswordToken(username,password);

    try{
        subject.login(token);
        return "index";
    }catch (UnknownAccountException e){//用户名不存在
        model.addAttribute("msg","用户名错误");
        return "login";
    }catch (IncorrectCredentialsException e){
        model.addAttribute("msg","密码错误");
        return "login";
    }
}

整合thymeleaf#

添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>2.0.0</version>
</dependency>
<!--shiro整合thymeleaf-->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.0.0</version>
</dependency>

在配置类ShiroConfig添加#

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

简单使用

<!-- 开启提示需要在根标签html加上:xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro" -->
<!-- 判断是否有此权限 -->
<div shiro:hasPermission="user:add">
    <a th:href="@{/user/add}">add</a>
</div>

作者:royal6

出处:https://www.cnblogs.com/royal6/p/12966620.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   royal6  阅读(298)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示