自学SpringBoot整合Shiro安全框架(二)

一、新建pageController:
        因为SpringBoot项目无法直接访问页面,所以需要配置pageController进行页面的转跳,且Controller层所在的
    类不能比启动类层级高或者同级,否则无法自动扫描(如果Controller层所在的类比启动类层级高或者同级可以在启
    动类上使用注解@ComponentScan(basePackages = {"包名1", "包名2", ...})指定Controller层所在的包Springboot
    2.0.5.RELEASE以上版本支持)。以下展示pageController里面的方法写法:
    
    @RequestMapping("/login")// 请求路径
    public String login() {
        return "login";// 需要返回的页面
    }
二、新建ShiroConfig类用来配置Shiro、UserRealm类用来和数据库交互用来执行认证逻辑和授权逻辑、LoginController用来与前台登录请求交互:
    网络图解Shiro执行流程:

三个核心组件:Subject、SecurityManager和Realms。
Subject:
        即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐(DaemonAccount)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
SecurityManager:
        它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm:
        Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

1、创建ShiroConfig类:

package com.kingduns.pertes.config.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {

	/**
	 *	 创建ShiroFilterFactoryBean
	 */
	@Bean
	public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		// 1、设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		// 2、设置Shiro内置的安全过滤器,来对相关权限进行拦截
		/**
		 * 	常用过滤器
		 * 		anon:无需认证(登录)可以访问
		 * 		authc:必须认证才可以访问
		 * 		user:如果使用rememberMe的功能可以直接访问
		 * 		perms:该资源必须得到资源权限才可以访问
		 * 		role:该资源必须得到角色权限才可以访问
		 */
		Map<String, String> filterMap = new LinkedHashMap<String, String>();
		/**
		 * 	资源权限过滤器
		 */
		filterMap.put("/user/addUser", "perms[user:add]");
		/*filterMap.put("/addUser", "authc");
		filterMap.put("/updateUser", "authc");*/
		/**
		 * 	若一个文件夹下的所有页面全部需要拦截可采用通配符
		 */
		filterMap.put("/user/*", "authc");
		filterMap.put("/rsat/login/getLogin", "anon");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
		// 3、没有权限访问时,转跳到登录页面
		shiroFilterFactoryBean.setLoginUrl("/login");
		return shiroFilterFactoryBean;
	}

	/**
	 * 	创建DefaultWebSecurityManager
	 * 
	 * @return
	 */
	@Bean(name="securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(userRealm);
		return securityManager;
	}

	/**
	 *	 创建Realm
	 * 
	 * @return
	 */
	@Bean(name="userRealm")
	public UserRealm getRealm() {
		return new UserRealm();
	}
}

2、创建UserRealm类继承AuthorizingRealm:

package com.kingduns.pertes.config.shiro;

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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.kingduns.pertes.common.bean.User;
import com.kingduns.pertes.login.service.LoginService;

/**
 * 自定义Realm
 * 
 * @author Administrator
 *
 */
public class UserRealm extends AuthorizingRealm {

	@Autowired
	private LoginService loginService;

	/**
	 * 执行授权逻辑
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("执行授权逻辑");
		return null;
	}

	/**
	 * 执行认证逻辑(认证用户名和密码)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 1、获取前端页面传过来的用户数据
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		// 2、查询数据库
		User user = loginService.getUserByAccountNumber(usernamePasswordToken.getUsername());
		if (user == null) {
			// 用户不存在返回null,shiro会报UnknownAccountException
			return null;
		} else {
			SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo("", user.getPassword(), "");
			return simpleAuthenticationInfo;
		}
	}

}

3、创建LoginController:

​
package com.kingduns.pertes.login.controller;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.kingduns.pertes.common.bean.User;
import com.kingduns.pertes.config.bean.ReturnBean;
import com.kingduns.pertes.login.service.LoginService;

/**
 * 用户登录相关业务
 * 
 * @author Administrator
 *
 */
@RestController
@RequestMapping("rsat/login")
public class LoginController {

	@Autowired
	private LoginService loginService;

	/**
	 * 登录
	 * 
	 * @param accountNumber 账号
	 * @param passWord      密码
	 * @return
	 */
	@RequestMapping("getLogin")
	public ReturnBean<User> getLogin(String accountNumber, String passWord, String referrer) {
		/*User user = loginService.getLogin(accountNumber, passWord);
		if (user != null) {
			return new ReturnBean<User>(ReturnBean.SUCCESS, "登录成功!", user);
		} else {
			return new ReturnBean<User>(ReturnBean.FAIL, "登录失败!", null);
		}*/
		System.out.println("accountNumber:" + accountNumber);
		System.out.println("passWord:" + passWord);
		System.out.println("referrer:" + referrer);
		// 1、获取Subject
		Subject subject = SecurityUtils.getSubject();
		// 2、封装用户数据
		UsernamePasswordToken token = new UsernamePasswordToken(accountNumber, passWord);
		// 3、执行登录方法
		try {// 若没有出现异常,则登陆成功!
			subject.login(token);
			return new ReturnBean<User>(ReturnBean.SUCCESS, "登录成功!", null);
		} catch (UnknownAccountException e) {
			//	用户名不存在
			return new ReturnBean<User>(ReturnBean.FAIL, "登录失败,该用户名不存在!", null);
		} catch (IncorrectCredentialsException e) {
			//	密码错误
			return new ReturnBean<User>(ReturnBean.FAIL, "登录失败,密码错误!", null);
		}
	}
}

​

以上操作实现了SpringBoot+Shiro+Mybatis用户登录认证

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值