Java 向存储在 spring 安全上下文中的主体对象添加其他详细信息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20349594/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding additional details to principal object stored in spring security context
提问by newUser
I am using Spring 3.0 and Spring Security 3. I am able to authenticate a user against a database using Spring Security. Using:
我正在使用 Spring 3.0 和 Spring Security 3。我能够使用 Spring Security 针对数据库对用户进行身份验证。使用:
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
I am able to retrieve username of the current logged in user. I wish to add additional details like user id and the module accesses to the principal object stored in Spring Security context so that I can retrieve it later. How can I add additional details to the principal object and then how can I retrieve it later on a jsp or java class. Please provide an appropriate code snippet if possible.
我能够检索当前登录用户的用户名。我希望添加其他详细信息,例如用户 id 和模块访问存储在 Spring Security 上下文中的主体对象,以便我可以稍后检索它。如何向主体对象添加其他详细信息,然后如何在 jsp 或 java 类上检索它。如果可能,请提供适当的代码片段。
Edit: I am using JDBC to access my database.
编辑:我正在使用 JDBC 访问我的数据库。
Thanks in advance.
提前致谢。
采纳答案by Yogen
In order to add more details to the authenticated user. You need to first create your own implementation of the User object which should extend the spring security User object. After that you can add the properties you want to add to the authenticated user. Once this is done you need to return your implementation of the user object in UserDetailService (If you are not using LDAP for authentication). This link provides the details for adding more details to the authenticated user--
为了向经过身份验证的用户添加更多详细信息。您需要首先创建您自己的 User 对象的实现,它应该扩展 spring security User 对象。之后,您可以向经过身份验证的用户添加要添加的属性。完成此操作后,您需要在 UserDetailService 中返回用户对象的实现(如果您未使用 LDAP 进行身份验证)。此链接提供了向经过身份验证的用户添加更多详细信息的详细信息--
http://javahotpot.blogspot.in/2013/12/spring-security-adding-more-information.html
http://javahotpot.blogspot.in/2013/12/spring-security-adding-more-information.html
回答by gpeche
(I will assume you have a basic Spring Security configuration working and know how the basic components work together)
(我假设你有一个基本的 Spring Security 配置,并且知道基本组件是如何协同工作的)
The most "correct" way would be providing your own implementation of AuthenticationProvider
, that return a custom Authentication
implementation. Then you can fill in this Authentication
instance with everything you need. For example:
最“正确”的方法是提供您自己的 实现AuthenticationProvider
,返回自定义Authentication
实现。然后你可以Authentication
用你需要的一切填充这个实例。例如:
public class MyAuthentication extends UsernamePasswordAuthenticationToken implements Authentication {
public MyAuthentication(Object principal, Object credentials, int moduleCode) {
super(principal, credentials);
this.moduleCode = moduleCode;
}
public MyAuthentication(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities,int moduleCode) {
super(principal, credentials, authorities);
this.moduleCode = moduleCode;
}
private int moduleCode;
public getModuleCode() {
return moduleCode;
}
}
public class MyAuthenticationProvider extends DaoAuthenticationProvider {
private Collection<GrantedAuthority> obtainAuthorities(UserDetails user) {
// return granted authorities for user, according to your requirements
}
private int obtainModuleCode(UserDetails user) {
// return moduleCode for user, according to your requirements
}
@Override
public Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
// Suppose this user implementation has a moduleCode property
MyAuthentication result = new MyAuthentication(authentication.getPrincipal(),
authentication.getCredentials(),
obtainAuthorities(user),
obtainModuleCode(user));
result.setDetails(authentication.getDetails());
return result;
}
}
And then, in applicationContext.xml
:
然后,在applicationContext.xml
:
<authentication-manager>
<authentication-provider ref="myAuthenticationProvider">
</authentication-manager>
<bean id="myAuthenticationProvider" class="MyAuthenticationProvider" scope="singleton">
...
</bean>
I guess you could get it working by providing custom implementations of AuthenticationDetails
and AuthenticationDetailsSource
, but I think that would be a less clean approach.
我想你可以通过提供AuthenticationDetails
and 的自定义实现来让它工作AuthenticationDetailsSource
,但我认为这会是一种不太干净的方法。
回答by M. Deinum
The "only" things you need to do is create your own UserDetailsServiceimplementation which returns your own implementation of a UserDetailsobject.
您需要做的“唯一”事情是创建您自己的UserDetailsService实现,它返回您自己的UserDetails对象实现。
See herefor a tutorial which implements a JPA based UserDetailsService
.
见这里为它实现基于JPA的教程UserDetailsService
。
回答by Alireza Fattahi
Here is what you need:
这是您需要的:
- Extend spring
User
(org.springframework.security.core.userdetails.User
) class and what ever properties you need. - Extend spring
UserDetailsService
(org.springframework.security.core.userdetails.UserDetailsService
) and fill the above object. OverrideloadUserByUsername
and return your extended user class - Set your custom
UserDetailsService
inAuthenticationManagerBuilder
- 扩展 spring
User
(org.springframework.security.core.userdetails.User
) 类以及您需要的任何属性。 - 拉伸弹簧
UserDetailsService
(org.springframework.security.core.userdetails.UserDetailsService
) 并填充上述对象。覆盖loadUserByUsername
并返回您的扩展用户类 - 设置自定义
UserDetailsService
的AuthenticationManagerBuilder
For example
例如
public class CurrentUser extends User{
//This constructor is a must
public CurrentUser(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
}
//Setter and getters are required
private String firstName;
private String lastName;
}
The Custom userdetails could be:
自定义用户详细信息可以是:
@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
//Try to find user and its roles, for example here we try to get it from database via a DAO object
//Do not confuse this foo.bar.User with CurrentUser or spring User, this is a temporary object which holds user info stored in database
foo.bar.User user = userDao.findByUserName(username);
//Build user Authority. some how a convert from your custom roles which are in database to spring GrantedAuthority
List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());
//The magic is happen in this private method !
return buildUserForAuthentication(user, authorities);
}
//Fill your extended User object (CurrentUser) here and return it
private User buildUserForAuthentication(foo.bar.User user,
List<GrantedAuthority> authorities) {
String username = user.getUsername();
String password = user.getPassword();
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new CurrentUser(username, password, enabled, accountNonExpired, credentialsNonExpired,
accountNonLocked, authorities);
//If your database has more information of user for example firstname,... You can fill it here
//CurrentUser currentUser = new CurrentUser(....)
//currentUser.setFirstName( user.getfirstName() );
//.....
//return currentUser ;
}
private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
// Build user's authorities
for (UserRole userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
return new ArrayList<GrantedAuthority>(setAuths);
}
}
Configure the spring security context
配置 spring 安全上下文
@Configuration
@EnableWebSecurity
@PropertySource("classpath://configs.properties")
public class SecurityContextConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
It's all done !
这一切都完成了!
You can call (CurrentUser)getAuthentication().getPrincipal()
to get you newly CurrentUser
or set some properties.
你可以打电话(CurrentUser)getAuthentication().getPrincipal()
给你新的CurrentUser
或设置一些属性。