上传代码
This commit is contained in:
173
src/main/java/com/nis/web/security/CacheSessionDAO.java
Normal file
173
src/main/java/com/nis/web/security/CacheSessionDAO.java
Normal file
@@ -0,0 +1,173 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.UnknownSessionException;
|
||||
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.apache.shiro.subject.support.DefaultSubjectContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.nis.util.Configurations;
|
||||
import com.nis.util.Constants;
|
||||
import com.nis.util.DateUtils;
|
||||
import com.nis.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 系统安全认证实现类
|
||||
* @author
|
||||
* @version
|
||||
*/
|
||||
public class CacheSessionDAO extends EnterpriseCacheSessionDAO implements SessionDAO {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public CacheSessionDAO() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doUpdate(Session session) {
|
||||
if (session == null || session.getId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
HttpServletRequest request = Servlets.getRequest();
|
||||
if (request != null){
|
||||
String uri = request.getServletPath();
|
||||
// 如果是静态文件,则不更新SESSION
|
||||
if (Servlets.isStaticFile(uri)){
|
||||
return;
|
||||
}
|
||||
// 如果是视图文件,则不更新SESSION
|
||||
if (StringUtils.startsWith(uri, Configurations.getStringProperty("web.view.prefix","/WEB-INF/views/"))
|
||||
&& StringUtils.endsWith(uri,Configurations.getStringProperty("web.view.suffix",".jsp"))){
|
||||
return;
|
||||
}
|
||||
// 手动控制不更新SESSION
|
||||
String updateSession = request.getParameter("updateSession");
|
||||
if (Constants.FALSE.equals(updateSession) || Constants.NO.equals(updateSession)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.doUpdate(session);
|
||||
logger.debug("update {} {}", session.getId(), request != null ? request.getRequestURI() : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doDelete(Session session) {
|
||||
if (session == null || session.getId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.doDelete(session);
|
||||
logger.debug("delete {} ", session.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable doCreate(Session session) {
|
||||
HttpServletRequest request = Servlets.getRequest();
|
||||
if (request != null){
|
||||
String uri = request.getServletPath();
|
||||
// 如果是静态文件,则不创建SESSION
|
||||
if (Servlets.isStaticFile(uri)){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
super.doCreate(session);
|
||||
logger.debug("doCreate {} {}", session, request != null ? request.getRequestURI() : "");
|
||||
return session.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session doReadSession(Serializable sessionId) {
|
||||
return super.doReadSession(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session readSession(Serializable sessionId) throws UnknownSessionException {
|
||||
try{
|
||||
Session s = null;
|
||||
HttpServletRequest request = Servlets.getRequest();
|
||||
if (request != null){
|
||||
String uri = request.getServletPath();
|
||||
// 如果是静态文件,则不获取SESSION
|
||||
if (Servlets.isStaticFile(uri)){
|
||||
return null;
|
||||
}
|
||||
s = (Session)request.getAttribute("session_"+sessionId);
|
||||
}
|
||||
if (s != null){
|
||||
return s;
|
||||
}
|
||||
|
||||
Session session = super.readSession(sessionId);
|
||||
logger.debug("readSession {} {}", sessionId, request != null ? request.getRequestURI() : "");
|
||||
|
||||
if (request != null && session != null){
|
||||
request.setAttribute("session_"+sessionId, session);
|
||||
}
|
||||
|
||||
return session;
|
||||
}catch (UnknownSessionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动会话
|
||||
* @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话)
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Collection<Session> getActiveSessions(boolean includeLeave) {
|
||||
return getActiveSessions(includeLeave, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动会话
|
||||
* @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话)
|
||||
* @param principal 根据登录者对象获取活动会话
|
||||
* @param filterSession 不为空,则过滤掉(不包含)这个会话。
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Collection<Session> getActiveSessions(boolean includeLeave, Object principal, Session filterSession) {
|
||||
// 如果包括离线,并无登录者条件。
|
||||
if (includeLeave && principal == null){
|
||||
return getActiveSessions();
|
||||
}
|
||||
Set<Session> sessions = Sets.newHashSet();
|
||||
for (Session session : getActiveSessions()){
|
||||
boolean isActiveSession = false;
|
||||
// 不包括离线并符合最后访问时间小于等于3分钟条件。
|
||||
if (includeLeave || DateUtils.pastMinutes(session.getLastAccessTime()) <= 3){
|
||||
isActiveSession = true;
|
||||
}
|
||||
// 符合登陆者条件。
|
||||
if (principal != null){
|
||||
PrincipalCollection pc = (PrincipalCollection)session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
|
||||
if (principal.toString().equals(pc != null ? pc.getPrimaryPrincipal().toString() : StringUtils.EMPTY)){
|
||||
isActiveSession = true;
|
||||
}
|
||||
}
|
||||
// 过滤掉的SESSION
|
||||
if (filterSession != null && filterSession.getId().equals(session.getId())){
|
||||
isActiveSession = false;
|
||||
}
|
||||
if (isActiveSession){
|
||||
sessions.add(session);
|
||||
}
|
||||
}
|
||||
return sessions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.web.util.WebUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.nis.util.Constants;
|
||||
import com.nis.util.IpUtil;
|
||||
import com.nis.util.StringUtils;
|
||||
|
||||
|
||||
@Service
|
||||
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
|
||||
|
||||
|
||||
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
|
||||
String username = getUsername(request);
|
||||
String password = getPassword(request);
|
||||
if (password==null){
|
||||
password = "";
|
||||
}
|
||||
boolean rememberMe = isRememberMe(request);
|
||||
|
||||
String host =IpUtil.getIpAddr((HttpServletRequest)request);
|
||||
String captcha = getCaptcha(request);
|
||||
boolean mobile = isMobileLogin(request);
|
||||
return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
|
||||
}
|
||||
|
||||
|
||||
protected String getCaptcha(ServletRequest request) {
|
||||
return WebUtils.getCleanParam(request, Constants.DEFAULT_CAPTCHA_PARAM);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected boolean isMobileLogin(ServletRequest request) {
|
||||
return WebUtils.isTrue(request, Constants.DEFAULT_MOBILE_PARAM);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 登录成功之后跳转URL
|
||||
*/
|
||||
public String getSuccessUrl() {
|
||||
return super.getSuccessUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void issueSuccessRedirect(ServletRequest request,
|
||||
ServletResponse response) throws Exception {
|
||||
// Principal p = UserUtils.getPrincipal();
|
||||
// if (p != null && !p.isMobileLogin()){
|
||||
WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
|
||||
// }else{
|
||||
// super.issueSuccessRedirect(request, response);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录失败调用事件
|
||||
*/
|
||||
@Override
|
||||
protected boolean onLoginFailure(AuthenticationToken token,
|
||||
AuthenticationException e, ServletRequest request, ServletResponse response) {
|
||||
String className = e.getClass().getName(), message = "";
|
||||
if (IncorrectCredentialsException.class.getName().equals(className)
|
||||
|| UnknownAccountException.class.getName().equals(className)){
|
||||
message = "用户或密码错误, 请重试.";
|
||||
}
|
||||
else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
|
||||
message = StringUtils.replace(e.getMessage(), "msg:", "");
|
||||
}
|
||||
|
||||
else{
|
||||
message = "系统出现点问题,请稍后再试!";
|
||||
e.printStackTrace(); // 输出到控制台
|
||||
}
|
||||
request.setAttribute(getFailureKeyAttribute(), className);
|
||||
request.setAttribute(Constants.DEFAULT_MESSAGE_PARAM, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
69
src/main/java/com/nis/web/security/IdGen.java
Normal file
69
src/main/java/com/nis/web/security/IdGen.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.nis.util.Encodes;
|
||||
|
||||
/**
|
||||
* 封装各种生成唯一性ID算法的工具类.
|
||||
* @author
|
||||
* @version 2013-01-15
|
||||
*/
|
||||
@Service
|
||||
@Lazy(false)
|
||||
public class IdGen implements SessionIdGenerator {
|
||||
|
||||
private static SecureRandom random = new SecureRandom();
|
||||
|
||||
/**
|
||||
* 封装JDK自带的UUID, 通过Random数字生成, 中间无-分割.
|
||||
*/
|
||||
public static String uuid() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用SecureRandom随机生成Long.
|
||||
*/
|
||||
public static long randomLong() {
|
||||
return Math.abs(random.nextLong());
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于Base62编码的SecureRandom随机生成bytes.
|
||||
*/
|
||||
public static String randomBase62(int length) {
|
||||
byte[] randomBytes = new byte[length];
|
||||
random.nextBytes(randomBytes);
|
||||
return Encodes.encodeBase62(randomBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activiti ID 生成
|
||||
*/
|
||||
public String getNextId() {
|
||||
return IdGen.uuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable generateId(Session session) {
|
||||
return IdGen.uuid();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(IdGen.uuid());
|
||||
System.out.println(IdGen.uuid().length());
|
||||
System.out.println(new IdGen().getNextId());
|
||||
for (int i=0; i<1000; i++){
|
||||
System.out.println(IdGen.randomLong() + " " + IdGen.randomBase62(5));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
262
src/main/java/com/nis/web/security/Servlets.java
Normal file
262
src/main/java/com/nis/web/security/Servlets.java
Normal file
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* Copyright (c) 2005-2012 springside.org.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*/
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.nis.util.Configurations;
|
||||
import com.nis.util.Encodes;
|
||||
import com.nis.util.StringUtils;
|
||||
import com.nis.web.security.SystemAuthorizingRealm.Principal;
|
||||
|
||||
/**
|
||||
* Http与Servlet工具类.
|
||||
* @author calvin/thinkgem
|
||||
* @version 2014-8-19
|
||||
*/
|
||||
public class Servlets {
|
||||
|
||||
// -- 常用数值定义 --//
|
||||
public static final long ONE_YEAR_SECONDS = 60 * 60 * 24 * 365;
|
||||
|
||||
// 静态文件后缀
|
||||
private final static String[] staticFiles = StringUtils.split(Configurations.getStringProperty("web.staticFile",""), ",");
|
||||
|
||||
|
||||
|
||||
// 动态映射URL后缀
|
||||
private final static String urlSuffix = Configurations.getStringProperty("urlSuffix", ".jsp");
|
||||
|
||||
/**
|
||||
* 设置客户端缓存过期时间 的Header.
|
||||
*/
|
||||
public static void setExpiresHeader(HttpServletResponse response, long expiresSeconds) {
|
||||
// Http 1.0 header, set a fix expires date.
|
||||
response.setDateHeader(HttpHeaders.EXPIRES, System.currentTimeMillis() + expiresSeconds * 1000);
|
||||
// Http 1.1 header, set a time after now.
|
||||
response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=" + expiresSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置禁止客户端缓存的Header.
|
||||
*/
|
||||
public static void setNoCacheHeader(HttpServletResponse response) {
|
||||
// Http 1.0 header
|
||||
response.setDateHeader(HttpHeaders.EXPIRES, 1L);
|
||||
response.addHeader(HttpHeaders.PRAGMA, "no-cache");
|
||||
// Http 1.1 header
|
||||
response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0");
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置LastModified Header.
|
||||
*/
|
||||
public static void setLastModifiedHeader(HttpServletResponse response, long lastModifiedDate) {
|
||||
response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModifiedDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Etag Header.
|
||||
*/
|
||||
public static void setEtag(HttpServletResponse response, String etag) {
|
||||
response.setHeader(HttpHeaders.ETAG, etag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据浏览器If-Modified-Since Header, 计算文件是否已被修改.
|
||||
*
|
||||
* 如果无修改, checkIfModify返回false ,设置304 not modify status.
|
||||
*
|
||||
* @param lastModified 内容的最后修改时间.
|
||||
*/
|
||||
public static boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response,
|
||||
long lastModified) {
|
||||
long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
|
||||
if ((ifModifiedSince != -1) && (lastModified < ifModifiedSince + 1000)) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据浏览器 If-None-Match Header, 计算Etag是否已无效.
|
||||
*
|
||||
* 如果Etag有效, checkIfNoneMatch返回false, 设置304 not modify status.
|
||||
*
|
||||
* @param etag 内容的ETag.
|
||||
*/
|
||||
public static boolean checkIfNoneMatchEtag(HttpServletRequest request, HttpServletResponse response, String etag) {
|
||||
String headerValue = request.getHeader(HttpHeaders.IF_NONE_MATCH);
|
||||
if (headerValue != null) {
|
||||
boolean conditionSatisfied = false;
|
||||
if (!"*".equals(headerValue)) {
|
||||
StringTokenizer commaTokenizer = new StringTokenizer(headerValue, ",");
|
||||
|
||||
while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) {
|
||||
String currentToken = commaTokenizer.nextToken();
|
||||
if (currentToken.trim().equals(etag)) {
|
||||
conditionSatisfied = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
conditionSatisfied = true;
|
||||
}
|
||||
|
||||
if (conditionSatisfied) {
|
||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||
response.setHeader(HttpHeaders.ETAG, etag);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置让浏览器弹出下载对话框的Header.
|
||||
*
|
||||
* @param fileName 下载后的文件名.
|
||||
*/
|
||||
public static void setFileDownloadHeader(HttpServletResponse response, String fileName) {
|
||||
try {
|
||||
// 中文文件名支持
|
||||
String encodedfileName = new String(fileName.getBytes(), "ISO8859-1");
|
||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedfileName + "\"");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得带相同前缀的Request Parameters, copy from spring WebUtils.
|
||||
*
|
||||
* 返回的结果的Parameter名已去除前缀.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static Map<String, Object> getParametersStartingWith(ServletRequest request, String prefix) {
|
||||
Validate.notNull(request, "Request must not be null");
|
||||
Enumeration paramNames = request.getParameterNames();
|
||||
Map<String, Object> params = new TreeMap<String, Object>();
|
||||
String pre = prefix;
|
||||
if (pre == null) {
|
||||
pre = "";
|
||||
}
|
||||
while (paramNames != null && paramNames.hasMoreElements()) {
|
||||
String paramName = (String) paramNames.nextElement();
|
||||
if ("".equals(pre) || paramName.startsWith(pre)) {
|
||||
String unprefixed = paramName.substring(pre.length());
|
||||
String[] values = request.getParameterValues(paramName);
|
||||
if (values == null || values.length == 0) {
|
||||
values = new String[]{};
|
||||
// Do nothing, no values found at all.
|
||||
} else if (values.length > 1) {
|
||||
params.put(unprefixed, values);
|
||||
} else {
|
||||
params.put(unprefixed, values[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组合Parameters生成Query String的Parameter部分,并在paramter name上加上prefix.
|
||||
*
|
||||
*/
|
||||
public static String encodeParameterStringWithPrefix(Map<String, Object> params, String prefix) {
|
||||
StringBuilder queryStringBuilder = new StringBuilder();
|
||||
|
||||
String pre = prefix;
|
||||
if (pre == null) {
|
||||
pre = "";
|
||||
}
|
||||
Iterator<Entry<String, Object>> it = params.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<String, Object> entry = it.next();
|
||||
queryStringBuilder.append(pre).append(entry.getKey()).append("=").append(entry.getValue());
|
||||
if (it.hasNext()) {
|
||||
queryStringBuilder.append("&");
|
||||
}
|
||||
}
|
||||
return queryStringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端对Http Basic验证的 Header进行编码.
|
||||
*/
|
||||
public static String encodeHttpBasic(String userName, String password) {
|
||||
String encode = userName + ":" + password;
|
||||
return "Basic " + Encodes.encodeBase64(encode.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Ajax异步请求
|
||||
* @param request
|
||||
*/
|
||||
public static boolean isAjaxRequest(HttpServletRequest request){
|
||||
|
||||
String accept = request.getHeader("accept");
|
||||
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||
Principal principal = UserUtils.getPrincipal();
|
||||
|
||||
// 如果是异步请求或是手机端,则直接返回信息
|
||||
return ((accept != null && accept.indexOf("application/json") != -1
|
||||
|| (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
|
||||
|| (principal != null && principal.isMobileLogin())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求对象
|
||||
* @return
|
||||
*/
|
||||
public static HttpServletRequest getRequest(){
|
||||
try{
|
||||
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
|
||||
}catch(Exception e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断访问URI是否是静态文件请求
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isStaticFile(String uri){
|
||||
if (staticFiles == null){
|
||||
try {
|
||||
throw new Exception("检测到“app.properties”中没有配置“web.staticFile”属性。配置示例:\n#静态文件后缀\n"
|
||||
+"web.staticFile=.css,.js,.png,.jpg,.gif,.jpeg,.bmp,.ico,.swf,.psd,.htc,.crx,.xpi,.exe,.ipa,.apk");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// if ((StringUtils.startsWith(uri, "/static/") || StringUtils.endsWithAny(uri, sfs))
|
||||
// && !StringUtils.endsWithAny(uri, ".jsp") && !StringUtils.endsWithAny(uri, ".java")){
|
||||
// return true;
|
||||
// }
|
||||
if (StringUtils.endsWithAny(uri, staticFiles) && !StringUtils.endsWithAny(uri, urlSuffix)
|
||||
&& !StringUtils.endsWithAny(uri, ".jsp") && !StringUtils.endsWithAny(uri, ".java")){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
25
src/main/java/com/nis/web/security/SessionDAO.java
Normal file
25
src/main/java/com/nis/web/security/SessionDAO.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.shiro.session.Session;
|
||||
|
||||
public interface SessionDAO extends org.apache.shiro.session.mgt.eis.SessionDAO {
|
||||
|
||||
/**
|
||||
* 获取活动会话
|
||||
* @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话)
|
||||
* @return
|
||||
*/
|
||||
public Collection<Session> getActiveSessions(boolean includeLeave);
|
||||
|
||||
/**
|
||||
* 获取活动会话
|
||||
* @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话)
|
||||
* @param principal 根据登录者对象获取活动会话
|
||||
* @param filterSession 不为空,则过滤掉(不包含)这个会话。
|
||||
* @return
|
||||
*/
|
||||
public Collection<Session> getActiveSessions(boolean includeLeave, Object principal, Session filterSession);
|
||||
|
||||
}
|
||||
208
src/main/java/com/nis/web/security/SessionManager.java
Normal file
208
src/main/java/com/nis/web/security/SessionManager.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* Copyright © 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
|
||||
*/
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.session.InvalidSessionException;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.session.UnknownSessionException;
|
||||
import org.apache.shiro.session.mgt.SessionContext;
|
||||
import org.apache.shiro.session.mgt.SessionKey;
|
||||
import org.apache.shiro.session.mgt.SimpleSession;
|
||||
import org.apache.shiro.web.servlet.Cookie;
|
||||
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
|
||||
import org.apache.shiro.web.servlet.SimpleCookie;
|
||||
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
import org.apache.shiro.web.util.WebUtils;
|
||||
|
||||
import com.nis.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 自定义WEB会话管理类
|
||||
* @author ThinkGem
|
||||
* @version 2014-7-20
|
||||
*/
|
||||
public class SessionManager extends DefaultWebSessionManager {
|
||||
|
||||
public SessionManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
|
||||
// 如果参数中包含“__sid”参数,则使用此sid会话。 例如:http://localhost/project?__sid=xxx&__cookie=true
|
||||
String sid = request.getParameter("__sid");
|
||||
if (StringUtils.isNotBlank(sid)) {
|
||||
// 是否将sid保存到cookie,浏览器模式下使用此参数。
|
||||
if (WebUtils.isTrue(request, "__cookie")){
|
||||
HttpServletRequest rq = (HttpServletRequest)request;
|
||||
HttpServletResponse rs = (HttpServletResponse)response;
|
||||
Cookie template = getSessionIdCookie();
|
||||
Cookie cookie = new SimpleCookie(template);
|
||||
cookie.setValue(sid); cookie.saveTo(rq, rs);
|
||||
}
|
||||
// 设置当前session状态
|
||||
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
|
||||
ShiroHttpServletRequest.URL_SESSION_ID_SOURCE); // session来源与url
|
||||
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sid);
|
||||
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
|
||||
return sid;
|
||||
}else{
|
||||
return super.getSessionId(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateSessions() {
|
||||
super.validateSessions();
|
||||
}
|
||||
|
||||
protected Session retrieveSession(SessionKey sessionKey) {
|
||||
try{
|
||||
return super.retrieveSession(sessionKey);
|
||||
}catch (UnknownSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Date getStartTimestamp(SessionKey key) {
|
||||
try{
|
||||
return super.getStartTimestamp(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Date getLastAccessTime(SessionKey key) {
|
||||
try{
|
||||
return super.getLastAccessTime(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public long getTimeout(SessionKey key){
|
||||
try{
|
||||
return super.getTimeout(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTimeout(SessionKey key, long maxIdleTimeInMillis) {
|
||||
try{
|
||||
super.setTimeout(key, maxIdleTimeInMillis);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
}
|
||||
}
|
||||
|
||||
public void touch(SessionKey key) {
|
||||
try{
|
||||
super.touch(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
}
|
||||
}
|
||||
|
||||
public String getHost(SessionKey key) {
|
||||
try{
|
||||
return super.getHost(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Object> getAttributeKeys(SessionKey key) {
|
||||
try{
|
||||
return super.getAttributeKeys(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getAttribute(SessionKey sessionKey, Object attributeKey) {
|
||||
try{
|
||||
return super.getAttribute(sessionKey, attributeKey);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAttribute(SessionKey sessionKey, Object attributeKey, Object value) {
|
||||
try{
|
||||
super.setAttribute(sessionKey, attributeKey, value);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
}
|
||||
}
|
||||
|
||||
public Object removeAttribute(SessionKey sessionKey, Object attributeKey) {
|
||||
try{
|
||||
return super.removeAttribute(sessionKey, attributeKey);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(SessionKey key) {
|
||||
try{
|
||||
super.stop(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
}
|
||||
}
|
||||
|
||||
public void checkValid(SessionKey key) {
|
||||
try{
|
||||
super.checkValid(key);
|
||||
}catch (InvalidSessionException e) {
|
||||
// 获取不到SESSION不抛出异常
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session doCreateSession(SessionContext context) {
|
||||
try{
|
||||
return super.doCreateSession(context);
|
||||
}catch (IllegalStateException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Session newSessionInstance(SessionContext context) {
|
||||
Session session = super.newSessionInstance(context);
|
||||
session.setTimeout(getGlobalSessionTimeout());
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session start(SessionContext context) {
|
||||
try{
|
||||
return super.start(context);
|
||||
}catch (NullPointerException e) {
|
||||
SimpleSession session = new SimpleSession();
|
||||
session.setId(0);
|
||||
return session;
|
||||
}
|
||||
}
|
||||
}
|
||||
295
src/main/java/com/nis/web/security/SystemAuthorizingRealm.java
Normal file
295
src/main/java/com/nis/web/security/SystemAuthorizingRealm.java
Normal file
@@ -0,0 +1,295 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
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.credential.DefaultPasswordService;
|
||||
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
||||
import org.apache.shiro.authc.credential.PasswordService;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.Permission;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.realm.AuthorizingRealm;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.code.kaptcha.Constants;
|
||||
import com.nis.domain.SysMenu;
|
||||
import com.nis.domain.SysRole;
|
||||
import com.nis.domain.SysUser;
|
||||
import com.nis.util.Configurations;
|
||||
import com.nis.util.Encodes;
|
||||
import com.nis.util.LogUtils;
|
||||
import com.nis.util.StringUtil;
|
||||
import com.nis.util.StringUtils;
|
||||
import com.nis.util.TreeUtil;
|
||||
import com.nis.web.service.SystemService;
|
||||
|
||||
|
||||
/**
|
||||
* 系统安全认证实现类
|
||||
* @author
|
||||
* @version 2014-7-5
|
||||
*/
|
||||
@Service
|
||||
public class SystemAuthorizingRealm extends AuthorizingRealm {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private SystemService systemService;
|
||||
|
||||
/**
|
||||
* 认证回调函数, 登录时调用
|
||||
* Authentication 存放用户名、密码地方,身份认证
|
||||
*/
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
|
||||
|
||||
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
|
||||
|
||||
int activeSessionSize = systemService.getActiveSessions(false).size();
|
||||
|
||||
|
||||
if (logger.isDebugEnabled()){
|
||||
logger.debug("login submit, active session size: {}, username: {}", activeSessionSize, token.getUsername());
|
||||
}
|
||||
|
||||
// 校验登录验证码
|
||||
if (UserUtils.isValidateCodeLogin(token.getUsername(), false, false)){
|
||||
|
||||
if (!UserUtils.validateCodeIsValid(token.getCaptcha())){
|
||||
throw new AuthenticationException("msg:验证码错误, 请重试.");
|
||||
}
|
||||
}
|
||||
|
||||
// 校验用户名密码
|
||||
SysUser user = systemService.getUserByLoginName(token.getUsername());
|
||||
if (user != null) {
|
||||
if (com.nis.util.Constants.NO.equals(user.getStatus())){
|
||||
throw new AuthenticationException("msg:该已帐号禁止登录.");
|
||||
}
|
||||
byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
|
||||
return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()), user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
|
||||
* Authorzation 授权,存放用户权限
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
Principal principal = (Principal) getAvailablePrincipal(principals);
|
||||
|
||||
// 获取当前已登录的用户
|
||||
if (!com.nis.util.Constants.TRUE.equals(Configurations.getStringProperty("user.multiAccountLogin","true"))){
|
||||
Collection<Session> sessions = systemService.getActiveSessions(true, principal, UserUtils.getSession());
|
||||
if (sessions.size() > 0){
|
||||
// 如果是登录进来的,则踢出已在线用户
|
||||
if (UserUtils.getSubject().isAuthenticated()){
|
||||
for (Session session : sessions){
|
||||
systemService.deleteSession(session);
|
||||
}
|
||||
}
|
||||
// 记住我进来的,并且当前用户已登录,则退出当前用户提示信息。
|
||||
else{
|
||||
UserUtils.getSubject().logout();
|
||||
throw new AuthenticationException("msg:账号已在其它地方登录,请重新登录。");
|
||||
}
|
||||
}
|
||||
}
|
||||
SysUser user = systemService.getUserByLoginName(principal.getLoginName());
|
||||
if (user != null) {
|
||||
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||
List<SysMenu> list = UserUtils.getMenuList();
|
||||
if(!StringUtil.isEmpty(list)) {
|
||||
for (SysMenu menu :list) {
|
||||
if (!StringUtil.isBlank(menu.getPermission())) {
|
||||
// 添加基于Permission的权限信息
|
||||
for (String permission : StringUtils.split(menu.getPermission(),",")){
|
||||
info.addStringPermission(permission);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 添加用户权限
|
||||
info.addStringPermission("user");
|
||||
// 添加用户角色信息
|
||||
for (SysRole role : user.getUserRoleList()){
|
||||
info.addRole(role.getName());
|
||||
}
|
||||
// 更新登录IP和时间,集成用户日志记录
|
||||
//systemService.updateUserLoginInfo(user);
|
||||
// 记录登录日志
|
||||
LogUtils.saveLog(Servlets.getRequest(), "系统登录");
|
||||
return info;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkPermission(Permission permission, AuthorizationInfo info) {
|
||||
authorizationValidate(permission);
|
||||
super.checkPermission(permission, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean[] isPermitted(List<Permission> permissions, AuthorizationInfo info) {
|
||||
if (permissions != null && !permissions.isEmpty()) {
|
||||
for (Permission permission : permissions) {
|
||||
authorizationValidate(permission);
|
||||
}
|
||||
}
|
||||
return super.isPermitted(permissions, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
|
||||
authorizationValidate(permission);
|
||||
return super.isPermitted(principals, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPermittedAll(Collection<Permission> permissions, AuthorizationInfo info) {
|
||||
if (permissions != null && !permissions.isEmpty()) {
|
||||
for (Permission permission : permissions) {
|
||||
authorizationValidate(permission);
|
||||
}
|
||||
}
|
||||
return super.isPermittedAll(permissions, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权验证方法
|
||||
* @param permission
|
||||
*/
|
||||
private void authorizationValidate(Permission permission){
|
||||
// 模块授权预留接口
|
||||
}
|
||||
|
||||
/**
|
||||
* 设定密码校验的Hash算法与迭代次数
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initCredentialsMatcher() {
|
||||
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(com.nis.util.Constants.HASH_ALGORITHM);
|
||||
matcher.setHashIterations(com.nis.util.Constants.HASH_INTERATIONS);
|
||||
setCredentialsMatcher(matcher);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 清空用户关联权限认证,待下次使用时重新加载
|
||||
// */
|
||||
// public void clearCachedAuthorizationInfo(Principal principal) {
|
||||
// SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
|
||||
// clearCachedAuthorizationInfo(principals);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 授权用户信息
|
||||
*/
|
||||
public static class Principal implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id; // 编号
|
||||
private String loginName; // 登录名
|
||||
private String name; // 姓名
|
||||
private boolean mobileLogin; // 是否手机登录
|
||||
private String email;
|
||||
|
||||
// private Map<String, Object> cacheMap;
|
||||
|
||||
public Principal(SysUser user, boolean mobileLogin) {
|
||||
this.id = user.getId();
|
||||
this.loginName = user.getLoginId();
|
||||
this.name = user.getName();
|
||||
this.email = user.getEmail();
|
||||
this.mobileLogin = mobileLogin;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getLoginName() {
|
||||
return loginName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isMobileLogin() {
|
||||
return mobileLogin;
|
||||
}
|
||||
|
||||
// @JsonIgnore
|
||||
// public Map<String, Object> getCacheMap() {
|
||||
// if (cacheMap==null){
|
||||
// cacheMap = new HashMap<String, Object>();
|
||||
// }
|
||||
// return cacheMap;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取SESSIONID
|
||||
*/
|
||||
public String getSessionid() {
|
||||
try{
|
||||
return (String) UserUtils.getSession().getId();
|
||||
}catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
428
src/main/java/com/nis/web/security/UserUtils.java
Normal file
428
src/main/java/com/nis/web/security/UserUtils.java
Normal file
@@ -0,0 +1,428 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.UnavailableSecurityManagerException;
|
||||
import org.apache.shiro.session.InvalidSessionException;
|
||||
import org.apache.shiro.session.Session;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
|
||||
import com.google.code.kaptcha.Constants;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.nis.domain.SysArea;
|
||||
import com.nis.domain.SysMenu;
|
||||
import com.nis.domain.SysOffice;
|
||||
import com.nis.domain.SysRole;
|
||||
import com.nis.domain.SysUser;
|
||||
import com.nis.util.CacheUtils;
|
||||
import com.nis.util.StringUtil;
|
||||
import com.nis.util.StringUtils;
|
||||
import com.nis.util.TreeUtil;
|
||||
import com.nis.web.dao.SysAreaDao;
|
||||
import com.nis.web.dao.SysMenuDao;
|
||||
import com.nis.web.dao.SysOfficeDao;
|
||||
import com.nis.web.dao.SysRoleDao;
|
||||
import com.nis.web.dao.UserDao;
|
||||
import com.nis.web.security.SystemAuthorizingRealm.Principal;
|
||||
import com.nis.web.service.BaseService;
|
||||
import com.nis.web.service.SpringContextHolder;
|
||||
|
||||
|
||||
/**
|
||||
* 用户工具类
|
||||
* @author darnell
|
||||
* @version
|
||||
*/
|
||||
public class UserUtils {
|
||||
|
||||
private static UserDao userDao = SpringContextHolder.getBean(UserDao.class);
|
||||
private static SysOfficeDao officeDao = SpringContextHolder.getBean(SysOfficeDao.class);
|
||||
private static SysRoleDao roleDao = SpringContextHolder.getBean(SysRoleDao.class);
|
||||
private static SysMenuDao sysMenuDao = SpringContextHolder.getBean(SysMenuDao.class);
|
||||
private static SysAreaDao areaDao = SpringContextHolder.getBean(SysAreaDao.class);
|
||||
|
||||
|
||||
public static final String USER_CACHE = "userCache";
|
||||
public static final String USER_CACHE_ID_ = "id_";
|
||||
public static final String USER_CACHE_LOGIN_NAME_ = "ln";
|
||||
public static final String USER_CACHE_LIST_BY_OFFICE_ID_ = "oid_";
|
||||
|
||||
public static final String CACHE_ROLE_LIST = "roleList";
|
||||
public static final String CACHE_MENU_LIST = "menuList";
|
||||
public static final String CACHE_AREA_LIST = "areaList";
|
||||
public static final String CACHE_OFFICE_LIST = "officeList";
|
||||
public static final String CACHE_OFFICE_ALL_LIST = "officeAllList";
|
||||
public static final String CACHE_OFFICE_ALL_MAP = "officeAllMap";
|
||||
|
||||
|
||||
/**
|
||||
* 根据ID获取用户
|
||||
* @param id
|
||||
* @return 取不到返回null
|
||||
*/
|
||||
public static SysUser get(String id){
|
||||
SysUser user = (SysUser)CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
|
||||
if (user == null){
|
||||
user = userDao.getUserWithRelation(new SysUser(Long.valueOf(id),null));
|
||||
if (user == null){
|
||||
return null;
|
||||
}
|
||||
CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
|
||||
CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginId(), user);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据登录名获取用户
|
||||
* @param loginName
|
||||
* @return 取不到返回null
|
||||
*/
|
||||
public static SysUser getByLoginName(String loginName){
|
||||
SysUser user = (SysUser)CacheUtils.get(USER_CACHE, USER_CACHE_LOGIN_NAME_ + loginName);
|
||||
if (user == null){
|
||||
user = userDao.getUserWithRelation(new SysUser(null,loginName));
|
||||
if (user == null){
|
||||
return null;
|
||||
}
|
||||
CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
|
||||
CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginId(), user);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除当前用户缓存
|
||||
*/
|
||||
public static void clearCache(){
|
||||
removeCache(CACHE_ROLE_LIST);
|
||||
removeCache(CACHE_MENU_LIST);
|
||||
removeCache(CACHE_AREA_LIST);
|
||||
removeCache(CACHE_OFFICE_LIST);
|
||||
removeCache(CACHE_OFFICE_ALL_LIST);
|
||||
UserUtils.clearCache(getUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除指定用户缓存
|
||||
* @param user
|
||||
*/
|
||||
public static void clearCache(SysUser user){
|
||||
CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getId());
|
||||
CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginId());
|
||||
CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getOldLoginId());
|
||||
if (user.getOffice() != null && user.getOffice().getId() != null){
|
||||
CacheUtils.remove(USER_CACHE, USER_CACHE_LIST_BY_OFFICE_ID_ + user.getOffice().getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户
|
||||
* @return 取不到返回 new User()
|
||||
*/
|
||||
public static SysUser getUser(){
|
||||
Principal principal = getPrincipal();
|
||||
if (principal!=null){
|
||||
SysUser user = get(String.valueOf(principal.getId()));
|
||||
if (user != null){
|
||||
return user;
|
||||
}
|
||||
return new SysUser();
|
||||
}
|
||||
// 如果没有登录,则返回实例化空的User对象。
|
||||
return new SysUser();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证码是否合法
|
||||
* @param validateCode
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateCodeIsValid(String validateCode) {
|
||||
String code = (String) getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
|
||||
return (StringUtil.isBlank(validateCode) || validateCode.toUpperCase().equals(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户角色列表
|
||||
* @return
|
||||
*/
|
||||
public static List<SysRole> getRoleList(){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SysRole> roleList = (List<SysRole>)getCache(CACHE_ROLE_LIST);
|
||||
if (roleList == null){
|
||||
roleList = roleDao.findAllList(new SysRole());
|
||||
putCache(CACHE_ROLE_LIST, roleList);
|
||||
}
|
||||
return roleList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前用户授权菜单
|
||||
* @return
|
||||
*/
|
||||
public static List<SysMenu> getMenuList(){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SysMenu> menuList = (List<SysMenu>)getCache(CACHE_MENU_LIST);
|
||||
if (menuList == null){
|
||||
SysUser user = getUser();
|
||||
if (user.isAdmin()){
|
||||
menuList = sysMenuDao.findAllList(new SysMenu());
|
||||
}else{
|
||||
menuList = sysMenuDao.findSysMenuByUserId(user.getId());
|
||||
}
|
||||
putCache(CACHE_MENU_LIST, menuList);
|
||||
}
|
||||
return menuList;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static String getMenuNameById(String id) {
|
||||
for (SysMenu menu : getMenuList()) {
|
||||
if (menu.getId() == Long.valueOf(id)) {
|
||||
return menu.getName();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 按照菜单各级递归排列
|
||||
* @return
|
||||
*/
|
||||
public static List<SysMenu> getMenuTreeList(){
|
||||
return new TreeUtil(getMenuList()).buildTree();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 验证用户是否有该权限
|
||||
* @param permission
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkPermission(String permission) {
|
||||
return SecurityUtils.getSubject().isPermitted(permission);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前用户有权限访问的部门
|
||||
* @return
|
||||
*/
|
||||
public static List<SysOffice> getOfficeList(){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SysOffice> officeList = (List<SysOffice>)getCache(CACHE_OFFICE_LIST);
|
||||
if (officeList == null){
|
||||
SysUser user = getUser();
|
||||
if (user.isAdmin()){
|
||||
officeList = officeDao.findAllList(new SysOffice());
|
||||
}else{
|
||||
SysOffice office = new SysOffice();
|
||||
office.getSqlMap().put("dsf", BaseService.dataScopeFilter(user, "a", ""));
|
||||
officeList = officeDao.findList(office);
|
||||
}
|
||||
putCache(CACHE_OFFICE_LIST, officeList);
|
||||
}
|
||||
return officeList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前用户授权的区域
|
||||
* @return
|
||||
*/
|
||||
public static List<SysArea> getAreaList(){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SysArea> areaList = (List<SysArea>)getCache(CACHE_AREA_LIST);
|
||||
if (areaList == null){
|
||||
areaList = areaDao.findAllList(new SysArea());
|
||||
putCache(CACHE_AREA_LIST, areaList);
|
||||
}
|
||||
return areaList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户有权限访问的部门
|
||||
* @return
|
||||
*/
|
||||
public static List<SysOffice> getOfficeAllList(){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SysOffice> officeList = (List<SysOffice>)getCache(CACHE_OFFICE_ALL_LIST);
|
||||
if (officeList == null){
|
||||
officeList = officeDao.findAllList(new SysOffice());
|
||||
putCache(CACHE_OFFICE_ALL_MAP, getOfficeAllMap(officeList));
|
||||
}
|
||||
|
||||
return officeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户有权限访问的部门
|
||||
* @return
|
||||
*/
|
||||
public static Map<Long, SysOffice> getOfficeAllMap(){
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Long, SysOffice> officeMap = (Map<Long, SysOffice>)getCache(CACHE_OFFICE_ALL_MAP);
|
||||
if (officeMap == null){
|
||||
officeMap = getOfficeAllMap(getOfficeAllList());
|
||||
}
|
||||
|
||||
return officeMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static Map<Long, SysOffice> getOfficeAllMap(List<SysOffice> officeList) {
|
||||
Map<Long, SysOffice> officeMap = new HashMap<Long,SysOffice>();
|
||||
for (SysOffice office: officeList) {
|
||||
officeMap.put(office.getId(), office);
|
||||
}
|
||||
return officeMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前部门各个部门级别描述
|
||||
* @param deptId
|
||||
* @return
|
||||
*/
|
||||
public static String getOfficeDesc(Long deptId) {
|
||||
|
||||
StringBuilder offices = new StringBuilder();
|
||||
Map<Long, SysOffice> officeMap = getOfficeAllMap();
|
||||
SysOffice office = officeMap.get(deptId);
|
||||
|
||||
if(!StringUtil.isEmpty(office)) {
|
||||
|
||||
String[] parentIds = office.getParentIds().split(",");
|
||||
|
||||
for(String id : parentIds) {
|
||||
if (StringUtils.isNotBlank(id) && !id.equals("0") && !id.equals("1")) {//去除空|0无意义|1顶部公司组织机构
|
||||
SysOffice parentOffice = officeMap.get(Long.valueOf(id));
|
||||
offices.append(StringUtil.isEmpty(parentOffice) ? "" : parentOffice.getName()).append("-");
|
||||
}
|
||||
}
|
||||
|
||||
offices.append(office.getName());
|
||||
}
|
||||
return offices.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取授权主要对象
|
||||
*/
|
||||
public static Subject getSubject(){
|
||||
return SecurityUtils.getSubject();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录者对象
|
||||
*/
|
||||
public static Principal getPrincipal(){
|
||||
try{
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
Principal principal = (Principal)subject.getPrincipal();
|
||||
|
||||
if (principal != null){
|
||||
return principal;
|
||||
}
|
||||
// subject.logout();
|
||||
}catch (UnavailableSecurityManagerException e) {
|
||||
|
||||
}catch (InvalidSessionException e){
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Session getSession(){
|
||||
try{
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
Session session = subject.getSession(false);
|
||||
if (session == null){
|
||||
session = subject.getSession();
|
||||
}
|
||||
if (session != null){
|
||||
return session;
|
||||
}
|
||||
// subject.logout();
|
||||
}catch (InvalidSessionException e){
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ============== User Cache ==============
|
||||
|
||||
public static Object getCache(String key) {
|
||||
return getCache(key, null);
|
||||
}
|
||||
|
||||
public static Object getCache(String key, Object defaultValue) {
|
||||
// Object obj = getCacheMap().get(key);
|
||||
Object obj = getSession().getAttribute(key);
|
||||
return obj==null?defaultValue:obj;
|
||||
}
|
||||
|
||||
public static void putCache(String key, Object value) {
|
||||
// getCacheMap().put(key, value);
|
||||
getSession().setAttribute(key, value);
|
||||
}
|
||||
|
||||
public static void removeCache(String key) {
|
||||
// getCacheMap().remove(key);
|
||||
getSession().removeAttribute(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 是否是验证码登录
|
||||
* @param useruame 用户名
|
||||
* @param isFail 计数加1
|
||||
* @param clean 计数清零
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static boolean isValidateCodeLogin(String useruame, boolean isFail, boolean clean){
|
||||
Map<String, Integer> loginFailMap = (Map<String, Integer>)CacheUtils.get("loginFailMap");
|
||||
if (loginFailMap==null){
|
||||
loginFailMap = Maps.newHashMap();
|
||||
CacheUtils.put("loginFailMap", loginFailMap);
|
||||
}
|
||||
Integer loginFailNum = loginFailMap.get(useruame);
|
||||
if (loginFailNum==null){
|
||||
loginFailNum = 0;
|
||||
}
|
||||
if (isFail){
|
||||
loginFailNum++;
|
||||
loginFailMap.put(useruame, loginFailNum);
|
||||
}
|
||||
if (clean){
|
||||
loginFailMap.remove(useruame);
|
||||
}
|
||||
return loginFailNum >= 3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.nis.web.security;
|
||||
|
||||
import org.apache.shiro.web.filter.authc.LogoutFilter;
|
||||
|
||||
|
||||
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String captcha;
|
||||
private boolean mobileLogin;
|
||||
|
||||
public UsernamePasswordToken() {
|
||||
super();
|
||||
}
|
||||
|
||||
public UsernamePasswordToken(String username, char[] password,
|
||||
boolean rememberMe, String host, String captcha, boolean mobileLogin) {
|
||||
super(username, password, rememberMe, host);
|
||||
this.captcha = captcha;
|
||||
this.mobileLogin = mobileLogin;
|
||||
}
|
||||
|
||||
public String getCaptcha() {
|
||||
return captcha;
|
||||
}
|
||||
|
||||
public void setCaptcha(String captcha) {
|
||||
this.captcha = captcha;
|
||||
}
|
||||
|
||||
public boolean isMobileLogin() {
|
||||
return mobileLogin;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user