几天来,我一直致力于将Facebook与我们的应用程序集成。我已成功建立连接,现在在Facebook登录后,我将用户复制到我们的数据库,之后我想在上下文中使用我们的内部主体。
对于Spring安全登录,我们使用我们的类实现UserDetailsService
重载了 authentication-manager 。
当有人使用Facebook登录时,他拥有他无法知道的抽象凭据。 我在我的Facebook登录控制器中使用此方法登录他:
Authentication auth = new UsernamePasswordAuthenticationToken(
profile.getId(), new Md5PasswordEncoder().encodePassword(
profile.getEmail() + profile.getId(), null),
(Collection<? extends GrantedAuthority>) getAuthorities(profile.getId()));
问题:
在某些控制器中我使用
public String profile(Locale locale, Model model, HttpSession session, Principal principal)
然后principal
实际上包含不同的对象。
对于常规弹簧安全性登录:
org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4527d081: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@21a2c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: A5E9AB9E4AEE7486EC4B4F6133F77320; Granted Authorities: ROLE_ADMIN
但是在使用控制器中的方法登录之后:
org.springframework.security.authentication.UsernamePasswordAuthenticationToken@cd4699c5: Principal: 1405308431; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_CLIENT
问题: 我真的不想在所有控制器中区分这些类型。它为什么不同?!当我们使用普通凭证登录时,它显然是一个用户(我的类型)对象,它只是一个Facebook的字符串。 如何更改它以便facebook登录在我的安全上下文中也会给我User对象?
答案 0 :(得分:3)
您需要按照this chapiter末尾的说明设置SignInAdapter。在SignInAdapter.signIn(...)
方法中,您可以从DB加载用户对象,然后准备身份验证对象并将其注入安全上下文持有者。
答案 1 :(得分:1)
我一开始并没有真正得到'准备身份验证对象',但这真的很容易; 我发布此示例以供将来澄清可能需要它:)
public class FacebookAuthenticationToken extends AbstractAuthenticationToken
{
private final org.springframework.security.core.userdetails.UserDetails principal;
private String credentials;
public FacebookAuthenticationToken(org.springframework.security.core.userdetails.UserDetails details,FacebookProfile profile, Collection<? extends GrantedAuthority> authorities){
super(authorities);
this.principal = details;
this.credentials = new Md5PasswordEncoder().encodePassword(profile.getEmail()+profile.getId(), null);
super.setAuthenticated(true); // must use super, as we override
}
private static final long serialVersionUID = -7545290433068513777L;
public Object getCredentials() {
return this.credentials;
}
public Object getPrincipal() {
return this.principal;
}
}
现在我知道我甚至可以使用UsernamePasswordAuthenticationToken,
只需为Object principal
提供正确的课程。傻我。