代码之家  ›  专栏  ›  技术社区  ›  AndreaNobili

如何在使用LDAP进行身份验证的项目中正确配置SpringSecurity的记住我选项?

  •  0
  • AndreaNobili  · 技术社区  · 10 年前

    我对SpringMVC很熟悉,在尝试理解如何在登录页面中实现“记住我”功能时遇到了一些问题。

    所以我正在开发一个Spring项目,该项目使用 4.1.7.释放 Spring版本。此web应用程序使用Spring Security和 LDAP协议 以处理用户登录。

    在这个项目中,我有一个名为 登录.jsp ,这个:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@page session="true"%>
    <%
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", -1);
    %>
    
    <!DOCTYPE html>
    <html>
    <head>
    <!-- link href="<c:url value="resources/css/style.css" />" rel="stylesheet"-->
    
    <link href="<c:url value="resources/css/bootstrap.css" />"
        rel="stylesheet">
    <link href="<c:url value="resources/css/bootstrap-theme.css" />"
        rel="stylesheet">
    
    <link href="<c:url value="resources/css/login.css" />" rel="stylesheet">
    
    <title>Login Page</title>
    
    
    
    </head>
    
    <body onload='document.loginForm.username.focus();'>
    
        <!-- div id="intestazione">
            <h1 align="center">WIFI e PNSD</h1>
        </div-->
    
        <div class="container">
            <section id="sezioneBenvenuto">
                <h1 id="benvenuto" >Benvenuto</h1>
            </section>
    
            <section id="sezioneLogo" >
                <img src="resources/img/logo2.png" id="logo">
            </section>
            <section id="sezioneLogin">
                <div id="login-box">
    
                    <c:if test="${not empty error}">
                        <div class="error">${error}</div>
                    </c:if>
    
                    <form class="form-horizontal" name='loginForm' action="<c:url value='/j_spring_security_check' />" method='POST'>
                        <div class="form-group" style="margin: 0px;" >
                            <label class="sr-only" for="exampleInputEmail3">Email address</label>
                            <input type='text' name='username' class="form-control" id="exampleInputEmail3" placeholder="Nome Utente">
                            <br>
    
                        </div>
    
                        <div class="form-group" style="margin: 0px;" >
                            <label class="sr-only" for="exampleInputPassword3">Password</label>
                            <input type='password' name='password' class="form-control" id="exampleInputPassword3" placeholder="Password">
                            <br>
                        </div>
    
                        <!--  <button type="submit" class="btn btn-default">Sign in</button> -->
                        <input id="ricorda" name="submit" type="submit" class="btn btn-default" value="Accedi" style="color: #0F8BB0;" />
    
                        <br>
    
                        <div style="white-space: nowrap; padding-top: 35px;">
                            <a id="linkGestioneUtenza" class="pull-left" href="${linkGestioneUtenza}">Gestione utenza</a>
                            <div class="pull-right">
                                <input style="vertical-align: top;" type="checkbox">
                                <label style="vertical-align: top; font-weight: normal; color: #0F8BB0;">Ricordami</label>
                            </div>
                        </div>
    
                    </form>
                </div>
            </section>
        </div>
        <!--jsp:include page="footer.jsp" /-->
    
        <script type="text/javascript" src="webjars/bootstrap/3.2.0/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="webjars/jquery/2.1.1/jquery.min.js"></script>
    
    </body>
    </html>
    

    因此,正如您在前面的代码片段中看到的,有一个复选框表示 记住我 选择:

    <div class="pull-right">
        <input style="vertical-align: top;" type="checkbox">
        <label style="vertical-align: top; font-weight: normal; color: #0F8BB0;">Ricordami</label>
    </div>
    

    好的,使用上一个 登录.jsp 页面我使用我的凭据访问我的应用程序没有问题,但如果我选中“记住我”复选框,它将无法工作(实际上,当我再次访问应用程序时,我必须再次插入我的凭据)。

    因此,我阅读了官方文档,发现我必须通过向浏览器发送cookie来实现或配置此行为,并在以后的会话中检测cookie,从而实现自动登录,如下所述: http://docs.spring.io/spring-security/site/docs/4.1.x-SNAPSHOT/reference/html/remember-me.html

    根据我的理解,有两种方法可以做到:

    1. 第一种方法使用哈希来保护基于cookie的令牌的安全性 .

    2. 第二种使用数据库或其他持久存储机制 存储生成的令牌

    第一个疑问是:这些断言的确切含义是什么?这两种方法的区别是什么?

    在文档中,我还可以阅读:

    注意,这两种实现都需要 用户详细信息服务 如果 您使用的身份验证提供程序不使用 用户详细信息服务 (例如 LDAP协议 提供者),除非你也有 用户详细信息服务 豆在你的 应用程序上下文 .

    好的,在这个项目中,使用 LDAP协议 。阅读文档,我觉得 用户详细信息服务 是一个接口(所以必须由自定义的具体类实现?)其加载用户特定数据。

    所以现在我的疑问是:这到底是什么 用户详细信息服务 ? 我到哪里去申报呢 应用程序上下文 ? 进入Spring Security配置文件( 弹簧安全.xml )或在Spring配置文件中( 根文本.xml ) ?

    2 回复  |  直到 10 年前
        1
  •  2
  •   user2965598    10 年前

    UserDetailService是一个用于加载用户特定数据(例如用户名和密码等)的接口。您将实现UserDetailService,然后编写自定义用户详细信息服务以提供特定于用户的信息。 以下是如何使用基于UserDetailService的身份验证的示例:-

    Custom UserDetailsService example for spring 3 security

    为了记住我,你最好吃饼干。使用数据库作为“记住我”选项不是一个好主意。只需使用cookie。

        2
  •  1
  •   Anudeep Gade    10 年前

    这些断言到底是什么意思?

    基本上记住我的功能有两件事

    1. 成功登录后,它会创建一个“rememeber me”浏览器cookie 使用基于用户名、密码的令牌(可以计算令牌 如果需要,可以保存在数据库中,也可以是动态计算的哈希 用户、密码)。
    2. 当用户尝试在没有任何会话的情况下访问安全页面时 (会话因超时而过期),然后RememberMe服务 将尝试通过反转过程自动登录用户(获取cookie 并使用userDetails哈希进行检查,或使用数据库中的持久化令牌进行检查 )

    这两种方法的区别是什么?

    TokenBasedRememberMe服务 -

    1. 它使用用户详细信息的哈希来保护 基于cookie的令牌。
    2. 它包含密码的哈希,此解决方案可能 如果cookie被捕获,则易受攻击。

    持久的基于令牌的RememberMeServices

    1. 它使用数据库或其他持久存储机制来存储 生成的令牌。
    2. 它使用用户的唯一序列标识符。这标识了 用户的初始登录,并在每次用户登录时保持不变 在持久会话期间自动登录。它也是 包含用户每次登录时重新生成的随机令牌 通过持久化的记住我的功能。这种组合 随机生成的序列和令牌持久化 武力攻击的可能性很小。

    用例示例

    public class LdapUserDetailsService implements UserDetailsService {
        @Override
        public UserDetails loadUserByUsername(final String userName) throws UsernameNotFoundException {
    //Basically you need user details , username,password,roles you can fetch from your LdapService
    
            final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            final SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
            authorities.add(authority);
    
    return new User(userName, "password", authorities);   }
    

    SpringSecurity配置文件(springsecurity.xml)

    <!-- Remember me config -->
    <security:http 
         <security:remember-me services-ref="rememberMeServices" />
    </security:http>
    <bean id="customUserDetailsService" class="com..LdapUserDetailsService"/>
    <bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
        <constructor-arg index="0" value="myAppKey" />
        <constructor-arg index="1" ref="customUserDetailsService" />
     </bean>
     <bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
        <constructor-arg index="0" value="myAppKey" />
      </bean>
      <security:authentication-manager alias="authenticationManager">
         <security:authentication-provider ref="rememberMeAuthenticationProvider"/>
      </security:authentication-manager>
    
    推荐文章