您现在的位置是:首页 > java技术交流java技术交流

shiro1.7 使用springboot 登录 笔记

上善若水2020-12-19 16:24:17【java技术交流】 3583人已围观

简介目前在权限这块shiro和Spring Security是比较热门的两个框架,本篇主要使用shiro实现基本的登录功能,供大家学习使用. 1.引入pom依赖在maven仓库中查找shiro-sprin

目前在权限这块shiroSpring Security是比较热门的两个框架,本篇主要使用shiro实现基本的登录功能,供大家学习使用.

1.引入pom依赖

在maven仓库中查找shiro-spring 截止到2020-12-19日 最新的版本为1.7,在pom中引入依赖如下.

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.0</version>
        </dependency>

2.编写登录控制器,实现登录方法

package com.springboot.blog.controller.admin;

import com.springboot.blog.dto.LayResponse;
import com.springboot.blog.service.IUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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 javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
class AdminLoginController {
    @Autowired
    IUserService userService;
    String PATH = "admin/login/";

    @GetMapping(value = {"/admin/login/index", "/admin/login"})
    public String index() {
        return PATH + "index";
    }

    @PostMapping(value = {"/admin/login"})
    @ResponseBody
    public LayResponse login(@RequestParam Map<String, String> param, HttpSession session) {
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(param.get("username"), param.get("password"));
        LayResponse response = new LayResponse();
        response.success("登录成功");
        try {
            //进行验证,这里可以捕获异常,然后返回对应信息
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException e) {
            response.error("用户名不存在!");
        } catch (AuthenticationException e) {
            response.error("账号或密码错误!");
        } catch (AuthorizationException e) {
            response.error("没有权限");
        } catch (Exception e) {
            response.error("其他错误");
        }
        return response;
    }
}

3.编写Realm 集成AuthorizingRealm 重写登录逻辑

package com.springboot.blog.interceptor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.springboot.blog.entity.User;
import com.springboot.blog.service.IUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
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 org.springframework.beans.factory.annotation.Autowired;

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    IUserService userService;
    /**
     * @MethodName doGetAuthorizationInfo
     * @Description 权限配置类
     * @Param [principalCollection]
     * @Return AuthorizationInfo
     * @Author WangShiLin
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        return simpleAuthorizationInfo;
    }

    /**
     * @MethodName doGetAuthenticationInfo
     * @Description 认证配置类
     * @Param [authenticationToken]
     * @Return AuthenticationInfo
     * @Author WangShiLin
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户信息
        String name = authenticationToken.getPrincipal().toString();
        User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, name));
        if(user==null){return null;}
        return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
    }
}

上面的查询是采用mybaits plus自带的查询方法,doGetAuthorizationInfo这个方法本篇不涉及到,可以不用看.

4.配置过滤器 拦截过滤 规则.同时配置shiro其他配置

package com.springboot.blog.config;

import com.springboot.blog.interceptor.CustomRealm;
import com.springboot.blog.interceptor.ShiroLoginFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    /**
     * 密码校验规则HashedCredentialsMatcher
     * 这个类是为了对密码进行编码的 ,
     * 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,
     * 这个类也负责对form里输入的密码进行编码
     * 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        //Shiro自带加密
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //散列算法使用md5
        credentialsMatcher.setHashAlgorithmName("md5");
        //散列次数,1表示md5加密1次
        credentialsMatcher.setHashIterations(1);
        credentialsMatcher.setStoredCredentialsHexEncoded(true);
        return credentialsMatcher;
    }

    //将自己的验证方式加入容器
    @Bean
    public CustomRealm myShiroRealm() {
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());//将自己的验证方式加入容器
        return customRealm;
    }

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    //Filter工厂,设置对应的过滤条件和跳转条件
    /*
     * @Shiro内置过滤器
     * anon         org.apache.shiro.web.filter.authc.AnonymousFilter
     * authc        org.apache.shiro.web.filter.authc.FormAuthenticationFilter
     * authcBasic   org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
     * perms        org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
     * port         org.apache.shiro.web.filter.authz.PortFilter
     * rest         org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
     * roles        org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
     * ssl          org.apache.shiro.web.filter.authz.SslFilter
     * user         org.apache.shiro.web.filter.authc.UserFilter
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<>();
        Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
        //filters.put("authc", new ShiroLoginFilter());//添加自定义拦截器
        //修改退出重定向页面
        LogoutFilter logout = new LogoutFilter();
        logout.setRedirectUrl("/admin/login");
        filters.put("logout", logout);
        map.put("/admin/**", "authc");
        map.put("/admin/logout", "logout");
        map.put("/**", "anon");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/admin/login");
        //错误页面,认证不通过跳转
//        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }


    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }


}

5.shiro登录完成.

附上代码:https://gitee.com/my4vsy/springboot-blog/tree/v2.1

参考资料:https://www.jianshu.com/p/7f724bec3dc3
以及网上大佬教程!

Tags: shiro springboot

很赞哦! (12)

文章评论

站点信息

  • 建站时间:2019-10-24
  • 网站程序:Thinkphp6 Layui
  • 文章统计247篇文章
  • 标签管理标签云
  • 统计数据cnzz统计
  • 微信公众号:扫描二维码,关注我们