jeecg-boot登录及接⼝验证(JWT+shiro)shrio配置
package fig;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.DefaultSessionStorageEvaluator;
import org.DefaultSubjectDAO;
import org.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.DefaultWebSecurityManager;
import dules.shiro.authc.ShiroRealm;
import dules.shiro.authc.aop.JwtFilter;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import t.annotation.Bean;
import t.annotation.Configuration;
import t.annotation.DependsOn;
/**
* @author: Scott
* @date: 2018/2/7
* @description: shiro 配置类
*/
@Configuration
public class ShiroConfig {
/**
* Filter Chain定义说明
*
* 1、⼀个URL可以配置多个Filter,使⽤逗号分隔
* 2、当设置多个过滤器时,全部验证通过,才视为通过
* 3、部分过滤器可指定参数,如perms,roles
*/
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//cas验证登录
filterChainDefinitionMap.put("/cas/client/validateLogin", "anon");
// 配置不会被拦截的链接顺序判断
filterChainDefinitionMap.put("/sys/login", "anon"); //登录接⼝排除
filterChainDefinitionMap.put("/sys/logout", "anon"); //登出接⼝排除
filterChainDefinitionMap.put("/sys/getEncryptedString", "anon"); //获取加密串
filterChainDefinitionMap.put("/sys/sms", "anon");//短信验证码
filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//⼿机登录
filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验⽤户是否存在
filterChainDefinitionMap.put("/sys/user/register", "anon");//⽤户注册
filterChainDefinitionMap.put("/sys/user/querySysUser", "anon");//根据⼿机号获取⽤户信息
filterChainDefinitionMap.put("/sys/user/phoneVerification", "anon");//⽤户忘记密码验证⼿机号
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//⽤户更改密码
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图⽚预览不限制token
filterChainDefinitionMap.put("/sys/common/download/**", "anon");//⽂件下载不限制token
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要⽂件
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/doc.html", "anon");
filterChainDefinitionMap.put("/**/*.js", "anon");
filterChainDefinitionMap.put("/**/*.css", "anon");
filterChainDefinitionMap.put("/**/*.html", "anon");
filterChainDefinitionMap.put("/**/*.svg", "anon");
filterChainDefinitionMap.put("/**/*.pdf", "anon");
filterChainDefinitionMap.put("/**/*.jpg", "anon");
filterChainDefinitionMap.put("/**/*.png", "anon");
filterChainDefinitionMap.put("/**/*.ico", "anon");
// update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀
filterChainDefinitionMap.put("/**/*.ttf", "anon");
filterChainDefinitionMap.put("/**/*.woff", "anon");
// update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
filterChainDefinitionMap.put("/swagger**/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/v2/**", "anon");
//性能监控
filterChainDefinitionMap.put("/actuator/metrics/**", "anon");
filterChainDefinitionMap.put("/actuator/httptrace/**", "anon");
filterChainDefinitionMap.put("/actuator/redis/**", "anon");
filterChainDefinitionMap.put("/test/jeecgDemo/demo3", "anon"); //模板测试
filterChainDefinitionMap.put("/test/jeecgDemo/redisDemo/**", "anon"); //redis测试
//排除Online请求
filterChainDefinitionMap.put("/auto/cgform/**", "anon");
//websocket排除
filterChainDefinitionMap.put("/websocket/**", "anon");
// 添加⾃⼰的过滤器并且取名为jwt
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
filterMap.put("jwt", new JwtFilter());
shiroFilterFactoryBean.setFilters(filterMap);
// <!-- 过滤链定义,从上向下顺序执⾏,⼀般将/**放在最为下边
filterChainDefinitionMap.put("/**", "jwt");
// 未授权界⾯返回JSON
shiroFilterFactoryBean.setUnauthorizedUrl("/sys/common/403");
// shiroFilterFactoryBean.setLoginUrl("/sys/common/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean("securityManager")
public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm);
/*
* 关闭shiro⾃带的session,详情见⽂档
* /session-management.html#SessionManagement-
* StatelessApplications%28Sessionless%29
*/
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
/**
* 下⾯的代码是添加注解⽀持
* @return
*/
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
说明:
⾸先配置⼀系列拦截的路径
配置jwtfilter 继承AuthenticatingFilter 作后⾯的接⼝登录验证
⾃定义realm
实例化常规bean
jwtFilter
package dules.shiro.authc.aop;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import dules.shiro.authc.JwtToken;
import dules.shiro.vo.DefContants;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
slf4j.Slf4j;
/**
* @Description: 鉴权登录
* @Author: Scott
* @Author: Scott
sun认证* @Date: 2018/10/7
**/
@Slf4j
public class JwtFilter extends BasicHttpAuthenticationFilter {
/**
* 执⾏登录认证
*
* @param request
* @param response
* @param mappedValue
* @return
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
try {
executeLogin(request, response);
return true;
} catch (Exception e) {
throw new AuthenticationException("Token失效,请重新登录", e);
}
}
/**
*
*/
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = Header(DefContants.X_ACCESS_TOKEN);
JwtToken jwtToken = new JwtToken(token);
// 提交给realm进⾏登⼊,如果错误他会抛出异常并被捕获
getSubject(request, response).login(jwtToken);
// 如果没有抛出异常则代表登⼊成功,返回true
return true;
}
/**
* 对跨域提供⽀持
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-control-Allow-Origin", Header("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", Header("Access-Control-Request-Headers")); // 跨域时会⾸先发送⼀个option请求,这⾥我们给option请求直接返回正常状态
if (Method().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
}
说明
该过滤器主要是通过对前端传的head中的token进⾏⽤户⾝份的验证
getSubject(request, response).login(jwtToken); 交给realm认证
⾃定义的realm
package dules.shiro.authc;
import java.util.Set;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.alm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import stant.CommonConstant;
import org.jeecgmon.system.util.JwtUtil;
import org.jeecgmon.system.vo.LoginUser;
import org.jeecgmon.util.RedisUtil;
import org.jeecgmon.util.SpringContextUtils;
import org.jeecgmon.util.oConvertUtils;
import ity.SysUser;
import dules.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import t.annotation.Lazy;
import org.springframework.stereotype.Component;
slf4j.Slf4j;
/**
* @Description: ⽤户登录鉴权和获取⽤户授权
* @Author: Scott
* @Date: 2019-4-23 8:13
* @Version: 1.1
*/
@Component
@Slf4j
public class ShiroRealm extends AuthorizingRealm {
@Autowired
@Lazy
private ISysUserService sysUserService;
@Autowired
@Lazy
private RedisUtil redisUtil;
/**
* 必须重写此⽅法,不然Shiro会报错
*/
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof JwtToken;
}
/**
* 功能:获取⽤户权限信息,包括⾓⾊以及权限。只有当触发检测⽤户权限时才会调⽤此⽅法,例如checkRole,checkPermission *
* @param token token
* @return AuthorizationInfo 权限信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("————权限认证 [ roles、permissions]————");
LoginUser sysUser = null;
String username = null;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论