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 iszhoubobo@outlook.com
* @date 2018年7月2日 下午5:40:07
*/
@Configuration
public class ShiroConfiguration {
/**
* @Title: userRealm
* @Description: 自定义认证领域
* @return
* @author 周华波(Jayszxs)
* @email iszhoubobo@outlook.com
* @Date 2018年7月2日 下午5:58:18
*/
@Bean
public UserRealm userRealm() {
UserRealm userRealm = new UserRealm();
return userRealm;
}
/**
* @Title: securityManager
* @Description: 托管自定义的验证领域
* @return
* @author 周华波(Jayszxs)
* @email iszhoubobo@outlook.com
* @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 iszhoubobo@outlook.com
* @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主页面。