shiro使用模板(springboot)

pom:

 <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring-boot-starter</artifactId>
 </dependency>

Config:

        -- MyRealm

package com.wang.config;

import com.wang.entity.TestUser;
import com.wang.entity.UserResouce;
import com.wang.service.TestUserServiceImpl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.util.*;

/**
 * @Author wangli
 * @Date: 2022/3/10 10:39
 * @Version 1.0
 */
@Configuration
public class MyRealm extends AuthorizingRealm {
    @Autowired
    private TestUserServiceImpl userService;

    static Logger logger = LogManager.getLogger(MyRealm.class.getName());
//    授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("进入了授权");
//        Set<String> myRealm = principalCollection.getRealmNames("myRealm");
        //获得当前用户
        TestUser user = (TestUser) principalCollection.asList().get(0);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //需要绑定角色、资源
        Collection<String> role = Collections.singleton(user.getRole());
        info.addRoles(role);
//      //拿到用户的权限-设置权限
        List<String> permissions =  userService.getUserPermission(user.getId());
        info.addStringPermissions(permissions);
        return info;
    }

//    认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        logger.info("进入了认证");
        //获得当前用户
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        System.out.println("userToken=>"+userToken);
        String username = userToken.getUsername();
        //获得数据库中的用户,来跟当前用户进行比对
        TestUser user = userService.queryUserByUserName(username);
        if (null == user) {//没有查到
            return null;
        }

        ByteSource salt = ByteSource.Util.bytes("salt");//设置加盐
        //完成了认证
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),salt,"myRealm");
        return info;
    }
}

        -- ShiroConfig

package com.wang.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
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.HashMap;
import java.util.Map;

/**
 * @Author wangli
 * @Date: 2022/3/10 10:35
 * @Version 1.0
 */
@Configuration
public class ShiroConfig {
//    1.Realm 代表系统资源
//        @Bean(name = "getRealm")
//        public Realm getRealm(){
//                return new MyRealm();
//        }

//    2.SecurityManager 流程控制
        @Bean(name = "SM")
        public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("myRealm")AuthorizingRealm MyRealm){//@Qualifier("getRealm")
                DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
                //设置加密方式(将输入的密码进行加密)
                HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
                matcher.setHashAlgorithmName("MD5");//设置加密算法
                matcher.setHashIterations(3);//设置跌代次数
                MyRealm.setCredentialsMatcher(matcher);

                securityManager.setRealm(MyRealm);
                return securityManager;
        }

//    3.ShiroFilterFactoryBean 请求控制器
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("SM")DefaultWebSecurityManager securityManager){
                ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
                factoryBean.setSecurityManager(securityManager);

                //配置路径过滤器
                Map<String, String> filterMap = new HashMap<>();
                //key是ant路径,value是shiro的默认过滤器
                //shiro过滤器是DefaultFilter
                /*
                * anon,authc,perms,role
                * 下面配置的认证或不认证是有先后顺序的,详细的配在前面才能生效
                * 出前往后进行匹配
                * perms[***]配置权限(有权限才能访问当前资源下的接口)
                * */

                filterMap.put("/comon/**","authc");
                filterMap.put("/api/**","perms[vip1]");
                filterMap.put("/salary/**","perms[vip2]");
//                filterMap.put("/salary/**","authc,perms[salary],roles[admin]");
                //设置登出
                filterMap.put("/logout","logout");
                factoryBean.setFilterChainDefinitionMap(filterMap);
                //设置登录页面
//                factoryBean.setLoginUrl("http://localhost:8080/");
                //设置未授权的页面
//                factoryBean.setUnauthorizedUrl();


                return factoryBean;
        }
}

        -- MyExceptionHandler

package com.wang.config;

import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.naming.AuthenticationException;

/**
 * @Author wangli
 * @Date: 2022/3/11 17:08
 * @Version 1.0
 */
@RestControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(AuthorizationException.class)
    public Object shiroHandler(){
        return "请先获取对应的资源,再进行访问!";
    }
}

Controller  (登录api)

package com.wang.controller;

import com.wang.entity.TestUser;
import com.wang.entity.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;


/**
 * @Author wangli
 * @Date: 2022/3/10 10:26
 * @Version 1.0
 */
@RequestMapping("/login")
@RestController
public class LoginController {
    private static Logger log = LogManager.getLogger(LoginController.class.getName());

    @PostMapping("/login")
    public Object login(TestUser user) {
        log.info(user);
        Map<String, String> errorMsg = new HashMap<String, String>();
        Subject currentUser = SecurityUtils.getSubject();
//        if (!currentUser.isAuthenticated()) {//没认证过
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            try {
                //登录入口
                currentUser.login(token);//去登录
                currentUser.getSession().setAttribute("currentUser", currentUser.getPrincipal());
                System.out.println("登录成功用户信息=>"+currentUser.getPrincipal());
                return "login Success";
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
                errorMsg.put("errorMsg", "用户不存在");
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
                errorMsg.put("errorMsg", "密码不正确");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
                errorMsg.put("errorMsg", "账户已锁定");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
                log.info("登录失败");
                errorMsg.put("errorMsg", "登录失败");
            }
            return errorMsg;
//        }else {
//
//        }
        }

        @RequiresAuthentication
        @RequestMapping("/getCurrentUser")
        public Object getCurrentUser(){
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession();
            return session.getAttribute("currentUser");
        }
//
    @RequestMapping("/logout")
    public void logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }

}

utils

        --MD5PasswordUtil

package com.wang.utils;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Component;

import static org.apache.shiro.crypto.hash.Md5Hash.ALGORITHM_NAME;

/**
 * @Author wangli
 * @Date: 2022/3/11 23:51
 * @Version 1.0
 */
@Component
public class MD5PasswordUtil {

    //MD5加密密码
    public String getEncryptionPass(String password){
        SimpleHash encryptionPass = new SimpleHash(ALGORITHM_NAME, password, "salt", 3);
        return encryptionPass.toString();
    }
}

--扩展--

log4j2pom

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

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <!--只接受程序中DEBUG级别的日志进行处理-->
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{HH:mm:ss.SSS}] %-5level %class{36} %L %M - %msg%xEx%n"/>
        </Console>
        <!--处理DEBUG级别的日志,并把该日志放到logs/debug.log文件中-->
        <!--打印出DEBUG级别日志,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileDebug" fileName="./logs/debug.log"
                     filePattern="logs/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <!--只接受DEBUG级别的日志,其余的全部拒绝处理-->
                <ThresholdFilter level="DEBUG"/>
                <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <!--输出日志的格式-->
            <PatternLayout
                    pattern="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="500 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
        <!--处理INFO级别的日志,并把该日志放到logs/info.log文件中-->
        <RollingFile name="RollingFileInfo" fileName="./logs/info.log"
                     filePattern="logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <!--只接受INFO级别的日志,其余的全部拒绝处理-->
                <ThresholdFilter level="INFO"/>
                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout
                    pattern="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="500 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
        <!--处理WARN级别的日志,并把该日志放到logs/warn.log文件中-->
        <RollingFile name="RollingFileWarn" fileName="./logs/warn.log"
                     filePattern="logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <ThresholdFilter level="WARN"/>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
            </Filters>
            <PatternLayout
                    pattern="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="500 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
        <!--处理error级别的日志,并把该日志放到logs/error.log文件中-->
        <RollingFile name="RollingFileError" fileName="./logs/error.log"
                     filePattern="logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
            <ThresholdFilter level="ERROR"/>
            <PatternLayout
                    pattern="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %class{36} %L %M - %msg%xEx%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="500 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
        <!--druid的日志记录追加器-->
        <RollingFile name="druidSqlRollingFile" fileName="./logs/druid-sql.log"
                     filePattern="logs/$${date:yyyy-MM}/api-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %L %M - %msg%xEx%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="500 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
    </appenders>
    <!--     然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->
    <loggers>
        <!--默认的root的logger-->
        <root level="DEBUG">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <appender-ref ref="RollingFileDebug"/>
        </root>
        <!--额外配置的logger-->
        <!--记录druid-sql的记录-->
        <logger name="druid.sql.Statement" level="debug" additivity="false">
            <appender-ref ref="druidSqlRollingFile"/>
        </logger>
        <!--log4j2 自带过滤日志-->
        <Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
        <Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
        <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
        <logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
        <Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
        <Logger name="org.crsh.plugin" level="warn" />
        <logger name="org.crsh.ssh" level="warn"/>
        <Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
        <Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
        <logger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
        <logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
        <logger name="org.thymeleaf" level="warn"/>
    </loggers>
</configuration>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值