springboot加shiro用户认证集成

1、简介

shiro是由apache基金会旗下的强大的安全校验框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,从最小的移动应用程序到最大的网络和企业应用程序。本博客展示一个用户认证的demo,看看用shiro怎么来做用户认证的。

2、maven依赖

这里的sprigboot的版本是2.1.6.RELEASE

    
      org.springframework.boot
      spring-boot-starter-web
    
    
      com.alibaba
      fastjson
      1.2.36
    
    
      org.apache.shiro
      shiro-spring
      1.4.0
    
    
      org.apache.tomcat.embed
      tomcat-embed-jasper
    

3、sql

用户信息表

CREATE TABLE `userinfo` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `user_name` varchar(64) DEFAULT NULL,
  `name` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL,
  `salt` varchar(32) DEFAULT NULL,
  `status` smallint(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4、springboot 配置shiro

shiroConfig.java

package com.example.demo2.config;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
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.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

/**
 * @author yy
 * @version 1.0.0
 * 
    *
  • project : demo2
  • *
  • package : com.example.demo2.config
  • *
* @since 2019/7/23 15:59 **/ @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){ System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map filterChainDefinitionMap = new LinkedHashMap(); // 配置不会被拦截的链接 顺序判断 filterChainDefinitionMap.put("/static/**", "anon"); //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); //:这是一个坑呢,一不小心代码就不好使了; // filterChainDefinitionMap.put("/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public MyShiroRealm myShiroRealm(){ MyShiroRealm myShiroRealm = new MyShiroRealm(); myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } @Bean public HashedCredentialsMatcher hashedCredentialsMatcher(){ HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); //散列算法:这里使用MD5算法; hashedCredentialsMatcher.setHashAlgorithmName("md5"); //散列的次数,比如散列两次,相当于 md5(md5("")); hashedCredentialsMatcher.setHashIterations(2); return hashedCredentialsMatcher; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @Bean(name="simpleMappingExceptionResolver") public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() { SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.setProperty("DatabaseException", "databaseError"); mappings.setProperty("UnauthorizedException","403"); r.setExceptionMappings(mappings); r.setDefaultErrorView("error"); r.setExceptionAttribute("ex"); return r; } }

MyshiroRealm.java

package com.example.demo2.config;

import com.stock.stockapi.dto.UserInfoDTO;
import com.stock.stockapi.dto.UserRoleDTO;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
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.realm.SimpleAccountRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

/**
 * @author K0171005
 * @version 1.0.0
 * 
    *
  • project : demo2
  • *
  • package : com.example.demo2.config
  • *
* @since 2019/7/23 16:03 **/ @Slf4j public class MyShiroRealm extends AuthorizingRealm { @Autowired RestTemplate restTemplate; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); UserInfoDTO userInfoDTO = (UserInfoDTO)principalCollection.getPrimaryPrincipal(); HttpEntity entity = new HttpEntity<>(userInfoDTO); ResponseEntity responseEntity = restTemplate. getForEntity("http://localhost:8080/stock/save", Boolean.class, ""); return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String userName = (String) token.getPrincipal(); log.info("当前用户token {}", token.getCredentials()); QueryUserInfoReqDTO reqDTO = new QueryUserInfoReqDTO(); reqDTO.setUserName(userName); UserInfoDTO userInfoDTO = restTemplate.postForObject("http://localhost:8080/user/queryUserByName", reqDTO, UserInfoDTO.class); if (userInfoDTO != null) { SimpleAuthenticationInfo authorizationInfo = new SimpleAuthenticationInfo(userInfoDTO, userInfoDTO.getPassword(), getName()); return authorizationInfo; } return null; } }

我这里直接用来restful来提供远程服务,大家也可以在项目中使用其他的远程过程调用,(例如dubbo,不过需要搭建注册中心,本人闲麻烦)
下面来介绍一些几个主要bean的作用。
ShiroFilterFactoryBean 的作用主要是用来拦截需要验证的url。可以看到上面配置了登录拦截,以及权限验证拦截,和验证通过之后跳转的页面。
MyShiroRealm
这个是自定义的Realm,继承了shiro的AuthorizingRealm,其中有两个重要的方法,一个是doGetAuthorizationInfo(权限校验),一个是doGetAuthenticationInfo(认证校验),在ShiroFilterFactoryBean 中配置的拦截url,都会经过这两个方法的校验。也是shiro的核心方法。

结语:
以上就是本人最近学习shiro的例子,希望能给大家带来帮助。

你可能感兴趣的:(JAVA)