SpingBoot+Shiro完成基础登录校验


前言

Shiro相对于Spring Security来说是一个更加轻量级的登录认证框架
Shiro 可以完成:认证、授权、加密、会话管理、与Web 集成、缓存等相关操作。
本片文章记录一下我们在SpringBoot中使用Shiro的过程

一、环境准备

1、搭建Spring项目,Maven导入相关包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.6.0</version>
</dependency>

2、相关的实体,服务,接口编写

LoginController

@Slf4j
@RestController
public class LoginController {

	@GetMapping("/login")
	public String login(User user) {
		if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())) {
			return "请输入用户名和密码!";
		}
		//获取用户认证信息
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
				user.getUserName(),
				user.getPassword()
		);
		try {
			//进行验证,这里可以捕获异常,然后返回对应信息
			subject.login(usernamePasswordToken);
		} catch (UnknownAccountException e) {
			log.error("用户名不存在!", e);
			return "用户名不存在!";
		} catch (AuthenticationException e) {
			log.error("账号或密码错误!", e);
			return "账号或密码错误!";
		} catch (AuthorizationException e) {
			log.error("没有权限!", e);
			return "没有权限";
		}
		return "login success";
	}
}

ILoginService

public interface ILoginService {
	/**
	 * 通过用户名获取密码
	 * @param getMapByName
	 * @return
	 */
	User getUserByName(String getMapByName);
}

LoginServiceImpl

@Service
public class LoginServiceImpl implements ILoginService {

	@Autowired 
	UserMapper usermapper;
	@Override
	public User getUserByName(String name) {
		return usermapper.selectByName(name);
	}
}

二、Shiro相关配置

1.编写自定义规则Realm

MyRealm

public class MyRealm extends AuthorizingRealm {

	@Autowired
	private ILoginService loginService;

	/**
	 * 授权
	 * @param principalCollection
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		//获取登录用户名
		String name = (String) principalCollection.getPrimaryPrincipal();
		//查询用户名称
		User user = loginService.getUserByName(name);
		//添加角色和权限
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		for (Role role : user.getRoles()) {
			//添加角色
			simpleAuthorizationInfo.addRole(role.getRoleName());
			//添加权限
			for (Permissions permissions : role.getPermissions()) {
				simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
			}
		}
		return simpleAuthorizationInfo;
	}

	/**
	 * @MethodName doGetAuthenticationInfo
	 * @Description 认证配置类
	 * @Param [authenticationToken]
	 * @Return AuthenticationInfo
	 * @Author WangShiLin
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
		if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
			return null;
		}
		//获取用户信息
		String name = authenticationToken.getPrincipal().toString();
		User user = loginService.getUserByName(name);
		if (user == null) {
			//这里返回后会报出对应异常
			return null;
		} else {
			//这里验证authenticationToken和simpleAuthenticationInfo的信息
			SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
			return simpleAuthenticationInfo;
		}
	}
}

2.编写自定义的Shiro配置规则

package com.zukxu.sources.config.shiro;

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.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * Description:
 *
 * @author zukxu
 * @date 2020/10/27 0027 16:16
 */
@Configuration
public class ShiroConfig {
	@Bean
	@ConditionalOnMissingBean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator defaultAPP = new DefaultAdvisorAutoProxyCreator();
		defaultAPP.setProxyTargetClass(true);
		return defaultAPP;
	}

	/**将自己的验证方式加入容器*/
	@Bean
	public MyRealm myShiroRealm() {
		MyRealm realm = new MyRealm();
		return realm;
	}

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

	/**Filter工厂,设置对应的过滤条件和跳转条件*/
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		Map<String, String> map = new HashMap<>();
		//登出
		map.put("/logout", "logout");
		//对所有用户认证
		map.put("/**", "authc");
		//登录
		shiroFilterFactoryBean.setLoginUrl("/login");
		//首页
		shiroFilterFactoryBean.setSuccessUrl("/index");
		//错误页面,认证不通过跳转
		shiroFilterFactoryBean.setUnauthorizedUrl("/error");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;
	}


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

总结

Shiro初步搭建使用

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页