java 单点登录 项目_单点登录demo,真心不方便发项目

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

干才有人问我要的.qq,不太喜欢加人.发这里吧.

说明:这个demo是单点登录一个思路,基于单机服务器的,全局globalsession 管理同样的思路,建议使用memcache或者redis,做一套session系统或者只维护session状态.

这个是基于内存map实现的,ps:说是demo,实际上是可以企业直接用的

url级别权限控制器.基于filter实现:

package com.an.core.controller;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import com.an.core.exception.ForbiddenException;

import com.an.core.exception.UnauthorizedException;

import com.an.core.utils.PayLoadRequestWrapper;

import com.an.core.utils.Util;

import com.an.sys.entity.User;

/**

* 用户权限过滤器(用户身份及权限验证)

*

* @author Karas

* @date

*/

public class GrantedFilter extends HttpServlet implements Filter {

private FilterConfig config;

private static final long serialVersionUID = -4275105240038370264L;

private static Logger logger = Logger.getLogger(GrantedFilter.class);

public static final ThreadLocal threadLocal = new ThreadLocal<>();

public void init(FilterConfig config) throws ServletException {

this.config = config;

}

public void doFilter(ServletRequest servletRequest,

ServletResponse servletResponse, FilterChain filterChain)

throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servletRequest;

HttpServletResponse response = (HttpServletResponse) servletResponse;

String uri = Util.nvl(request.getRequestURI(), "");

String method = request.getMethod();

String ip = request.getRemoteAddr();

String username = " ";

boolean flag = true;

String regEx = "(?<=" + request.getContextPath() + "/)[^/]+(/[^/]+|$)";

String act = "";

Pattern pattern = Pattern.compile(regEx);

Matcher matcher = pattern.matcher(uri.replace("/rest/", "/"));

if (matcher.find())

act = matcher.group();

String exclude = config.getInitParameter("exclude");

if (act.isEmpty() || !exclude.contains(act)) { // 需验证区域

try {

HttpSession session = request.getSession();

if (session == null)

throw new UnauthorizedException();

if (!SessionIntercept.isAlive(session.getId())) {

session.invalidate();

throw new UnauthorizedException("你已被强制登出!");

}

User user = (User) session.getAttribute(User.SESSION_KEY);

if (user == null)

throw new UnauthorizedException();

username = user.getLoginName();

if (!act.isEmpty() && !user.granted(act, method)) // 验证用户所访问资源权限许可

throw new ForbiddenException();

threadLocal.set(user);

if (user.isFirstTime()){

response.setContentType("text/html;charset=utf-8");

RequestDispatcher rd = request

.getRequestDispatcher("/sys/firstTime.html");

rd.forward(servletRequest, servletResponse);

}

} catch (UnauthorizedException e) {

flag = false;

response.setStatus(401);

if ("XMLHttpRequest".equals(request

.getHeader("X-Requested-With"))) {

response.setContentType("application/json;charset=utf-8");

PrintWriter out = response.getWriter();

out.write("登录超时!");

out.flush();

out.close();

} else {

response.setContentType("text/html;charset=utf-8");

RequestDispatcher rd = request

.getRequestDispatcher("/login.html");

rd.forward(servletRequest, servletResponse);

}

} catch (ForbiddenException e) {

flag = false;

response.setStatus(403);

if ("XMLHttpRequest".equals(request

.getHeader("X-Requested-With"))) {

response.setContentType("application/json;charset=utf-8");

PrintWriter out = response.getWriter();

out.write("权限验证失败!");

out.flush();

out.close();

} else {

response.setContentType("text/html;charset=utf-8");

RequestDispatcher rd = request

.getRequestDispatcher("/login.html");

rd.forward(servletRequest, servletResponse);

}

} catch (Exception e) {

flag = false;

response.setStatus(503);

logger.error(e.getMessage(), e);

} finally {

StringBuffer sb = new StringBuffer("ip:" + ip);

sb.append(",");

sb.append(request.getMethod());

sb.append(",");

sb.append(response.getStatus());

sb.append(",u:");

sb.append(username);

sb.append(",:");

sb.append(uri);

sb.append(",body:");

if ("application/json".equalsIgnoreCase(request.getContentType())) {

PayLoadRequestWrapper wrapper = new PayLoadRequestWrapper(

request);

sb.append(wrapper.getBody());

request = wrapper;

} else {

sb.append(JSONObject.fromObject(request.getParameterMap())

.toString());

}

logger.info(sb);

}

}

if (flag) {

filterChain.doFilter(request, response);

}

}

public void destroy() {

this.config = null;

}

}

然后是session状态管理器,基于map实现,这个如果换成基于reids实现就可以应用到分布式系统,并且避免了session复制,同时,如果要使用restful风格的去session ,就要自己写一个系统,这里只提供思路

package com.an.core.controller;

import javax.servlet.http.HttpSession;

import java.util.*;

/**

* Session 状态管理

* Created by karas on 9/2/14.

*/

public class SessionIntercept {

private static Map AppSession = new HashMap<>();

public static void forceQuit(String userId) {

Set> set = AppSession.entrySet();

for (Map.Entry entry : set) {

if (userId.equals(entry.getValue())) {

AppSession.remove(entry.getKey());

}

}

AppSession.remove(userId);

}

public static void add(String userId, String sessionId) {

AppSession.put(sessionId, userId);

}

public static boolean isAlive(String value) {

return AppSession.containsKey(value);

}

public static boolean isOnline(String key) {

return AppSession.containsValue(key);

}

public static boolean isOnline(String userId, HttpSession session) {

Set> set = AppSession.entrySet();

for (Map.Entry entry : set) {

if (entry.getValue().equals(userId) && !session.getId().equals(entry.getKey())) {

return true;

}

}

return false;

}

public static void remove(String sid) {

AppSession.remove(sid);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值