Shiro集成web环境[Springboot]-认证与授权

Shiro集成web环境[Springboot]--认证与授权

在登录页面提交登陆数据后,发起请求也被ShiroFilter拦截,状态码为302

<form action="${pageContext.request.contextPath}/user/login" method="post">
    Username:<input type="text" name="username"></br>
    Password:<input type="password" name="password"></br>
    <input type="submit" value="提交">
</form>

所以,必须将控制器的请求全部设置为匿名资源

@Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> map = new HashMap<>();
        //多个过滤器  AnonymousFilter  匿名过滤器   anon
        // FormAuthenticationFilter 认证过滤器 authc
        map.put("/**","authc");
        map.put("/user/*","anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/main/login.jsp");
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager getSecurityManager(Realm realm){
        //web环境下securityManage的实现类为DefaultWebSecurityManager
        SecurityManager securityManager = new DefaultWebSecurityManager();
        ((DefaultWebSecurityManager) securityManager).setRealm(realm);
        return securityManager;
    }

再次发起请求,ok 但由于认证未设置 所以没有成功的跳转。

开发自定义Realm--认证与授权方法全部实现

public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserMapper userMapper;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        String principal =(String) authenticationToken.getPrincipal();
        User user= new User();
        user.setUsername(principal);
        User user1 = userMapper.selectOne(user);
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal,user1.getPassword(),ByteSource.Util.bytes("salt"),this.getName());
        return authenticationInfo;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        System.out.println("================================");
        User user= new User();
        user.setUsername(primaryPrincipal);
        User user1 = userMapper.selectOne(user);
        if(primaryPrincipal.equals(user1.getUsername())){
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            authorizationInfo.addRole("super");
            authorizationInfo.addStringPermission("user:delete");
            authorizationInfo.addStringPermissions(Arrays.asList("admin:delete","admin:add"));
            return authorizationInfo;
        }
        return null;
    }
}

补充ShiroFilter,将SecurityManager,自定义Realm,CredentialsMatcher,CacheManager全部交由工厂管理:

@Configuration
public class ShiroFilterConf {

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //shiro会对所有资源进行控制,默认不拦截  需要配置
        Map<String,String> map = new HashMap<>();
        //多个过滤器  AnonymousFilter  匿名过滤器   anon
        // FormAuthenticationFilter 认证过滤器 authc
        map.put("/**","authc");
        map.put("/user/*","anon");
        map.put("/index.jsp","anon");
        //多个过滤器组成过滤器链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        //设置认证页面路径
        shiroFilterFactoryBean.setLoginUrl("/main/login.jsp");
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager getSecurityManager(Realm realm,CacheManager cacheManager){
        //web环境下securityManage的实现类为DefaultWebSecurityManager
        SecurityManager securityManager = new DefaultWebSecurityManager();
        ((DefaultWebSecurityManager) securityManager).setRealm(realm);
        ((DefaultWebSecurityManager) securityManager).setCacheManager(cacheManager);
        return securityManager;
    }

    @Bean
    public Realm getRealm(CredentialsMatcher credentialsMatcher){
        MyRealm myRealm = new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher);
        return myRealm;
    }

    @Bean
    public CredentialsMatcher getCredentialsMatcher(){
        HashedCredentialsMatcher hm = new HashedCredentialsMatcher();
        hm.setHashAlgorithmName("MD5");
        hm.setHashIterations(1024);
        return hm;
    }

    @Bean
    public CacheManager getCacheManager(){
        CacheManager cacheManager = new EhCacheManager();
        return cacheManager;
    }
}

测试index页面

<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<shiro:authenticated>
    hello:<shiro:principal></shiro:principal>&nbsp;&nbsp;<a href="${pageContext.request.contextPath}/user/logout">登出</a>
    <ul>
        <li>专辑</li>
        <li>章节</li>
        <li>用户</li>
        <shiro:hasRole name="super">
            <li>管理员</li>
            <shiro:hasPermission name="admin:delete">
                删
            </shiro:hasPermission>
            <shiro:hasPermission name="admin:add">
                增
            </shiro:hasPermission>
            <shiro:hasPermission name="admin:update">
                改
            </shiro:hasPermission>
        </shiro:hasRole>
    </ul>
</shiro:authenticated>

<shiro:notAuthenticated>
    <a href="${pageContext.request.contextPath}/main/login.jsp">你好请登录</a>
</shiro:notAuthenticated>
</body>
</html>

shiro中相关的标签

<shiro:principal></shiro:principal>  //用户的身份信息
<shiro:authenticated></shiro:authenticated> //认证成功  执行标签体的内容
<shiro:notAuthenticated></shiro:notAuthenticated> //未认证  执行标签体内容
//基于角色的权限管理
<shiro:hasRole name="super"></shiro:hasRole>
<shiro:hasAnyRoles name="admin,super"></shiro:hasAnyRoles>
//基于资源的权限管理
<shiro:hasPermission name="user:delete"></shiro:hasPermission>

缓存问题

如果没有缓存,一个Permission或者role判断要查询三次数据库-username查主体--主体查角色---角色查权限,这样对于数据库的压力太大,需要设置缓存。而且要注意到,在第一次查询时shiro就会多个Permission或者Role判断设置一次缓存,就是说,授权方法doGetAuthorizationInfo只走一次。

ehcache主包必须导入,shiro集成时CacheManager是没有实现的,主包中才有实现类EhCacheManager

    @Bean
    public CacheManager getCacheManager(){
        CacheManager cacheManager = new EhCacheManager();
        return cacheManager;
    }

原文地址:https://www.cnblogs.com/mzc1997/p/10225647.html

时间: 2024-10-08 22:16:30

Shiro集成web环境[Springboot]-认证与授权的相关文章

Shiro集成web环境[Springboot]-基础使用

Shiro集成web环境[Springboot] 1.shiro官网查找依赖的jar,其中shiro-ehcache做授权缓存时使用,另外还需要导入ehcache的jar包 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.3.2</version> </dependency&

Web Api 2 认证与授权 2

HTTP Message Handler 在 Web Api 2 认证与授权 中讲解了几种实现机制,本篇就详细讲解 Message Handler 的实现方式 关于 Message Handler 在 request 到 response 过程所处于的位置,可以参考这里 HTTP Message Handlers Authentication Message Handler 先看一段实现的代码,然后再做讲解,完整代码可以在 Github 上参考,WebApi2.Authentication 1

Java Web系列:认证和授权基础

1.认证和授权概述 (1)认证:对用户的身份进行验证. .NET基于的RBS(参考1)的认证和授权相关的核心是2个接口System.Security.Principal.IPrincipal和System.Security.Principal.IIdentity.我们自己实现认证过程,通过Thread.CurrentPrincipal来设置和读取认证结果.认证成功后设置认证状态和标识. Java内置了的JAAS(参考2),核心是javax.security.auth.Subject类和javax

Shiro安全框架之权限认证(授权)

第一讲.权限认证核心要素 权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源. 在权限认证中,最核心的三个要素是:权限,角色和用户: Authorization has three core elements that we reference quite a bit in Shiro: permissions, roles, and users. 权限permissions,即操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利: 角色,是权限的集合,一中

关于 Web Api 2 认证与授权

今天有幸被召回母校给即将毕业的学弟学妹们讲我这两年的工作史,看了下母校没啥特别的变化,就是寝室都安了空调,学妹们都非常漂亮而已..好了不扯蛋了,说下今天的主题吧.这些天我在深度定制语法高亮功能的同时发现了博客园提供的一些有意思的函数,甚至有几个博客园都没用到,我也不知道怎么才能触发那些功能..打开这个js就可以看到很多好用的东西了,虽然写的不怎么样,但是至少有这些功能. ps: 推荐安装一个代码格式化的插件,否则一坨看着蛋疼.比如第一个就是 log,方便调试. http://www.qidian

【Shiro】Apache Shiro架构之集成web

前面两节内容介绍了Shiro中是如何进行身份和权限的认证,但是只是单纯的进行Shiro的验证,简单一点的话,用的是.ini配置文件,也举了个使用jdbc realm的例子,这篇博文主要来总结一下Shiro是如何集成web的,即如何用在web工程中. 写在前面:本文没有使用web框架,比如springmvc或者struts2,用的是原始的servlet,使用的是.ini配置文件,旨在简单粗暴,说明问题.后面会写一些和框架整合的博文. 本文部分参考Apache Shiro的官方文档,文档地址:htt

Shiro 简介(认证、授权、加密、会话管理、与 Web 集成、缓存等)

https://www.w3cschool.cn/shiro/ Shiro 简介 简介 Apache Shiro 是 Java 的一个安全框架.目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了.对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了. 本教程只介绍基本的 Shiro 使用,不会

使用Shiro实现认证和授权(基于SpringBoot)

Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案.下面是在SpringBoot中使用Shiro进行认证和授权的例子,代码如下: pom.xml 导入SpringBoot和Shiro依赖: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s

springboot引入shiro实现拦截,权限,认证,授权功能

Shiro核心三大组件 1. Subject Subject表示与系统交互的对象,可以是登录系统的操作用户,也可能是另外一个软件系统. Subject类图 2. SecurityManager SecurityManager是Shiro架构最核心的组件.实际上,SecurityManager就是Shiro框架的控制器,协调其他组件一起完成认证和授权 3. Realms Realm定义了访问数据的方式,用来连接不同的数据源,如:LDAP,关系数据库,配置文件等等. Spingboot整合shiro