Spring Security 从两个实现 UserDetails 的方法中检索当前用户对象

Posted

技术标签:

【中文标题】Spring Security 从两个实现 UserDetails 的方法中检索当前用户对象【英文标题】:Spring Security retrieve current user object out two methods implementing UserDetails 【发布时间】:2015-03-22 06:15:11 【问题描述】:

我正在开发一个 Spring-MVC 项目,我正在使用 Spring-Security 进行身份验证和其他安全功能。现在项目分为两部分,一是个人登录,二是群组登录。 对于他们两个,我使用不同的数据库表。但是这两个表的 Java 类都实现了 UserDetails 和 userDetailsS​​ervice 的一个实例。 现在,当用户从个人帐户或组帐户登录时,我想从任一类中提取当前登录的用户对象。这样,我就能知道是群组用户登录还是个人帐户用户登录。请告诉我该怎么办?

安全应用程序上下文.xml:

    <security:http create-session="ifRequired" use-expressions="true"
                   entry-point-ref="loginUrlAuthenticationEntryPoint"
                   auto-config="false" disable-url-rewriting="true">
        <security:logout logout-success-url="/" delete-cookies="JSESSIONID"
                         invalidate-session="true" logout-url="/j_spring_security_logout"/>
        <security:custom-filter ref="CustomUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER" />
        <security:port-mappings>
            <security:port-mapping http="8080" https="8443"/>
        </security:port-mappings>
    </security:http>

  <bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
      <property name="defaultFailureUrl" value="/login.do?error"/>
  </bean>

    <bean id="loginUrlAuthenticationEntryPoint"
          class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <property name="loginFormUrl" value="/login.do"/>
    </bean>

    <bean id="authenticationManagerForPersonal" class="com.journaldev.spring.utility.CustomDAOAuthenticationProvider">
        <constructor-arg index="0" value="org.springframework.security.authentication.UsernamePasswordAuthenticationToken"/>
        <property name="userDetailsService" ref="LoginServiceImpl"/>
        <property name="passwordEncoder" ref="encoder"/>
    </bean>

    <bean id="authenticationManagerForGroup" class="com.journaldev.spring.utility.CustomDAOAuthenticationProvider">
        <constructor-arg index="0" value="com.journaldev.spring.utility.CustomUsernamePasswordAuthenticationToken"/>
        <property name="userDetailsService" ref="GroupLoginServiceImpl"/>
        <property name="passwordEncoder" ref="encoder"/>
    </bean>

    <bean id="CustomUsernamePasswordAuthenticationFilter" class="com.journaldev.spring.utility.CustomUsernamePasswordAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationFailureHandler" ref="failureHandler"/>
        <property name="authenticationSuccessHandler" ref="redirectRoleStrategy"/>
    </bean>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="authenticationManagerForPersonal"/>
        <security:authentication-provider ref="authenticationManagerForGroup"/>
    </security:authentication-manager>

    <bean id="redirectRoleStrategy" class="com.journaldev.spring.utility.RoleBasedAuthenticationSuccessHandler">
        <property name="roleUrlMap">
            <map>
                <entry key="ROLE_USER" value="/person.do"/>
                <entry key="ROLE_GROUP" value="/group.do"/>
            </map>
        </property>
    </bean>

    <beans:bean id="encoder"
                class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        <beans:constructor-arg name="strength" value="11" />
    </beans:bean>

Person.Java(个人账户模型类):

@Entity
@Table(name="person")
public class Person implements UserDetails

@Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "person_seq_gen")
    @SequenceGenerator(name = "person_seq_gen",sequenceName = "person_seq")
    private int id;
// other values

GroupMember.java(组帐户成员模型)

@Entity
@Table(name="groupmembers")
public class GroupMembers implements UserDetails 

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_GROUP");

    @Id
    @Column(name="memberid")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupmembers_seq_gen")
    @SequenceGenerator(name = "groupmembers_seq_gen",sequenceName = "groupmembers_seq")
    private Long memberid;
    // Other values

编辑: 这就是我检索当前用户的方式,但是我找不到如何检查它是哪个对象,我可以得到一个 UserDetails 的对象,但是由于两种方法都实现了 UserDetails,我无法分辨它是哪个。

  @Override
    public Person getCurrentlyAuthenticatedUser() 
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication == null)
            return null;
         else 
            return personDAO.findPersonByUsername(authentication.getName());
        
    

【问题讨论】:

你到现在有没有尝试过,你有什么错误吗?? @EkanshRastogi 是的。我有获取此人的代码,我将在帖子中添加。我也在并行处理其他一些代码。 【参考方案1】:

我希望这应该很简单。

您有两个 UserDetails 对象 User1 和 User2,假设 User1 属于 Person 类,而 User2 属于 GroupPerson。

您可以按照您的说明获取 UserDetails 对象,然后您需要做的就是检查该对象是 Person 还是 GroupMembers 的实例。

您可以使用instanceof 来完成,如下所示

if(userObject instanceof Person)
 // DO Stuff

else if(userObject instanceof GroupMembers)
 // Do Stuff

这里你的 userObject 可以是 Person 或 GroupMember 的对象

【讨论】:

以上是关于Spring Security 从两个实现 UserDetails 的方法中检索当前用户对象的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Spring Security自定义用户认证

基于 XML 的 Spring Security 配置中的 use-expressions 属性等同于基于代码的配置

Spring Security JWT - 400 错误请求:“无效授权”“错误凭据”

我是这样使用SpringBoot(Spring Security实现用户登录)

Spring Security整合JWT,实现单点登录,So Easy~!

Spring Security 不会抛出任何异常