Spring boot 整合 shiro 的简单例子

版权声明:本文为博主原创文章,转载请附上原文链接。 https://blog.csdn.net/Jayszxs/article/details/80888866

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


模拟用户登录情况:

ShiroConfiguration.java [shiro配置信息]

package jz.shiro.config;

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

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

import jz.shiro.realm.UserRealm;

/**
 * @package: jz.shiro.config 
 * @Title: ShiroConfiguration 
 * @Description: shiro配置信息类
 * @author 周华波(Jayszxs)
 * @email [email protected]
 * @date 2018年7月2日 下午5:40:07
 */
@Configuration
public class ShiroConfiguration {

	/**
	 * @Title: userRealm 
	 * @Description: 自定义认证领域
	 * @return 
	 * @author 周华波(Jayszxs)
	 * @email [email protected]
	 * @Date 2018年7月2日 下午5:58:18
	 */
	@Bean
	public UserRealm userRealm() {
		UserRealm userRealm = new UserRealm();
		return userRealm;
	}

	/**
	 * @Title: securityManager 
	 * @Description: 托管自定义的验证领域
	 * @return 
	 * @author 周华波(Jayszxs)
	 * @email [email protected]
	 * @Date 2018年7月2日 下午7:38:37
	 */
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
		defaultWebSecurityManager.setRealm(userRealm());
		return defaultWebSecurityManager;
	}

	//设置对应的过滤条件和跳转条件
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		
		//未认证跳转到的登录页面
		shiroFilterFactoryBean.setLoginUrl("/login.html");
		shiroFilterFactoryBean.setUnauthorizedUrl("/");
		/*
		 * 首页 其实没有多大的作用,只是做为一种附加配置
		 *  比如,在访问的地址是:https://xxxx.xxxx.xxxx/abc.html则验证通过之后,系统就会访问到abc.html页面,而不去访问index.html
		 *  如果认证成功之后,也会在前端页面做请求到index页面上
		 *  【以上都属于个人观点,如有不同见解,欢迎留言探讨】
		 */
		//shiroFilterFactoryBean.setSuccessUrl("/index");
		//错误页面,认证不通过跳转
		//shiroFilterFactoryBean.setUnauthorizedUrl("/error.html");
		
		Map<String,String> map = new HashMap<String, String>();
		/*
		 *  authc 需要验证
		 *  anon 不需要验证
		 */
		map.put("/login.html","anon");
		map.put("/statics/**", "anon");
		map.put("/sys/login", "anon");
		map.put("/favicon.ico", "anon");
		map.put("/captcha.jpg", "anon");
		map.put("/**","authc"); // 对所有的地址都需要认证 一定要按照顺序来 先放开的地址,在闭合的地址
	
		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;
	}

	// 开启注解
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

}

UserRealm.java [用户认证领域]

package jz.shiro.realm;

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;

/**
 * @package: jz.shiro.realm 
 * @Title: UserRealm 
 * @Description: 用户认证领域
 * @author 周华波(Jayszxs)
 * @email [email protected]
 * @date 2018年7月2日 下午5:41:11
 */
public class UserRealm extends AuthorizingRealm {

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

	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 获取用户名和密码
		UsernamePasswordToken utoken =  (UsernamePasswordToken) token;
		String userName = utoken.getUsername();
		/**
		 * 通过用户名可以去DB中获取该用户的正确对应的信息,然后将信息放入shiro中,并调用CredentialsMatcher校验密码
		 */
		return new SimpleAuthenticationInfo(userName,"123456",this.getName()); // 存放的是用户正确的相关信息
	}

}

ShiroController.java [控制器]

package jz.shiro.test;

import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Maps;

@RestController
@RequestMapping("/login")
public class ShiroController {

	@RequestMapping(method=RequestMethod.GET)
	public Map<String,Object> index(String name, String password) {
		Map<String,Object> result = Maps.newHashMap();
		
		if(StringUtils.isBlank(name) || StringUtils.isBlank(password)) {
			result.put("status", "500");
			result.put("msg", "用户或密码为空!");
			
			return result;
		}
		//添加用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(name,password);
        //进行验证,这里可以捕获异常,然后返回对应信息
        try {
        	 subject.login(usernamePasswordToken);
        } catch (AuthenticationException e) {
        	result.put("status", "400");
        	result.put("msg", "用户名或密码错误!");
        	return result;
		}
        result.put("status", "200");
    	result.put("msg", "登录成功!");
		return result;
	}
}

测试:

失败情况:

成功情况:


在登录成功之后,可以在login.html页面中进行跳转到index.html主页面。


猜你喜欢

转载自blog.csdn.net/Jayszxs/article/details/80888866