SpringBoot整合Shiro

基本步骤:

添加pom文件依赖
书写自定义的realm
配置shiro
控制层使用
 

1.添加pom文件依赖

<!-- spring整合shiro -->
<!-- maven会自动添加shiro-core,shiro-web依赖 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.3.2</version>
</dependency>


2.书写自定义realm

package com.diit.business.interceptor;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.realm.AuthorizingRealm;

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

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.diit.business.entity.User;
import com.diit.business.service.AdminService;


/**
 * 
 * @ClassName: MyRealm
 * @Description: 自定义realm
 * @date 
 */
public class MyRealm extends AuthorizingRealm {
	
	//用于用户查询
    @Autowired
    private AdminService adminService;

	
	/**
     * 用于认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        

        //加这一步的目的是在Post请求的时候会先进认证,然后在到请求
        if (token.getPrincipal() == null) {
            return null;
        }

      //获取用户信息
        String name = token.getPrincipal().toString();
        String password=new String((char[])token.getCredentials()); 	//得到密码
  
       
        return new SimpleAuthenticationInfo(name, password, this.getName());
    }

    /**
     * 用于授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("使用了自定义的realm,用户授权...");

        // 获取用户名
        // String userName = (String) principals.getPrimaryPrincipal();
        // 依据用户名在数据库中查找权限信息

        // 角色
        List<String> roles = new ArrayList<>();
        roles.add("admin");
        roles.add("user");
        // 权限
        List<String> permissions = new ArrayList<>();
        permissions.add("admin:select");
        permissions.add("admin:delete");

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissions);
        simpleAuthorizationInfo.addRoles(roles);
        return simpleAuthorizationInfo;
    }

}


3.配置shiro

package com.diit.business.interceptor;

import java.util.HashMap;
import java.util.LinkedHashMap;
/**
 * Shiro配置Bean
 */
import java.util.Map;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;

 /**
  * 
  * @ClassName: ShiroConfig
  * @Description: spring整合shiro配置
  * @author cheng
  * @date 2017年10月10日 上午9:46:43
  */
 @Configuration
 public class ShiroConfig {

     /**
      * 
      * @Title: createMyRealm
      * @Description: 自定义的realm
      * @return
      */
     @Bean
     public MyRealm createMyRealm() {
         // 加密相关
         HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
         // 散列算法
         hashedCredentialsMatcher.setHashAlgorithmName("MD5");
         // 散列次数
         hashedCredentialsMatcher.setHashIterations(1);
         MyRealm myRealm = new MyRealm();
         //myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
         return myRealm;
     }

     /**
      * 
      * @Title: securityManager
      * @Description: 注入自定义的realm
      * @Description: 注意方法返回值SecurityManager为org.apache.shiro.mgt.SecurityManager
      *               ,不要导错包
      * @return
      */
     @Bean
     public SecurityManager securityManager() {
         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
         securityManager.setRealm(createMyRealm());
         return securityManager;
     }

     /**
      * 
      * @Title: shirFilter
      * @Description: Shiro 的Web过滤器
      * @param securityManager
      * @return
      */
     @Bean
     public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
         shiroFilterFactoryBean.setSecurityManager(securityManager);

         // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/userLogin");
         // 登录成功后要跳转的链接,建议不配置,shiro认证成功自动到上一个请求路径
        shiroFilterFactoryBean.setSuccessUrl("/index");
         // 未授权界面,指定没有权限操作时跳转页面
         shiroFilterFactoryBean.setUnauthorizedUrl("/403");

         // 过滤器
         Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
         // 配置不会被过滤的链接 顺序判断
         // 过虑器链定义,从上向下顺序执行,一般将/**放在最下边
         // 对静态资源设置匿名访问
         // anon:所有url都都可以匿名访问
         filterChainDefinitionMap.put("/static/**", "anon");
         // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
         filterChainDefinitionMap.put("/logout", "logout");
         // authc:所有url都必须认证通过才可以访问
         filterChainDefinitionMap.put("/**", "anon");
         shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
         return shiroFilterFactoryBean;
     }
     
     /**
      * @description: shiro web过滤器
      * @author cheng
      * @dateTime 2018/4/18 15:50
      */
     @Bean
     public ShiroFilterFactoryBean createShiroFilter(SecurityManager securityManager) {
         ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
         shiroFilterFactoryBean.setSecurityManager(securityManager);
         // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
         shiroFilterFactoryBean.setLoginUrl("/v1/toLoginPage");

         // 过滤器
         Map<String, String> filterChainDefinitionMap = new HashMap<>();
         // 配置不会被过滤的链接 顺序判断
         // 过虑器链定义,从上向下顺序执行,一般将/**放在最下边
         // 用户注册匿名访问
         filterChainDefinitionMap.put("/v1/users/", "anon");
         // 管理员登录页面
         filterChainDefinitionMap.put("/v1/toLoginPage", "anon");
         // 管理员登录
         filterChainDefinitionMap.put("/v1/login", "anon");
         // 对静态资源设置匿名访问
         // anon:所有url都都可以匿名访问
         filterChainDefinitionMap.put("/static/**", "anon");

         // authc:所有url都必须认证通过才可以访问
         filterChainDefinitionMap.put("/**", "anon");
         shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
         return shiroFilterFactoryBean;
     }
     
   //加入注解的使用,不加入这个注解不生效
     @Bean
     public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
         AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
         authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
         return authorizationAttributeSourceAdvisor;
     }

}


代码说明: 
1.自定义的realm和注入自定义的realm相当于以前的shiro.ini文件#自定义的realm
myRealm=com.ahut.test.MyRealm
# 注入自定义的realm
securityManager.realms=$myRealm

4.控制层使用
 

@RestController
public class ShiroAction {

    /**
     * 
     * @Title: userLogin
     * @Description: 用户登录
     * @return
     */
    @RequestMapping(value = "/userLogin")
    public String userLogin(String username, String password) {

        // 以下部分在配置阶段就已经完成,可以直接使用
        // 读取配置文件
        // Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 获取SecurityManager的实例
        // SecurityManager securityManager = factory.getInstance();
        // 把 securityManager 的实例绑定到 SecurityUtils 上
        // SecurityUtils.setSecurityManager(securityManager);

        System.out.println(username + ":" + password);
        Subject subject = SecurityUtils.getSubject();
        // 自己创建一个令牌,输入用户名和密码
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
        try {
            subject.login(usernamePasswordToken);
            System.out.println("身份认证成功!");

        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("账号不存在!");

        } catch (LockedAccountException e) {
            e.printStackTrace();
            System.out.println("账号被锁定!");

        } catch (DisabledAccountException e) {
            e.printStackTrace();
            System.out.println("账号被禁用!");

        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("凭证/密码错误!");

        } catch (ExpiredCredentialsException e) {
            e.printStackTrace();
            System.out.println("凭证/密码过期!");

        } catch (ExcessiveAttemptsException e) {
            e.printStackTrace();
            System.out.println("登录失败次数过多!");

        }

        // 是否认证通过
        boolean isAuthenticated1 = subject.isAuthenticated();
        System.out.println("登录后,是否认证通过:" + isAuthenticated1);

        // 退出
        subject.logout();

        // 是否认证通过
        boolean isAuthenticated2 = subject.isAuthenticated();
        System.out.println("退出登录后,是否认证通过:" + isAuthenticated2);

        return "处理登录";
    }

}



可能出现的问题
页面加载css或者js时,出现以下错误:Resource interpreted as Stylesheet but transferred with MIME type text/html 
原因:shiro配置原因,对需要认证的资源进行了拦截操作

// authc:所有url都必须认证通过才可以访问
filterChainDefinitionMap.put("/**", "authc");

修改以上代码为:
filterChainDefinitionMap.put("/**", "anon");
完整代码:

    /**
     * @description: shiro web过滤器
     * @author cheng
     * @dateTime 2018/4/18 15:50
     */
    @Bean
    public ShiroFilterFactoryBean createShiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/v1/toLoginPage");

        // 过滤器
        Map<String, String> filterChainDefinitionMap = new HashMap<>();
        // 配置不会被过滤的链接 顺序判断
        // 过虑器链定义,从上向下顺序执行,一般将/**放在最下边
        // 用户注册匿名访问
        filterChainDefinitionMap.put("/v1/users/", "anon");
        // 管理员登录页面
        filterChainDefinitionMap.put("/v1/toLoginPage", "anon");
        // 管理员登录
        filterChainDefinitionMap.put("/v1/login", "anon");
        // 对静态资源设置匿名访问
        // anon:所有url都都可以匿名访问
        filterChainDefinitionMap.put("/static/**", "anon");

        // authc:所有url都必须认证通过才可以访问
        filterChainDefinitionMap.put("/**", "anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }


转载自:https://blog.csdn.net/qq_28988969/article/details/78190869 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值