提交 6cd988ea 编写于 作者: sinat_25235033's avatar sinat_25235033

reconstruct security subject holder - ThreadContext to SurenessContextHolder

上级 e437742e
......@@ -2,7 +2,6 @@ package com.usthe.sureness.subject;
import com.usthe.sureness.subject.support.SurenessSubjectSum;
import com.usthe.sureness.util.ThreadContext;
import java.io.Serializable;
import java.util.List;
......@@ -68,14 +67,10 @@ public interface Subject extends Serializable {
String principal = (String)getPrincipal();
List<String> roles = (List<String>)getOwnRoles();
String targetUri = (String)getTargetResource();
SubjectSum subject = SurenessSubjectSum.builder()
return SurenessSubjectSum.builder()
.setTargetResource(targetUri)
.setRoles(roles)
.setPrincipal(principal)
.build();
// 将subject 绑定到localThread变量中
ThreadContext.bind(subject);
// 如果是网关认证中心, 之后可以考虑把subject绑定到request请求中,供子系统使用
return subject;
}
}
package com.usthe.sureness.util;
import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.SubjectSum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* learn from ThreadContext
* @author from shiro
* @date 23:01 2019-01-09
*/
public class SurenessContextHolder {
private static final Logger logger = LoggerFactory.getLogger(SurenessContextHolder.class);
public static final String SUBJECT_KEY = "SUBJECT_KEY";
private static final ThreadLocal<Map<Object, Object>> RESOURCES = InheritableThreadLocal
.withInitial(() -> new HashMap<>(8));
/**
* 线程结束前调用 清空内容 防止oom
*/
public static void clear() {
RESOURCES.remove();
}
public static void bind(Object key, Object value) {
internalPut(key, value);
}
public static void unbind(Object key) {
if (key != null) {
internalRemove(key);
}
}
public static Object getBind(Object key) {
if (key == null) {
return null;
}
return internalGet(key);
}
public static void bindSubject(SubjectSum subjectSum) {
internalPut(SUBJECT_KEY, subjectSum);
}
public static void bindSubject(Subject subject) {
if (subject != null) {
internalPut(SUBJECT_KEY, subject.generateSubjectSummary());
}
}
public static void unbindSubject() {
internalRemove(SUBJECT_KEY);
}
public static SubjectSum getBindSubject() {
return (SubjectSum) internalGet(SUBJECT_KEY);
}
private static void internalPut(Object key, Object value) {
if (key == null) {
throw new NullPointerException("key cannot be null");
} else if (value == null) {
internalRemove(key);
} else {
ensureResourcesInitialized();
RESOURCES.get().put(key, value);
}
}
private static Object internalGet(Object key) {
if (logger.isTraceEnabled()) {
logger.trace("get() - in thread [{}]", Thread.currentThread().getName());
}
Map<Object, Object> perThreadResources = RESOURCES.get();
return perThreadResources != null ? perThreadResources.get(key) : null;
}
private static void internalRemove(Object key) {
Map<Object, Object> perThreadResources = RESOURCES.get();
if (perThreadResources != null) {
perThreadResources.remove(key);
}
}
private static void ensureResourcesInitialized() {
if (RESOURCES.get() == null) {
RESOURCES.set(new HashMap<>(8));
}
}
}
package com.usthe.sureness.util;
import com.usthe.sureness.subject.SubjectSum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* learn from shiro ThreadContext
* @author from shiro
* @date 23:01 2019-01-09
*/
public class ThreadContext {
private static final Logger logger = LoggerFactory.getLogger(ThreadContext.class);
public static final String SUBJECT_KEY = ThreadContext.class.getName() + "_SUBJECT_KEY";
@SuppressWarnings("unchecked")
private static final ThreadLocal<Map<Object, Object>> RESOURCES = new ThreadContext.InheritableThreadLocalMap();
public static void bind(SubjectSum subject) {
if (subject != null) {
put(SUBJECT_KEY, subject);
}
}
public static SubjectSum unbindSubject() {
return (SubjectSum)remove(SUBJECT_KEY);
}
public static SubjectSum getBindSubject() {
return (SubjectSum)get(SUBJECT_KEY);
}
private static void put(Object key, Object value) {
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
} else if (value == null) {
remove(key);
} else {
ensureResourcesInitialized();
(RESOURCES.get()).put(key, value);
if (logger.isTraceEnabled()) {
String msg = "Bound value of type [" + value.getClass().getName() + "] for key [" + key + "] to thread [" + Thread.currentThread().getName() + "]";
logger.trace(msg);
}
}
}
private static Object get(Object key) {
if (logger.isTraceEnabled()) {
String msg = "get() - in thread [" + Thread.currentThread().getName() + "]";
logger.trace(msg);
}
Map<Object, Object> perThreadResources = RESOURCES.get();
Object value = perThreadResources != null ? perThreadResources.get(key) : null;
if (value != null && logger.isTraceEnabled()) {
String msg = "Retrieved value of type [" + value.getClass().getName() + "] for key [" + key + "] bound to thread [" + Thread.currentThread().getName() + "]";
logger.trace(msg);
}
return value;
}
private static Object remove(Object key) {
Map<Object, Object> perThreadResources = RESOURCES.get();
Object value = perThreadResources != null ? perThreadResources.remove(key) : null;
if (value != null && logger.isTraceEnabled()) {
String msg = "Removed value of type [" + value.getClass().getName() + "] for key [" + key + "]from thread [" + Thread.currentThread().getName() + "]";
logger.trace(msg);
}
return value;
}
@SuppressWarnings("unchecked")
private static void ensureResourcesInitialized() {
if (RESOURCES.get() == null) {
RESOURCES.set(new HashMap(8));
}
}
public static void remove() {
RESOURCES.remove();
}
private static final class InheritableThreadLocalMap<T extends Map<Object, Object>> extends InheritableThreadLocal<Map<Object, Object>> {
private InheritableThreadLocalMap() {
}
@Override
@SuppressWarnings("unchecked")
protected Map<Object, Object> childValue(Map<Object, Object> parentValue) {
return parentValue != null ? (Map)((HashMap)parentValue).clone() : null;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册