spring-security 向存储在Spring Security上下文中的主体对象添加其他详细信息

cgvd09ve  于 2022-11-11  发布在  Spring
关注(0)|答案(4)|浏览(256)

我正在使用Spring 3.0和Spring Security 3。我能够使用Spring Security针对数据库验证用户。使用:

SecurityContextHolder.getContext().getAuthentication().getPrincipal()

我可以检索当前登录用户的用户名。我希望添加其他详细信息(如用户ID和对存储在Spring Security上下文中的主体对象的模块访问权限),以便以后可以检索它。如何向主体对象添加其他详细信息,以及以后如何在jsp或java类中检索它。如果可能,请提供适当的代码段。
编辑:我正在使用JDBC访问我的数据库。
先谢谢你。

mmvthczy

mmvthczy1#

以下是您需要的内容:
1.扩展SpringUserorg.springframework.security.core.userdetails.User)类和您需要的任何属性。
1.扩展spring UserDetailsServiceorg.springframework.security.core.userdetails.UserDetailsService)并填充上面的对象。重写loadUserByUsername并返回扩展的用户类
1.在AuthenticationManagerBuilder中设置自定义UserDetailsService
比如说

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;

}

自定义用户详细信息可以是:

@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);
}

}

配置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);
    }

都搞定了!
您可以调用(CurrentUser)getAuthentication().getPrincipal()来获取新的CurrentUser或设置一些属性。

ttcibm8c

ttcibm8c2#

为了向已验证的用户添加更多的细节。您需要首先创建您自己的User对象的实现,该实现应该扩展spring安全User对象。之后,您可以添加您想要添加到已验证的用户的属性。完成后,您需要返回UserDetailService中的用户对象的实现(如果您未使用LDAP进行验证)。此链接提供有关向已验证用户添加更多详细资料的详细资料--
http://javahotpot.blogspot.com/2013/12/spring-security-adding-more-information.html

sqxo8psd

sqxo8psd3#

(我假设您有一个基本的Spring Security配置,并且知道基本组件是如何协同工作的)
最“正确”的方法是提供您自己的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;
    }
}

然后,在applicationContext.xml中:

<authentication-manager>
    <authentication-provider ref="myAuthenticationProvider">
</authentication-manager>

<bean id="myAuthenticationProvider" class="MyAuthenticationProvider" scope="singleton">
    ...
</bean>

我想您可以通过提供AuthenticationDetailsAuthenticationDetailsSource的自定义实现来使其工作,但我认为这是一种不太清晰的方法。

cnwbcb6i

cnwbcb6i4#

您需要做的“唯一”事情是创建您自己的UserDetailsService实现,该实现返回您自己的UserDetails对象实现。
有关实现基于JPA的UserDetailsService的教程,请参见here

相关问题