SpringBoot与Shiro整合实现用户认证登录

Shiro的基本概念

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

Shiro的三大核心API

1、subject:用户主体
2、SecurityManager:安全管理器(管理所有的subject,关联Realm)
3、Realm:连接数据的桥梁(连接数据库)

Shiro整合SpringBoot步骤

1、导入shiro与spring整合的依赖:

<!-- 导入shiro与spring整合的依赖: -->
     <dependency>
       <groupId>org.apache.shiro</groupId>
       <artifactId>shiro-spring</artifactId>
       <version>1.5.2</version>
     </dependency>

SpringBoot与Shiro整合实现用户认证登录_第1张图片
2、自定义Relam类(编写一下查询方法与完成一些授权逻辑认证)

package com.gzmu.config;

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;

/**
 * 自定义Realm
 * 需要继承AuthorizingRealm类
 * 会实现两个方法
 * @author jojo
 *
 */
public class MyRealm extends AuthorizingRealm{

	/**
	 * 执行授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 执行认证逻辑
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg) throws AuthenticationException {
		System.out.println("执行认证"+arg);
		//假设获取数据库用户名与密码
		String name = "wuhui";;
		String password = "123";
		//编写Shiro判断逻辑,判断用户名与密码
		//判断用户名
		UsernamePasswordToken token = (UsernamePasswordToken)arg;
		//如果返回的值与数据库中是用户名不匹配
		if(!token.getUsername().equals(name)) {
			//shiro底层会抛出一个异常
			return null;
		}
		//判断密码
		return new SimpleAuthenticationInfo("",password,"");
	}
	
}


3、编写Shiro的配置类(ShiroConfig)

package com.gzmu.config;

import java.util.LinkedHashMap;

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();
		//设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		
		//添加Shiro内置过滤器
		/**
		 * Shiro内置过滤器,可以实现权限相关的拦截器
		 * 常用的有:
		 * 	anon:无需认证就能访问
			authc:必须认证才能访问
			user:必须拥有 “记住我” 功能才能使用
			perms:拥有对某个资源的权限才能访问
			role: 拥有对某个角色权限才能访问
		 */
		LinkedHashMap<String, String> filterMap = new LinkedHashMap<String,String>();
//		filterMap.put("/add", "authc");
//		filterMap.put("/update", "authc");
		//放行的用户放在前面
		filterMap.put("/test", "anon");
		filterMap.put("/login", "anon");
		filterMap.put("/*", "authc");
		
		//修改登录页面
		shiroFilterFactoryBean.setLoginUrl("/toLogin");
		
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
		
		return shiroFilterFactoryBean;
	}
	
	/**
	 * 创建DefaultWebSecurityManager
	 */
	@Bean(name="securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("MyRealm") MyRealm myRealm) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		//关联Realm
		securityManager.setRealm(myRealm);
		return securityManager;
	}
	
	/**
	 * 创建Realm对象(第一步)
	 * @Bean 将方法返回的对象放入Sprin环境进行管理
	 */
	@Bean(name="MyRealm")
	public MyRealm myRealm() {
		return new MyRealm();
	}
	
}


4、设置controller测试:

package com.gzmu.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
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.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {
	
	/**
	 * 测试方法
	 * @return
	 */
	@RequestMapping("/add")
	public String add() {
		System.out.println("usercontroller.add");
		return "/user/add";
	}
	
	@RequestMapping("/update")
	public String update() {
		System.out.println("usercontroller.update");
		return "/user/update";
	}
	
	/**
	 * 设置登录跳转页面
	 * @return
	 */
	@RequestMapping("/toLogin")
	public String toLogin() {
		System.out.println("usercontroller.toLogin");
		return "login";
	}
	
	/**
	 * 测试thymeleaf页面是否可用
	 */
	@GetMapping("/test")
	public String testThymeleaf(Model model) {
		
		model.addAttribute("name","huihui");
		
		return "test";
		
	}
	
	/**
	 * 登录逻辑处理
	 * @return
	 */
	@RequestMapping("/login")
	public String login(String name,String password,Model model) {
		/**
		 * 获取Shiro编写认证操作
		 */
		//1、获取Subject
		Subject subject = SecurityUtils.getSubject();
		//2、封装用户数据
		UsernamePasswordToken token = new UsernamePasswordToken(name,password);
		//执行登录方法
		try {
			//登录成功
			subject.login(token);
			//跳转到test.html
			return "redirect:test";
		} catch (UnknownAccountException e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			//登录失败: 用户名不存在
			model.addAttribute("msg","用户名不存在");
			return "login";
		}catch (IncorrectCredentialsException e) {
			//登录失败: 用户名不存在
			model.addAttribute("msg","密码错误");
			return "login";
		}
		
	}
	
}

5、添加静态html:
SpringBoot与Shiro整合实现用户认证登录_第2张图片

6、运行启动类:

package com.gzmu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 
 * @author jojo
 *
 */
@SpringBootApplication
public class Application {
	
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
} 

7、结果:
SpringBoot与Shiro整合实现用户认证登录_第3张图片

SpringBoot与Shiro整合实现用户认证登录_第4张图片
登录之后没进行拦截可进行访问

你可能感兴趣的:(SpringBoot,Shiro)