Shiro练习小Demo(SpringBoot)

本Demo是用SpringBoot+Mybatis+Shiro
省略创建SpringBoot的截图流程
导入jar包

 <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>

整个项目结构

shiro一般都在service(业务层)内
CredentialMatcher类是自定义登陆验证规则
AuthRealm类是每次登陆授权时需要使用的类
shiroConfiguration类是shiro的总配置文件
从大到小的顺序是 shiroConfiguration→AuthRealm→CredentialMatcher

CredentialMatcher

package com.hjy.serivce;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;

/**
 * 自定义登陆检验规则
 */
public class CredentialMatcher extends SimpleCredentialsMatcher {

    //自定义验证规则
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) token;
        //session的密码
        String password =new String(usernamePasswordToken.getPassword());
        //数据库对应的密码
        String dePassword=info.getCredentials().toString();
        //返回对比结果
        return this.equals(password,dePassword);
    }
}

AuthRealm
PS:我的dao和service只写一个方法就是通过传用户名来查找对应用户角色权限信息

package com.hjy.serivce;

import com.hjy.entity.Permission;
import com.hjy.entity.Role;
import com.hjy.entity.Users;
import org.apache.commons.collections.CollectionUtils;
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.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 验证授权类
 */

public class AuthRealm extends AuthorizingRealm {

    @Autowired(required = false)
    private UsersService usersService;

    //授权(每次验证权限或角色都会走这个方法)
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //从session里面获取当前用户
        Users users=(Users) principalCollection.fromRealm(this.getClass().getName()).iterator().next();
        //存放给info添加所有关系集合
        List<String> permissionList=new ArrayList<>();
        //所有角色集合
        Set<Role> roleSet=users.getRoles();
        //存放给info添加的角色集合
        List<String> roleNameList=new ArrayList<>();
        //判断角色是否为空
        if (CollectionUtils.isNotEmpty(roleSet)){
            for (Role role : roleSet){
                //获取所有角色信息后添加进集合(存放到info)
                roleNameList.add(role.getRname());
                //获取所有关系集合
                Set<Permission> permissionSet=role.getPermissions();
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(permissionSet)){
                    for (Permission permission:permissionSet){
                        //获取所有权限后添加进集合
                        permissionList.add(permission.getName());
                    }
                }
            }
        }
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionList);
        info.addRoles(roleNameList);
        System.out.println("授权");
        return info;
    }

    //认证登陆
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) authenticationToken;
        String username=usernamePasswordToken.getUsername();
        Users users=usersService.findByUsersName(username);
        System.out.println("登陆");
        return new SimpleAuthenticationInfo(users,users.getPassword(),this.getClass().getName());
    }

    public UsersService getUsersService() {
        return usersService;
    }

    public void setUsersService(UsersService usersService) {
        this.usersService = usersService;
    }
}

shiroConfiguration

package com.hjy.serivce;

import org.apache.shiro.mgt.SecurityManager;
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.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

/**
 * shiro配置整合
 * 最下面是底层,依次向上
 */
@Configuration
public class ShiroConfiguration {

    //把SecurityManager放入Filter过滤内,并配置过滤规则
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //注销后跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        //登陆成功后跳转的页面
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");

        //配置过滤规则(过滤规则搜索DefaultFilter,apache的)
        LinkedHashMap<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
        filterChainDefinitionMap.put("/index","authc");
        filterChainDefinitionMap.put("/login","anon");
        filterChainDefinitionMap.put("/loginUser","anon");
        //下面这个只是允许admin角色用户访问
        filterChainDefinitionMap.put("/admin","roles[admin]");
        //只允许拥有该权限的人才能访问
        filterChainDefinitionMap.put("/edit","perms[edit]");

        filterChainDefinitionMap.put("/**","user");
        //把规则添加到shiroFilter内
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    //把authRealm放入SecurityManager里面
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm){
        DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        return manager;
    }

    //把自定义规则通过参数从Spring里面拿出来用
    @Bean("authRealm")
    public AuthRealm authRealm(@Qualifier("credentialMatcher")CredentialMatcher credentialMatcher){
        AuthRealm authRealm=new AuthRealm();
        //把自定义规则发放如Realm内
        authRealm.setCredentialsMatcher(credentialMatcher);
        return  authRealm;
    }

    //前面的自定义规则(这是一个类)
    @Bean("credentialMatcher")
    public CredentialMatcher credentialMatcher(){
        return new CredentialMatcher();
    }


    //下面两个是关联配置
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor=new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }
}

Controller层

package com.hjy.controller;

import com.hjy.entity.Users;
import com.hjy.serivce.UsersServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Controller
public class UsersController {

    @Resource
    private UsersServiceImpl usersService;

    public UsersServiceImpl getUsersService() {
        return usersService;
    }

    public void setUsersService(UsersServiceImpl usersService) {
        this.usersService = usersService;
    }

   /* @RequestMapping("/text")
    public String text(){
        return JSONArray.toJSONString(usersService.findByUsersName("admin"));
    }*/

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

    @RequestMapping("/index")
    public String index(){
        return "index";
    }

    @RequestMapping("/logout")
    public String logout(){
        Subject subject=SecurityUtils.getSubject();
        if (subject!=null){
            subject.logout();
        }
        return "redirect:/login";
    }
    @GetMapping
    @ResponseBody
    public String admin(){
        return "只有admin才能看到的";
    }

    //登陆认证
    @RequestMapping("/loginUser")
    public String loginUsers(@RequestParam("username")String username,
                             @RequestParam("password")String password,
                             HttpServletRequest request){
        //传入用户名和密码进去
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
        Subject subject=SecurityUtils.getSubject();
        try {
            //开始认证,若出错则会catch
            subject.login(usernamePasswordToken);
            //获得对象
            Users users=(Users) subject.getPrincipal();
            //把对象放入session内
            request.getSession().setAttribute("users",users);
            //成功则返回index页面
            return "redirect:/index";
        } catch (Exception e) {
            //失败则返回到login页面
            return "redirect:/login";
        }
    }

    @GetMapping("/edit")
    @ResponseBody
    public String edit(){
        return "edit返回信息";
    }

    @GetMapping("unauthorized")
    public String unauthorized(){
        return "unauthorized";
    }
}

这是本次Demo的码云下载地址https://gitee.com/chijj/shiroDemo1.git

猜你喜欢

转载自blog.csdn.net/chijiajing/article/details/85013321