Java 从spring security检索当前用户的密码

Java 从spring security检索当前用户的密码,java,spring-security,Java,Spring Security,我正在使用spring security和HTTP Basic Auth来保护java webapp。在我的webapp中,我需要获取当前用户的用户名和密码,以进一步针对其他服务对其进行身份验证。我可以得到用户名,但不能得到密码 我已尝试使用SecurityContextHolder.getContext().getAuthentication()访问此处建议的信息,但密码返回为null 我怎样才能获得密码 谢谢 这是我的applicationContext-security.xml <b

我正在使用spring security和HTTP Basic Auth来保护java webapp。在我的webapp中,我需要获取当前用户的用户名和密码,以进一步针对其他服务对其进行身份验证。我可以得到用户名,但不能得到密码

我已尝试使用
SecurityContextHolder.getContext().getAuthentication()
访问此处建议的信息,但密码返回为
null

我怎样才能获得密码

谢谢

这是我的applicationContext-security.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<sec:http authentication-manager-ref='authenticationManager'>
    <sec:intercept-url pattern="/spring/**" access="ROLE_USER" />
    <sec:http-basic />
</sec:http>

<bean id="basicAuthenticationFilter"
    class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
</bean>

<bean id="authenticationEntryPoint"
    class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
    <property name="realmName" value="Announcements Rest Realm" />
</bean>

<bean id="authenticationManager"
    class="org.springframework.security.authentication.ProviderManager">
    <property name="providers">
        <list>
            <ref local="authProvider" />
        </list>
    </property>
</bean>

<bean id="authProvider"
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="userDetailsService" />
</bean>

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
    <constructor-arg>
        <list>
            <sec:filter-chain pattern="/spring/**" filters="basicAuthenticationFilter" />
        </list>
    </constructor-arg>
</bean>

<sec:user-service id="userDetailsService">
    <sec:user name="admin" password="**" authorities="ROLE_USER, ROLE_ADMIN" />
    <sec:user name="user" password="**" authorities="ROLE_USER" />
</sec:user-service>


您是否使用记住我/以用户身份运行/切换用户?在这种情况下,密码为null(如您提到的线程中所述)。另外,您可能必须使用基本表单身份验证(向j_spring_安全检查发送请求)

如果您正在设置当前用户的全部详细信息,包括会话对象中的密码,那么您可以从该会话对象获取密码。

我已经找到了答案

我已将身份验证管理器配置更改为使用身份验证管理器元素,并在其中添加了属性:

<sec:authentication-manager alias="authenticationManager" erase-credentials="false">
    <sec:authentication-provider ref="authProvider" />      
</sec:authentication-manager>

然后,我可以在控制器类中使用
SecurityContextHolder.getContext().getAuthentication().getCredentials()
来获取密码


感谢您的帮助,尽管Piotrek De

一个更好的方法是实现您的“用户详细信息服务”。因此,您可以控制在进行身份验证时如何初始化UserDetails。我实现了基于表单的身份验证并编写了自定义用户服务

@Service("userService")
public class UserServiceImpl extends GenericService<User> implements UserDetailsService,UserService{



    @Override
        @Transactional
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
               // Declare a null Spring User
            UserDetails userDetails = null;



            // Search database for a user that matches the specified username
            // You can provide a custom DAO to access your persistence layer
            // Or use JDBC to access your database
            // DbUser is our custom domain user. This is not the same as Spring's User
            User dbUser=this.findUserByUserName(username);

            if (dbUser == null) {
                throw new UsernameNotFoundException("HiMVC Security:: Error in retrieving user(username=" + username + ")");
            }



            userDetails = new org.springframework.security.core.userdetails.User(
                    dbUser.getUserName(),
                    dbUser.getPassword(),//here you can put a clear text password
                    true,
                    true,
                    true,
                    true,
                    loadUserAuthorities(username));


            return userDetails;
        }
@Service(“用户服务”)
公共类UserServiceImpl扩展GenericService实现UserDetailsService,UserService{
@凌驾
@交易的
public UserDetails loadUserByUsername(字符串用户名)抛出UsernameNotFoundException、DataAccessException{
//声明一个空的Spring用户
UserDetails UserDetails=null;
//在数据库中搜索与指定用户名匹配的用户
//您可以提供一个自定义DAO来访问持久层
//或者使用JDBC访问您的数据库
//DbUser是我们的自定义域用户。这与Spring的用户不同
User dbUser=this.findUserByUserName(用户名);
if(dbUser==null){
抛出新的UsernameNotFoundException(“HiMVC安全性::检索用户时出错(username=“+username+”);
}
userDetails=new org.springframework.security.core.userDetails.User(
dbUser.getUserName(),
dbUser.getPassword(),//这里可以输入明文密码
是的,
是的,
是的,
是的,
LoadUserAuthories(用户名));
返回用户详细信息;
}

据我所知,我没有使用Memory me、run as或switch user(除非默认情况下启用了它们?我没有使用auto config)。此外,我不能使用表单身份验证,因为我的webapp是一个web服务。好的,那么如何通知SI用户已成功通过身份验证?如果使用SecurityContextHolder.getContext().setAuthentication(…),那么您传递的是什么类型的令牌?我不是直接调用setAuthentication(),它必须发生在我配置的一个bean中。我将使用applicationContext-security.xml更新我的帖子,以防有所帮助。我只是尝试改为使用基于表单的身份验证和SecurityContextHolder.getContext()getAuthentication()进行设置.getCredentials()仍然返回null。作为基于表单的,您是说POST to j_spring_安全检查?会话中唯一的内容是从getAuthentication返回的同一个对象,以及getCredentials()方法返回null。从Spring 3.1开始,默认情况下,这将不起作用-在成功身份验证时,凭据将被擦除。请参阅Nice find。不知道
erase credentials=“false”
这正是我所需要的,尽管我有点担心安全问题;但我看不到其他合理的方法来避免这些问题。LDAP登录也很好。在设置橡皮擦0Credentials=false Authentication loggedInUser=SecurityContextHolder.getContext().getAuthentication()后,我使用了以下方法;String username=loggedInUser.getName();String password=loggedInUser.getCredentials().toString();但是仍然要以空字符串的形式接收密码,有什么建议吗?但是这样,您从数据库中获取的密码应该(希望)只是一个散列,对吗?因此它对于OP的预期用途毫无用处(针对第三方服务的进一步身份验证)。他需要在HTTP请求中发送密码。