-3

何日もの調査の後、私はあきらめました。私の唯一の希望は、ここで助けを見つけることです。

ログイン部分がSpring Security 3.2.5でSpring 4を手動で使用しているアプリケーションがあります。ログインの同時実行数を制御する必要がありますが、機能しません。

私のコード:

spring-security.xml

<http auto-config="true" use-expressions="true" disable-url-rewriting="true" create-session="always">
    <intercept-url pattern="/public/**" access="permitAll" />
    <intercept-url pattern="/protected/**" access="isAuthenticated()" />
    <!-- Necessário jogar a pasta template para fora do protected por causa do AngularJS ( $routeProvider ) -->
    <intercept-url pattern="/resources/template/**" access="isAuthenticated()" /> 

    <form-login login-page="/public/login"
                default-target-url="/protected/main"
                authentication-failure-url="/public/login?error=403"  
                always-use-default-target="true"/>

    <logout logout-success-url="/public/login"
            logout-url="/logout"
            delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"
            invalidate-session="true"/>

    <session-management invalid-session-url="/public/login" >
        <concurrency-control error-if-maximum-exceeded="false" max-sessions="1" expired-url="/logout"/>
    </session-management>

    <remember-me key="rememberkysecurity" services-ref="rememberMeServices"/>

    <headers >
        <cache-control />
        <frame-options />
        <hsts/>
    </headers>
</http>

<beans:bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <beans:property name="key" value="rememberkysecurity" />
    <beans:property name="userDetailsService" ref="userDetailsService" />
    <beans:property name="alwaysRemember" value="true" />
    <beans:property name="tokenValiditySeconds" value="10080" />
</beans:bean>

<authentication-manager alias="autenticationManagerDB" >
    <authentication-provider>
        <password-encoder hash="bcrypt" />
        <jdbc-user-service data-source-ref="dataSource" id="userDetailsService" 
                           users-by-username-query="SELECT username, password, enabled FROM user WHERE username = ?"
                           authorities-by-username-query= "SELECT usr_id, 'ROLE_ADMIN' AS role FROM user WHERE username = ?"/>
    </authentication-provider>
</authentication-manager>

web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>APP</display-name>
<welcome-file-list>
    <welcome-file>/public/login</welcome-file>
</welcome-file-list>
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/spring.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/spring.xml</param-value>
</context-param>
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<session-config>
    <session-timeout>360</session-timeout>
    <cookie-config>
        <http-only>true</http-only>
        <secure>false</secure>
    </cookie-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>   

Java ログイン

Authentication authenticatedUser = null;
    if ( keeplogged ) {
        UserDetails userDetails = userDetailsService.loadUserByUsername( user.getUsername() );
        RememberMeAuthenticationToken rememberMeAuthenticationToken = new RememberMeAuthenticationToken( "rememberkysecurity", userDetails, userDetails.getAuthorities() );

        rememberMeServices.loginSuccess(request, response, rememberMeAuthenticationToken);
        authenticatedUser = rememberMeAuthenticationToken;

    } else {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( user.getUsername(), user.getPassword() );

        authenticatedUser = this.autenticationManagerDB.authenticate( authenticationToken );

    }
    UserDetails userDetails = userDetailsService.loadUserByUsername( user.getUsername() );
    SecurityContextHolder.getContext().setAuthentication( authenticatedUser );
4

2 に答える 2

0

UsernamePasswordAuthenticationFilter を使用する

Spring Security を使用していない理由はありますUsernamePasswordAuthenticationFilterか? あなたがそうであれば、これは箱から出してあなたのために処理されます。

カスタムコントローラー

認証用に独自のコントローラーを提供する場合は、SessionAuthenticationStrategy手動で実行する必要があります。通常、これはCompositeSessionAuthenticationStrategy、次の実装が (この順序で) 取り込まれた を使用して行われます。

  • ConcurrentSessionControlAuthenticationStrategy - ユーザーが認証を許可されている (つまり、アプリケーションにまだログインしていない) ことを確認します。
  • SessionFixationProtectionStrategy - 認証時にセッション ID を変更して、セッション固定攻撃が開始されないようにします
  • RegisterSessionAuthenticationStrategy - 新しいユーザーを現在認証済みとして登録します

したがって、問題を解決するには、次のことができる必要があります。

@Autowired
CompositeSessionAuthenticationStrategy strategy;


public void doLogin() {

    Authentication authenticatedUser = null;
    if ( keeplogged ) {
        UserDetails userDetails = userDetailsService.loadUserByUsername( user.getUsername() );
        RememberMeAuthenticationToken rememberMeAuthenticationToken = new RememberMeAuthenticationToken( "rememberkysecurity", userDetails, userDetails.getAuthorities() );

        rememberMeServices.loginSuccess(request, response, rememberMeAuthenticationToken);
        authenticatedUser = rememberMeAuthenticationToken;

    } else {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( user.getUsername(), user.getPassword() );

        authenticatedUser = this.autenticationManagerDB.authenticate( authenticationToken );

    }
    UserDetails userDetails = userDetailsService.loadUserByUsername( user.getUsername() );

    sessionStrategy.onAuthentication(authenticatedUser, request, response);

    SecurityContextHolder.getContext().setAuthentication( authenticatedUser );
}
于 2015-08-12T13:15:02.853 に答える