Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UserInfoHolder(Required):获取当前登录用户信息,SSO一般都是把当前登录用户信息放在线程ThreadLocal上 #2607

Closed
endypark opened this issue Sep 19, 2019 · 8 comments

Comments

@endypark
Copy link

这个描述太模糊了吧,我看Ctrip的实现,也是用了一堆的反射,还是调用的sso远程。
1 . 这个是查询本地的User,还是查询SSO的当前登录用户,还是先本地再SSO,如果是SSO,那么就会碰到问题2 ?

  1. 我sso使用的是Webflux 和 Redis,没有request.getSession或request.getSslInfo()这个东西,该如何无参数查询到对应的在线用户? (现在在分布式系统中,request.getSession的用户基本被废弃了吧,请问是否有 支持Redis 的方案)

由于查不到UserInfoHolder.getUser被什么方法调用了,具体干什么用的,所以自己也无法做更多理解,是否可以替换为 带参数的 getUser(param) 。

@endypark
Copy link
Author

我在Filter中,如果 通过,则: set authentication,如下:

SecurityContextHolder.getContext().setAuthentication(new Authentication() {
/**
*
*/
private static final long serialVersionUID = 6162391002484452337L;

			@Override
			public String getName() {
				return null;
			}
			
			@Override
			public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
				
			}
			
			@Override
			public boolean isAuthenticated() {
				return false;
			}
			
			@Override
			public Object getPrincipal() {
				return SessionUtils.getSessionUser(request);
			}
			
			@Override
			public Object getDetails() {
				return null;
			}
			
			@Override
			public Object getCredentials() {
				return null;
			}
			
			@Override
			public Collection<? extends GrantedAuthority> getAuthorities() {
				return null;
			}
		});

然后,再在 UserInfoHolder的实现类中 get authentication,如下:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal instanceof SessionUser) {
String account = ((SessionUser) principal).getAccount();
return new UserInfo(account);
}
return new UserInfo(principal.toString());

这样应该可以吧?

@nobodyiam
Copy link
Member

接入SSO的思路如下,ctrip的实现使用反射是因为不想让开源代码依赖内部的jar包。

  1. SSO会提供一个jar包,需要配置一个filter
  2. filter会拦截所有请求,检查是否已经登录
  3. 如果没有登录,那么就会跳转到SSO的登录页面
  4. 在SSO登录页面登录成功后,会跳转回apollo的页面,带上认证的信息
  5. 再次进入SSO的filter,校验认证信息,把用户的信息保存下来,并且把用户凭证写入cookie或分布式session,以免下次还要重新登录
  6. 进入Apollo的代码,Apollo的代码会调用UserInfoHolder.getUser获取当前登录用户

@happyyangyuan
Copy link

弱弱地问下,阿波罗目前有没有开箱即用的SSO接口,可以让我不修改阿波罗程序就可以单点登入到阿波罗呀?

@nobodyiam
Copy link
Member

nobodyiam commented Oct 1, 2019

@happyyangyuan

sso有多种实现,所以目前没有标准开箱即用的方式,ldap是有的。

@happyyangyuan
Copy link

@happyyangyuan

sso有多种实现,所以目前没有标准开箱即用的方式,ldap是有的。

好的,感谢

@endypark
Copy link
Author

endypark commented Oct 8, 2019

UserInfoHolder(Required), 我的 这个最终实现是: 1. 增加一个类 CustomThreadLocal, 里面有一个public static final ThreadLocal sThreadLocal; 2. Filter如果验证通过,那么 sThreadLocal.set(userInfo); 3. 然后在UserInfoHolder的实现类中,直接 sThreadLocal.get。
这样相当于每次请求都要set,这样才能保证业务代码中可以get到当前线程的user。

over.

@endypark endypark closed this as completed Oct 8, 2019
@maxiaoyin
Copy link

你们最后实现SSO了么

@maxiaoyin
Copy link

您好, CustomThreadLocal 的代码能参考下么

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants