简体   繁体   English

我可以将自己的User对象推送到Spring的SecurityContext吗?

[英]Can I push my own User object into Spring's SecurityContext?

I'm new to Spring Security and have followed some basic recipes to get Spring Security working in my application, but now I'm trying to see if there is a way to get my own User object added to Spring's SecurityContext upon login/authentication. 我是Spring Security的新手,并且已经按照一些基本的食谱来使Spring Security在我的应用程序中运行,但是现在我正在尝试查看是否有一种方法可以在登录/身份验证时将自己的User对象添加到Spring的SecurityContext中。

My security is currently configured to use the JdbcDaoImpl: 我的安全性当前配置为使用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>

I realize that I can retrieve the Principal object from the SecurityContext and get the username and requery the DB given the username, but was thinking it would be easier to simple store the my entire User object in the SecurityContext to have it easily accessible whenever I need it throughout my application as opposed to just storing the username, password and enabled fields in the UserDetails object. 我意识到我可以从SecurityContext中检索Principal对象并获取用户名,然后使用给定的用户名重新查询数据库,但是我认为将我的整个User对象简单地存储在SecurityContext中以便在需要时可以轻松访问它会更容易它遍及我的整个应用程序,而不仅仅是在UserDetails对象中存储用户名,密码和启用的字段。

I've looked into the UserDetailsService, and more specifically the JdbcDaoImpl class, but not entirely sure of the best way to proceed. 我已经研究了UserDetailsS​​ervice,更具体地说是JdbcDaoImpl类,但并不完全确定最佳方法。 If I simply override/extend by calling super.loadUserByUsername the loadUserByUsername method to return my own UserDetails object is that sufficient? 如果我只是简单地通过调用super.loadUserByUsername覆盖/扩展,则loadUserByUsername方法返回我自己的UserDetails对象就足够了吗? Then would I just be able to do SecurityContextHolder.getContext().getAuthentication().getDetails() and cast it to my own object? 然后,我是否能够执行SecurityContextHolder.getContext().getAuthentication().getDetails()并将其SecurityContextHolder.getContext().getAuthentication().getDetails()为我自己的对象?

I've found other posts on StackOverflow that relate to this, but most seem to be ignoring anything to do with Authorities and Roles that are retrieved from the DB, so I'm not sure if this is the best way to proceed. 我在StackOverflow上找到了与此相关的其他帖子,但是大多数帖子似乎都忽略了与从数据库中检索到的Authorities和Roles有关的任何内容,因此我不确定这是否是最好的处理方法。

The short answer: Yes you can do exactly as you planned. 简短的答案:是的,您可以完全按照计划进行。 Keep in mind that some functionality like "hasRole" checks the authorities list and not the user details by default. 请记住,默认情况下,某些功能(例如“ hasRole”)会检查权限列表,而不是用户详细信息。

The long answer: Keeping a user object in the securitycontext, which is held in the session can have some side effects. 很长的答案:将用户对象保留在会话中保留的securitycontext中可能会有一些副作用。 This is particularly true when you are using hibernate. 使用休眠模式时尤其如此。 Lazy exceptions anyone? 懒惰的例外有人吗? ;) We went this route first and several calls later some LIEs happend which was quite tricky to follow up. ;)我们先走了这条路线,然后打了几个电话,发生了一些LIE,要跟进它非常棘手。 Using the OpenSessionInView filter, we thought we are safe, but that's just wrong as in the next request the session is gone. 使用OpenSessionInView过滤器,我们认为我们很安全,但这是错误的,因为在下一个请求中会话已消失。 So we loaded more related objects from the user and it still happend. 因此,我们从用户那里加载了更多相关对象,并且这种情况仍然发生。 Just later :) 稍后:)

We had three options. 我们有三个选择。 Either merge the user object on each request, create a pojo holding just the neccessary security information in the userdetails, or just keep the principal (login) in the security context and load the user object once it's needed. 要么在每个请求上合并用户对象,要么创建一个pojo,仅在用户详细信息中保存必要的安全性信息,要么仅将主体(登录名)保留在安全性上下文中,并在需要时加载用户对象。

We went with the third solution as hibernate does a good job using the second level cache. 我们采用了第三种解决方案,因为休眠状态使用第二级缓存可以很好地完成工作。 As a side effect the security is now more reliable as spring security gets now the latest version of a user on each request and does not work with "stale" user roles. 副作用是,安全性现在更加可靠,因为Spring Security会在每个请求上获取用户的最新版本,并且不适用于“过时的”用户角色。

So if you dont use hibernate or you can guarantee that no LIEs will happen go for solution one or two. 因此,如果您不使用休眠模式,或者可以保证不会发生任何LIE,请选择解决方案一或二。 Else i would recommend our approach. 否则我会推荐我们的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Apache可以基于Tomcat Web应用程序的Spring SecurityContext限制访问吗? - Can Apache restrict access based on a Tomcat webapp's Spring SecurityContext? 如何模拟Spring SecurityContext,以便可以与TestNG一起使用? - How to mock Spring SecurityContext so I can use it with TestNG? 如何连接到Spring的@RequestBody参数解析,以使用请求的主体解析我自己的参数 - How can I hook into Spring's @RequestBody argument resolving to resolve my own argument using the body of the request 我可以在自己的注释中使用Spring Security @PreAuthorize吗? - Can I use the Spring Security @PreAuthorize on my own annotations? 如何在春季发送自己的回复? - How can I send my own response in spring? 我想要一个我可以在自己程序的时间内读取的HttpResponse对象(或类似对象),而不必担心服务器超时 - I want an HttpResponse object (or similar) that I can read in my own program's time without having to worry about server timeouts 如何仅对用户自己的端点启用请求 - How can I enable request only for user's own endpoint 如何在 Jax-RS 中使用 SecurityContext 来获取指定用户的 Token? - How can i use SecurityContext in Jax-RS to get Token of a specified user? 如何在我的 Android 应用程序中使用用户自己的短信服务发送 OTP 并进行手机号码验证? - How can I use a user's own SMS service to send OTP and make mobile number verification in my Android app? 如何在反序列化期间手动创建自己的对象? - How can I manually create my own object during deserialization?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM