我可以将我自己的用户对象推送到 Spring 的安全上下文中吗?



我是Spring Security的新手,并且遵循了一些基本的食谱以使Spring Security在我的应用程序中工作,但是现在我想看看是否有一种方法可以获取自己的方法登录/身份验证时,用户对象添加到Spring的SecurityContext。

当前我的安全性用于使用JDBCDAOIMPL:

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="com.ia.security.SpringSecurityDao" />
</authentication-manager>
<beans:bean id="com.ia.security.SpringSecurityDao" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <beans:property name="usersByUsernameQuery">
        <beans:value>select username,password,enabled 
        from user 
        where username = ?
        </beans:value>
    </beans:property>
    <beans:property name="dataSource" ref="dataSource" />
    <beans:property name="enableGroups" value="true" />
    <beans:property name="enableAuthorities" value="false" />
    <beans:property name="groupAuthoritiesByUsernameQuery">
        <beans:value>SELECT R.ID, R.NAME, P.NAME
            FROM ROLE R
            JOIN USER_ROLE UR on R.id = UR.role_id
            JOIN USER U on U.id = UR.user_id
            JOIN ROLE_PERMISSION RP ON RP.role_id = R.id
            JOIN PERMISSION P ON P.id = RP.permission_id
            WHERE U.username=?
        </beans:value>
    </beans:property>
</beans:bean>

我意识到我可以从SecurityContext中检索Principal对象,并获取用户名并申请db给定用户名,但是认为简单地将我的整个User对象放在SecurityContext中,以使其易于访问,将其简单地存储在SecurityContext中每当我在整个应用程序中都需要它,而不是仅存储用户名,密码和启用字段在UserDetails对象中。

我已经研究了UserDetailsService,更具体地说是JdbcDaoImpl类,但不完全确定继续进行的最佳方法。如果我只是通过调用super.loadUserByUsername来覆盖/扩展,那么loadUserByUsername方法返回我自己的用户访问对象就足够了吗?那我只能做SecurityContextHolder.getContext().getAuthentication().getDetails()并将其施放给我自己的对象?

我在Stackoverflow上找到了与此相关的其他帖子,但是大多数人似乎都忽略了与DB检索到的当局和角色有关的任何事情,因此我不确定这是否是继续进行的最佳方法。

简短答案:是的,您可以按照您的计划进行。请记住,诸如" Hasrole"之类的某些功能会检查当局列表,而不是默认情况下的用户详细信息。

长答案:将用户对象保存在会话中保存的安全性context中可能会产生一些副作用。当您使用Hibernate时,尤其如此。懒惰的例外吗?)我们首先走了这条路线,后来有几次电话发生了一些谎言,这很难跟进。使用OpenSessionInview过滤器,我们认为我们很安全,但这完全是错误的,就像下一个请求中的会话消失一样。因此,我们从用户加载了更多相关的对象,但它仍然发生了。稍后:)

我们有三个选择。要么在每个请求上合并用户对象,要么创建一个仅保存在用户限制中的必要安全信息的pojo,要么仅保留委托人(登录),然后将用户对象加载到需要的情况下。

我们使用了第三个解决方案,因为Hibernate使用第二级缓存做得很好。作为副作用,安全现在更加可靠,因为Spring Security现在获得了每个请求上的最新版本的用户,并且不适用于"陈旧"用户角色。

因此,如果您不使用冬眠,或者可以保证不会发生任何谎言,那么解决方案一两个。否则我会推荐我们的方法。

最新更新